--- /dev/null
+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
--- /dev/null
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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.
+\f
+ 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
+\f
+ How to Apply These Terms to Your New Libraries
+
+ If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change. You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+ To apply these terms, attach the following notices to the library. It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the library's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the
+ library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+ <signature of Ty Coon>, 1 April 1990
+ Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = debian.upstream gst-libs gst pkgconfig tests docs
+
+# 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
+
+DEB_BUILDDIR = debian.build
+
+deb:
+ dpkg-buildpackage -rfakeroot -uc -us
+
+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 && \
+ $(MAKE) deb -f Makefile.am
--- /dev/null
+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.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
+* 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
--- /dev/null
+
+ gstreamer-vaapi
+ VA-API support to GStreamer
+
+ Copyright (C) 2010-2011 Splitted-Desktop Systems
+ Copyright (C) 2011-2012 Intel Corporation
+ Copyright (C) 2011 Collabora Ltd.
+
+
+License
+-------
+
+gstreamer-vaapi helper libraries and plugin elements are available
+under the terms of the GNU Lesser General Public License v2.1+
+
+Overview
+--------
+
+gstreamer-vaapi consists in a collection of VA-API based plugins for
+GStreamer and helper libraries.
+
+ * `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.
+
+ * `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.
+
+ * `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.
+
+
+Features
+--------
+
+ * 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)
+
+
+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
+
+ If codecparsers-based decoders are not used:
+
+ * libavcodec-dev >= 0.6
+ or with <libavcodec/vaapi.h>
+
+Hardware requirements
+
+ * AMD platforms with UVD2 (XvBA supported)
+ * Intel Eaglelake (G45)
+ * Intel Ironlake, Sandy Bridge and Ivy Bridge (HD Graphics)
+ * Intel Poulsbo (US15W)
+ * Intel Medfield or Cedar Trail
+ * NVIDIA platforms with PureVideo (VDPAU supported)
+
+
+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
--- /dev/null
+#!/bin/sh
+
+PROJECT="gstreamer-vaapi"
+
+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`"
+cd "$srcdir"
+
+mkdir -p m4
+
+GTKDOCIZE=`which gtkdocize`
+if test -z $GTKDOCIZE; then
+ echo "*** No gtk-doc support ***"
+ echo "EXTRA_DIST =" > gtk-doc.make
+else
+ gtkdocize || exit $?
+fi
+
+AUTORECONF=`which autoreconf`
+if test -z $AUTORECONF; then
+ echo "*** No autoreconf found ***"
+ exit 1
+else
+ autoreconf -v --install || exit $?
+fi
+
+cd "$olddir"
+
+if test -z "$NO_CONFIGURE"; then
+ $srcdir/configure "$@" && echo "Now type 'make' to compile $PROJECT."
+fi
--- /dev/null
+# gstreamer-vaapi package version number
+m4_define([gst_vaapi_major_version], [0])
+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])
+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], [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])
+
+# gst version number
+m4_define([gst_major_version], [0])
+m4_define([gst_minor_version], [10])
+m4_define([gst_micro_version], [14])
+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])
+
+# 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])
+
+# 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])
+
+AC_PREREQ([2.58])
+AC_INIT([gst_vaapi], [gst_vaapi_version],
+ [gwenole.beauchesne@intel.com],
+ [gstreamer-vaapi])
+
+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)
+
+GST_VAAPI_MAJOR_VERSION=gst_vaapi_major_version
+AC_SUBST(GST_VAAPI_MAJOR_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
+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)
+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
+ AC_SUBST(AM_DEFAULT_VERBOSITY)
+])
+
+dnl Check for tools
+AC_PROG_CC
+AM_PROG_CC_C_O
+
+dnl Initialize libtool
+LT_PREREQ([2.2])
+LT_INIT
+
+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(encoders,
+ AC_HELP_STRING([--enable-encoders],
+ [enable encoders @<:@default=no@:>@]),
+ [], [enable_encoders="no"])
+
+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])], [
+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 ---------------------------------------------------------------------------
+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_BASE_CFLAGS"
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $GST_BASE_LIBS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <gst/base/gstbasesink.h>]],
+ [[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 GStreamer -base plugins
+PKG_CHECK_MODULES([GST_PLUGINS_BASE],
+ [gstreamer-plugins-base-$GST_MAJORMINOR >= gst_plugins_base_version])
+PKG_CHECK_MODULES([GST_INTERFACES],
+ [gstreamer-interfaces-$GST_MAJORMINOR >= gst_plugins_base_version])
+
+dnl ... GstVideoOverlayComposition (gstreamer-video)
+PKG_CHECK_MODULES([GST_VIDEO],
+ [gstreamer-video-$GST_MAJORMINOR >= gst_plugins_base_version])
+
+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_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <gst/video/video-overlay-composition.h>]],
+ [[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 GStreamer -bad plugins
+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])
+
+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"
+ saved_LIBS="$LIBS"
+ LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <gst/codecparsers/gsth264parser.h>]],
+ [[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"
+])
+
+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 ... 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_LIBS="$LIBS"
+ LIBS="$LIBS $GST_LIBS $GST_CODEC_PARSERS_LIBS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <gst/codecparsers/gstjpegparser.h>]],
+ [[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"
+])
+
+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 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`
+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 ---------------------------------------------------------------------------
+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
+ 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
+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
+ enable_opengl="yes"
+fi
+
+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 <GL/gl.h>
+#endif
+ ])
+ CPPFLAGS="$saved_CPPFLAGS"
+fi
+
+dnl Check for encoders
+USE_ENCODERS=0
+if test "$enable_encoders" = "yes"; then
+ USE_ENCODERS=1
+fi
+
+AC_DEFINE_UNQUOTED(USE_ENCODERS, $USE_ENCODERS,
+ [Defined to 1 if GStreamer Vaapi Encoder are used])
+AM_CONDITIONAL(USE_ENCODERS, test $USE_ENCODERS -eq 1)
+
+dnl ... GLX
+USE_GLX=0
+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"
+ CPPFLAGS="$CPPFLAGS $GL_CFLAGS"
+ LIBS="$LIBS $GL_LIBS"
+ AC_CHECK_HEADERS([GL/glx.h], [:], [USE_GLX=0], [
+#ifdef HAVE_GL_GL_H
+# include <GL/gl.h>
+#endif
+ ])
+ AC_CHECK_LIB([GL], [glXCreateContext], [:], [USE_GLX=0])
+ CPPFLAGS="$saved_CPPFLAGS"
+ 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 ---------------------------------------------------------------------------
+
+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"
+
+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"
+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
+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_CPPFLAGS"
+ AC_CHECK_HEADERS([va/va_glx.h], [:], [HAVE_VA_GLX=0])
+ CPPFLAGS="$saved_CPPFLAGS"
+ fi
+fi
+AC_SUBST(LIBVA_GLX_PKGNAME)
+
+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_LIBS="$LIBS"
+ LIBS="$CFLAGS $LIBVA_LIBS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <va/va.h>]],
+ [[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"]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LIBS="$saved_LIBS"
+])
+
+dnl Check libva old H.264 encoder API
+HAVE_OLD_H264_ENCODER=0
+AC_CACHE_CHECK([for H264 encoder old structures],
+ ac_cv_have_old_h264_encoder, [
+ saved_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS $LIBVA_CFLAGS"
+ saved_LIBS="$LIBS"
+ LIBS="$CFLAGS $LIBVA_LIBS"
+ AC_COMPILE_IFELSE(
+ [AC_LANG_PROGRAM(
+ [[#include <va/va_enc_h264.h>]],
+ [[VAEncSequenceParameterBufferH264 seq;
+ seq.seq_fields.value = 0;
+ seq.vui_fields.value = 0;]])],
+ [ac_cv_have_old_h264_encoder="no" HAVE_OLD_H264_ENCODER=0],
+ [ac_cv_have_old_h264_encoder="yes" HAVE_OLD_H264_ENCODER=1]
+ )
+ CFLAGS="$saved_CFLAGS"
+ LIBS="$saved_LIBS"
+])
+
+AC_DEFINE_UNQUOTED(HAVE_OLD_H264_ENCODER, $HAVE_OLD_H264_ENCODER,
+ [Defined to 1 if old h264 encoder API exists.])
+
+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:$USE_WAYLAND:$USE_DRM:" 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_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_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
+ debian.upstream/Makefile
+ debian.upstream/changelog
+ debian.upstream/control
+ 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-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
+ 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/codecparsers/Makefile
+ gst-libs/gst/vaapi/Makefile
+ gst/Makefile
+ gst/vaapi/Makefile
+ 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:\
+pkgconfig/gstreamer-vaapi-wayland.pc.in
+ pkgconfig/gstreamer-vaapi-x11-$GST_MAJORMINOR.pc:\
+pkgconfig/gstreamer-vaapi-x11.pc.in
+ tests/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_WAYLAND -eq 1], [VIDEO_OUTPUTS="$VIDEO_OUTPUTS wayland"])
+
+echo
+echo $PACKAGE configuration summary:
+echo
+echo VA-API version ................... : $VA_VERSION_STR
+echo Video outputs .................... : $VIDEO_OUTPUTS
+echo VaapiEncoder support....... ...... : $(yesno $USE_ENCODERS)
+echo
--- /dev/null
+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 \
+ 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 \
+ rules \
+ $(NULL)
+
+DEBIANGENFILES = \
+ control \
+ changelog \
+ gstreamer$(GST_MAJORMINOR)-vaapi.install \
+ 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 \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(DEBIANFILES)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in $(DEBIANGENFILES)
--- /dev/null
+gstreamer@GST_MAJORMINOR@-vaapi (@PACKAGE_VERSION@-1) unstable; urgency=low
+
+ * Autogenerated package, see NEWS file for ChangeLog.
+
+ -- Gwenole Beauchesne <gwenole.beauchesne@intel.com> @TODAY@
--- /dev/null
+Source: gstreamer@GST_MAJORMINOR@-vaapi
+Section: libs
+Priority: optional
+Maintainer: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
+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@),
+ libva-dev (>= @LIBVA_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:
+ - `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
+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
+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-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
+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-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-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
+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.
+ .
+ This package contains development files for GStreamer libraries for
+ the "vaapi" set.
--- /dev/null
+This package is maintained by:
+Gwenole Beauchesne <gwenole.beauchesne@intel.com>
+
+Copyright:
+
+ gstreamer-vaapi helper libraries
+ and plugins elements: LGPL (v2.1 or later)
+
+License:
+
+ Copyright (C) 2010-2011, Splitted-Desktop Systems.
+ Copyright (C) 2011-2012, 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'.
+
--- /dev/null
+debian/tmp/usr/share/doc/gstreamer@GST_MAJORMINOR@-vaapi
--- /dev/null
+debian/tmp/usr/lib/gstreamer-@GST_MAJORMINOR@/libgstvaapi*.so
--- /dev/null
+debian/tmp/usr/lib/libgstvaapi*.so
+debian/tmp/usr/lib/pkgconfig/gstreamer-vaapi*.pc
+debian/tmp/usr/include/gstreamer-@GST_MAJORMINOR@/gst/vaapi/*.h
--- /dev/null
+debian/tmp/usr/lib/libgstvaapi-drm-@GST_MAJORMINOR@.so.*
--- /dev/null
+debian/tmp/usr/lib/libgstvaapi-glx-@GST_MAJORMINOR@.so.*
--- /dev/null
+debian/tmp/usr/lib/libgstvaapi-wayland-@GST_MAJORMINOR@.so.*
--- /dev/null
+debian/tmp/usr/lib/libgstvaapi-x11-@GST_MAJORMINOR@.so.*
--- /dev/null
+debian/tmp/usr/lib/libgstvaapi-@GST_MAJORMINOR@.so.*
--- /dev/null
+#!/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
+
+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)
+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/$(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)
--- /dev/null
+SUBDIRS =
+
+if ENABLE_GTK_DOC
+SUBDIRS += reference
+endif
+
+DIST_SUBDIRS = reference
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+SUBDIRS = libs plugins
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+## 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 = $(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"
+
+# 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 $(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 \
+ 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-$(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
+
+# Other files to distribute
+# 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
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+<book id="index" xmlns:xi="http://www.w3.org/2003/XInclude">
+ <bookinfo>
+ <title>GStreamer VA-API Plugins @GST_MAJORMINOR@ Library Reference Manual</title>
+ </bookinfo>
+
+ <chapter>
+ <title>gst-plugins-vaapi Library</title>
+ <xi:include href="xml/gstvaapitypes.xml"/>
+ <xi:include href="xml/gstvaapivalue.xml"/>
+ <xi:include href="xml/gstvaapiparamspecs.xml"/>
+ <xi:include href="xml/gstvaapidisplay.xml"/>
+ <xi:include href="xml/gstvaapidisplay_x11.xml"/>
+ <xi:include href="xml/gstvaapidisplay_glx.xml"/>
+ <xi:include href="xml/gstvaapiwindow.xml"/>
+ <xi:include href="xml/gstvaapiwindow_x11.xml"/>
+ <xi:include href="xml/gstvaapiwindow_glx.xml"/>
+ <xi:include href="xml/gstvaapiobject.xml"/>
+ <xi:include href="xml/gstvaapisurface.xml"/>
+ <xi:include href="xml/gstvaapiimage.xml"/>
+ <xi:include href="xml/gstvaapiimageformat.xml"/>
+ <xi:include href="xml/gstvaapisubpicture.xml"/>
+ <xi:include href="xml/gstvaapitexture.xml"/>
+ <xi:include href="xml/gstvaapiprofile.xml"/>
+ <xi:include href="xml/gstvaapivideopool.xml"/>
+ <xi:include href="xml/gstvaapisurfacepool.xml"/>
+ <xi:include href="xml/gstvaapiimagepool.xml"/>
+ <xi:include href="xml/gstvaapivideobuffer.xml"/>
+ <xi:include href="xml/gstvaapicontext.xml"/>
+ <xi:include href="xml/gstvaapidecoder.xml"/>
+ <xi:include href="xml/gstvaapidecoder_mpeg2.xml"/>
+ <xi:include href="xml/gstvaapidecoder_mpeg4.xml"/>
+ <xi:include href="xml/gstvaapidecoder_h264.xml"/>
+ <xi:include href="xml/gstvaapidecoder_vc1.xml"/>
+ <xi:include href="xml/gstvaapidecoder_ffmpeg.xml"/>
+ <xi:include href="xml/gstvaapisurfaceproxy.xml"/>
+ </chapter>
+
+ <chapter id="object-tree">
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+
+ <index id="api-index-full">
+ <title>API Index</title>
+ <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</book>
--- /dev/null
+<SECTION>
+<FILE>gstvaapisurfacepool</FILE>
+<TITLE>GstVaapiSurfacePool</TITLE>
+GstVaapiSurfacePool
+GstVaapiSurfacePoolClass
+gst_vaapi_surface_pool_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapivideopool</FILE>
+<TITLE>GstVaapiVideoPool</TITLE>
+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
+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
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidisplay_x11</FILE>
+<TITLE>GstVaapiDisplayX11</TITLE>
+GstVaapiDisplayX11
+GstVaapiDisplayX11Class
+gst_vaapi_display_x11_new
+gst_vaapi_display_x11_new_with_display
+gst_vaapi_display_x11_get_display
+gst_vaapi_display_x11_get_screen
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiwindow_x11</FILE>
+<TITLE>GstVaapiWindowX11</TITLE>
+GstVaapiWindowX11
+GstVaapiWindowX11Class
+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
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidisplay_glx</FILE>
+<TITLE>GstVaapiDisplayGLX</TITLE>
+GstVaapiDisplayGLX
+GstVaapiDisplayGLXClass
+gst_vaapi_display_glx_new
+gst_vaapi_display_glx_new_with_display
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiwindow_glx</FILE>
+<TITLE>GstVaapiWindowGLX</TITLE>
+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_make_current
+gst_vaapi_window_glx_swap_buffers
+gst_vaapi_window_glx_put_texture
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidisplay</FILE>
+<TITLE>GstVaapiDisplay</TITLE>
+GstVaapiDisplay
+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
+gst_vaapi_display_get_size
+gst_vaapi_display_get_pixel_aspect_ratio
+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
+gst_vaapi_display_has_subpicture_format
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiimagepool</FILE>
+<TITLE>GstVaapiImagePool</TITLE>
+GstVaapiImagePool
+GstVaapiImagePoolClass
+gst_vaapi_image_pool_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapivideobuffer</FILE>
+<TITLE>GstVaapiVideoBuffer</TITLE>
+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
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapitypes</FILE>
+<TITLE>Basic data structures</TITLE>
+GstVaapiID
+GST_VAAPI_ID_FORMAT
+GST_VAAPI_ID_ARGS
+GST_VAAPI_ID
+GST_VAAPI_ID_NONE
+GstVaapiPoint
+GstVaapiRectangle
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapivalue</FILE>
+<TITLE></TITLE>
+GST_VAAPI_TYPE_ID
+gst_vaapi_value_get_id
+gst_vaapi_value_set_id
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiparamspecs</FILE>
+<TITLE></TITLE>
+GstVaapiParamSpecID
+gst_vaapi_param_spec_id
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiwindow</FILE>
+<TITLE>GstVaapiWindow</TITLE>
+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
+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
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiobject</FILE>
+<TITLE>GstVaapiObject</TITLE>
+GstVaapiObject
+GstVaapiObjectClass
+gst_vaapi_object_get_display
+gst_vaapi_object_lock_display
+gst_vaapi_object_unlock_display
+gst_vaapi_object_get_id
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiimage</FILE>
+GST_VAAPI_IMAGE_FORMAT
+GST_VAAPI_IMAGE_WIDTH
+GST_VAAPI_IMAGE_HEIGHT
+<TITLE>GstVaapiImage</TITLE>
+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
+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_get_raw
+gst_vaapi_image_update_from_buffer
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapisurface</FILE>
+GstVaapiChromaType
+GstVaapiSurfaceStatus
+GstVaapiSurfaceRenderFlags
+<TITLE>GstVaapiSurface</TITLE>
+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
+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
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapisubpicture</FILE>
+<TITLE>GstVaapiSubpicture</TITLE>
+GstVaapiSubpicture
+GstVaapiSubpictureClass
+gst_vaapi_subpicture_new
+gst_vaapi_subpicture_get_id
+gst_vaapi_subpicture_get_image
+gst_vaapi_subpicture_set_image
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiimageformat</FILE>
+<TITLE>GstVaapiImageFormat</TITLE>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiprofile</FILE>
+<TITLE>GstVaapiProfile</TITLE>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapitexture</FILE>
+<TITLE>GstVaapiTexture</TITLE>
+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
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapicontext</FILE>
+<TITLE>GstVaapiContext</TITLE>
+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_get_surface_count
+gst_vaapi_context_put_surface
+gst_vaapi_context_find_surface_by_id
+gst_vaapi_context_apply_composition
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecoder</FILE>
+GstVaapiDecoderStatus
+<TITLE>GstVaapiDecoder</TITLE>
+GstVaapiDecoder
+GstVaapiDecoderClass
+gst_vaapi_decoder_get_caps
+gst_vaapi_decoder_put_buffer
+gst_vaapi_decoder_get_surface
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecoder_jpeg</FILE>
+<TITLE>GstVaapiDecoderJpeg</TITLE>
+GstVaapiDecoderJpeg
+GstVaapiDecoderJpegClass
+gst_vaapi_decoder_jpeg_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecoder_mpeg2</FILE>
+<TITLE>GstVaapiDecoderMpeg2</TITLE>
+GstVaapiDecoderMpeg2
+GstVaapiDecoderMpeg2Class
+gst_vaapi_decoder_mpeg2_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecoder_mpeg4</FILE>
+<TITLE>GstVaapiDecoderMpeg4</TITLE>
+GstVaapiDecoderMpeg4
+GstVaapiDecoderMpeg4Class
+gst_vaapi_decoder_mpeg4_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecoder_h264</FILE>
+<TITLE>GstVaapiDecoderH264</TITLE>
+GstVaapiDecoderH264
+GstVaapiDecoderH264Class
+gst_vaapi_decoder_h264_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecoder_vc1</FILE>
+<TITLE>GstVaapiDecoderVC1</TITLE>
+GstVaapiDecoderVC1
+GstVaapiDecoderVC1Class
+gst_vaapi_decoder_vc1_new
+<SUBSECTION Standard>
+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
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapisurfaceproxy</FILE>
+<TITLE>GstVaapiSurfaceProxy</TITLE>
+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_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
+<SUBSECTION Standard>
+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
+</SECTION>
--- /dev/null
+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_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
--- /dev/null
+gst_vaapi_display_glx_get_type
+gst_vaapi_texture_get_type
+gst_vaapi_window_glx_get_type
--- /dev/null
+gst_vaapi_display_x11_get_type
+gst_vaapi_window_x11_get_type
--- /dev/null
+## 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_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/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)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in $(DOC_MODULE)-docs.xml
--- /dev/null
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
+[
+ <!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
+]>
+<book id="index">
+ <bookinfo>
+ <title>GStreamer VA-API Plugins @GST_MAJORMINOR@ Plugins Reference Manual</title>
+ </bookinfo>
+
+ <chapter>
+ <title>gst-plugins-vaapi Plugins</title>
+ <xi:include href="xml/gstvaapidecode.xml"/>
+ <xi:include href="xml/gstvaapipostproc.xml"/>
+ <xi:include href="xml/gstvaapidownload.xml"/>
+ <xi:include href="xml/gstvaapiupload.xml"/>
+ <xi:include href="xml/gstvaapisink.xml"/>
+ </chapter>
+
+ <chapter id="object-tree">
+ <title>Object Hierarchy</title>
+ <xi:include href="xml/tree_index.sgml"/>
+ </chapter>
+
+ <index id="api-index-full">
+ <title>API Index</title>
+ <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
+ </index>
+
+ <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+</book>
--- /dev/null
+<SECTION>
+<FILE>gstvaapisink</FILE>
+<TITLE>GstVaapiSink</TITLE>
+GstVaapiSink
+<SUBSECTION Standard>
+GST_VAAPISINK
+GST_IS_VAAPISINK
+GST_TYPE_VAAPISINK
+gst_vaapisink_get_type
+GST_VAAPISINK_CLASS
+GST_IS_VAAPISINK_CLASS
+GST_VAAPISINK_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidecode</FILE>
+<TITLE>GstVaapiDecode</TITLE>
+GstVaapiDecode
+<SUBSECTION Standard>
+GST_VAAPIDECODE
+GST_IS_VAAPIDECODE
+GST_TYPE_VAAPIDECODE
+gst_vaapidecode_get_type
+GST_VAAPIDECODE_CLASS
+GST_IS_VAAPIDECODE_CLASS
+GST_VAAPIDECODE_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapipostproc</FILE>
+<TITLE>GstVaapiPostproc</TITLE>
+GstVaapiPostproc
+<SUBSECTION Standard>
+GST_VAAPIPOSTPROC
+GST_IS_VAAPIPOSTPROC
+GST_TYPE_VAAPIPOSTPROC
+gst_vaapipostproc_get_type
+GST_VAAPIPOSTPROC_CLASS
+GST_IS_VAAPIPOSTPROC_CLASS
+GST_VAAPIPOSTPROC_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapiupload</FILE>
+<TITLE>GstVaapiUpload</TITLE>
+GstVaapiUpload
+<SUBSECTION Standard>
+GST_VAAPIUPLOAD
+GST_IS_VAAPIUPLOAD
+GST_TYPE_VAAPIUPLOAD
+gst_vaapiupload_get_type
+GST_VAAPIUPLOAD_CLASS
+GST_IS_VAAPIUPLOAD_CLASS
+GST_VAAPIUPLOAD_GET_CLASS
+</SECTION>
+
+<SECTION>
+<FILE>gstvaapidownload</FILE>
+<TITLE>GstVaapiDownload</TITLE>
+GstVaapiDownload
+<SUBSECTION Standard>
+GST_VAAPIDOWNLOAD
+GST_IS_VAAPIDOWNLOAD
+GST_TYPE_VAAPIDOWNLOAD
+gst_vaapidownload_get_type
+GST_VAAPIDOWNLOAD_CLASS
+GST_IS_VAAPIDOWNLOAD_CLASS
+GST_VAAPIDOWNLOAD_GET_CLASS
+</SECTION>
--- /dev/null
+gst_vaapidecode_get_type
+gst_vaapidownload_get_type
+gst_vaapipostproc_get_type
+gst_vaapisink_get_type
+gst_vaapiupload_get_type
--- /dev/null
+SUBDIRS = gst
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+SUBDIRS = codecparsers vaapi
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in $(gen_headers)
--- /dev/null
+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_la_SOURCES = \
+ $(libgstvaapi_codecparsers_source_c) \
+ $(libgstvaapi_codecparsers_source_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
--- /dev/null
+/*
+ * 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 <string.h>
+#include <gst/base/gstbytereader.h>
+#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;
+}
--- /dev/null
+/*
+ * 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 <gst/gst.h>
+
+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 */
--- /dev/null
+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
+
+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
+
+libgstvaapi_cflags = \
+ -DGST_USE_UNSTABLE_API \
+ -I$(top_srcdir)/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 = \
+ 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 \
+ gstvaapiimageformat.c \
+ gstvaapiimagepool.c \
+ gstvaapiobject.c \
+ gstvaapiparamspecs.c \
+ gstvaapiprofile.c \
+ gstvaapisubpicture.c \
+ gstvaapisurface.c \
+ gstvaapisurfacepool.c \
+ gstvaapisurfaceproxy.c \
+ gstvaapiutils.c \
+ gstvaapivalue.c \
+ gstvaapivideobuffer.c \
+ gstvaapivideopool.c \
+ gstvaapiwindow.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 \
+ gstvaapiimage.h \
+ gstvaapiimageformat.h \
+ gstvaapiimagepool.h \
+ gstvaapiobject.h \
+ gstvaapiparamspecs.h \
+ gstvaapiprofile.h \
+ gstvaapisubpicture.h \
+ gstvaapisurface.h \
+ gstvaapisurfacepool.h \
+ gstvaapisurfaceproxy.h \
+ gstvaapitypes.h \
+ gstvaapivalue.h \
+ gstvaapivideobuffer.h \
+ gstvaapivideopool.h \
+ gstvaapiwindow.h \
+ $(NULL)
+
+if USE_ENCODERS
+libgstvaapi_source_c += \
+ gstvaapiencoder.c \
+ gstvaapibaseencoder.c \
+ gstvaapiencoder_h264.c \
+ gstvaapiencoder_h263.c \
+ gstvaapiencoder_mpeg4.c \
+ $(NULL)
+
+libgstvaapi_source_h += \
+ gstvaapiencoder.h \
+ gstvaapibaseencoder.h \
+ gstvaapiencoder_h264.h \
+ gstvaapiencoder_h263.h \
+ gstvaapiencoder_mpeg4.h \
+ $(NULL)
+
+endif
+
+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 \
+ gstvaapisurface_priv.h \
+ gstvaapiutils.h \
+ gstvaapivideobuffer_priv.h \
+ gstvaapiworkarounds.h \
+ sysdeps.h \
+ $(NULL)
+
+if USE_JPEG_DECODER
+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 \
+ gstvaapiutils_x11.c \
+ gstvaapiwindow_x11.c \
+ $(NULL)
+
+libgstvaapi_x11_source_h = \
+ gstvaapidisplay_x11.h \
+ gstvaapiwindow_x11.h \
+ $(NULL)
+
+libgstvaapi_x11_source_priv_h = \
+ gstvaapicompat.h \
+ gstvaapidisplay_x11_priv.h \
+ gstvaapiutils.h \
+ gstvaapiutils_x11.h \
+ $(NULL)
+
+libgstvaapi_glx_source_c = \
+ gstvaapidisplay_glx.c \
+ gstvaapitexture.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)
+
+libgstvaapi_glx_source_priv_h = \
+ gstvaapicompat.h \
+ gstvaapidisplay_glx_priv.h \
+ gstvaapiutils.h \
+ gstvaapiutils_glx.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)
+
+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) \
+ $(NULL)
+
+libgstvaapi_@GST_MAJORMINOR@include_HEADERS = \
+ $(libgstvaapi_source_h) \
+ $(NULL)
+
+libgstvaapi_@GST_MAJORMINOR@includedir = \
+ $(libgstvaapi_includedir)
+
+libgstvaapi_@GST_MAJORMINOR@_la_CFLAGS = \
+ $(libgstvaapi_cflags) \
+ $(NULL)
+
+libgstvaapi_@GST_MAJORMINOR@_la_LIBADD = \
+ $(libgstvaapi_libs) \
+ $(NULL)
+
+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) \
+ $(NULL)
+
+libgstvaapi_x11_@GST_MAJORMINOR@include_HEADERS = \
+ $(libgstvaapi_x11_source_h) \
+ $(NULL)
+
+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) \
+ $(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)
+
+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) \
+ $(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 = \
+ -DGST_USE_UNSTABLE_API \
+ -I$(top_srcdir)/gst-libs \
+ $(GLIB_CFLAGS) \
+ $(GST_BASE_CFLAGS) \
+ $(GL_CFLAGS) \
+ $(LIBVA_GLX_CFLAGS) \
+ $(NULL)
+
+libgstvaapi_glx_@GST_MAJORMINOR@_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(GL_LIBS) \
+ $(LIBVA_GLX_LIBS) \
+ libgstvaapi-x11-@GST_MAJORMINOR@.la \
+ $(NULL)
+
+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
--- /dev/null
+/*
+ * 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 <glib.h>
+#include <glib-object.h>
+
+#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)
+#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 */
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapiobject_priv.h>
+#include <gst/vaapi/gstvaapidisplay_priv.h>
+
+#endif /* GST_VAAPI_PRIV_H */
--- /dev/null
+/*
+ * gstvaapibaseencoder.c - VA-API base encoder
+ *
+ * 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 "gstvaapibaseencoder.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <X11/Xlib.h>
+
+#include <va/va.h>
+#include "va/va_x11.h"
+
+#include "gst/gstclock.h"
+#include "gst/gstvalue.h"
+
+#include "gstvaapiobject.h"
+#include "gstvaapiobject_priv.h"
+#include "gstvaapicontext.h"
+#include "gstvaapisurface.h"
+#include "gstvaapisurfacepool.h"
+#include "gstvaapivideobuffer.h"
+#include "gstvaapidisplay_priv.h"
+#include "gstvaapidebug.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_base_encoder_debug);
+#define GST_CAT_DEFAULT gst_vaapi_base_encoder_debug
+
+#define VA_INVALID_PROFILE 0xffffffff
+#define DEFAULT_VA_CODEDBUF_NUM 4
+#define GST_VAAPI_ENCODER_SURFACE_COUNT 3
+
+struct _GstVaapiBaseEncoderPrivate {
+ guint32 format; /*NV12, I420,*/
+ VAProfile profile;
+ /*total encoded frames*/
+ guint32 frame_count;
+ VABufferID *coded_bufs;
+ guint32 coded_buf_num;
+ GMutex *code_buffer_lock;
+ GCond *code_buffer_cond;
+ GQueue *available_code_buffers;
+
+ GstVaapiSurfacePool *surfaces_pool;
+
+ guint frame_notify_flag : 1;
+ guint need_flush : 1;
+};
+
+G_DEFINE_TYPE(GstVaapiBaseEncoder, gst_vaapi_base_encoder, GST_TYPE_VAAPI_ENCODER)
+
+static VABufferID *
+pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv);
+
+static gboolean
+push_available_coded_buffer(
+ GstVaapiBaseEncoderPrivate *priv,
+ VABufferID *buf
+);
+
+void
+gst_vaapi_base_encoder_set_frame_notify(
+ GstVaapiBaseEncoder *encoder,
+ gboolean flag
+)
+{
+ GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+ priv->frame_notify_flag = flag;
+}
+
+gboolean
+gst_vaapi_base_encoder_set_va_profile(
+ GstVaapiBaseEncoder *encoder,
+ guint profile
+)
+{
+ GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+ priv->profile = profile;
+ return TRUE;
+}
+
+void
+gst_vaapi_base_encoder_set_input_format(
+ GstVaapiBaseEncoder* encoder,
+ guint32 format
+)
+{
+ GstVaapiBaseEncoderPrivate *priv = encoder->priv;
+ priv->format = format;
+}
+
+static gboolean
+default_validate_encoder_parameters(
+ GstVaapiBaseEncoder *encoder
+)
+{
+ if (!ENCODER_WIDTH(encoder) ||
+ !ENCODER_HEIGHT(encoder) ||
+ !ENCODER_FPS(encoder)) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+base_encoder_alloc_coded_buffers(
+ GstVaapiBaseEncoder *base_encoder,
+ GstVaapiContext *context
+)
+{
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+ VADisplay va_dpy;
+ VAContextID context_id;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ gboolean is_locked = FALSE;
+ guint i = 0;
+ gboolean ret = TRUE;
+ guint32 buffer_size =
+ (ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder) * 400) /
+ (16*16);
+
+ ENCODER_ASSERT(display && context);
+ ENCODER_ASSERT(priv->available_code_buffers);
+ ENCODER_ASSERT(!priv->coded_bufs);
+
+ va_dpy = ENCODER_VA_DISPLAY(base_encoder);
+ context_id = gst_vaapi_context_get_id(context);
+
+ priv->coded_bufs = (VABufferID*)
+ g_malloc0(priv->coded_buf_num * sizeof(priv->coded_bufs[0]));
+
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ for (i = 0; i < priv->coded_buf_num; i++) {
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncCodedBufferType,
+ buffer_size, 1,
+ NULL,
+ &priv->coded_bufs[i]);
+ if (VA_STATUS_SUCCESS != va_status)
+ break;
+ }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "create coded buffer failed.");
+
+ /* init queue available_code_buffers */
+ g_mutex_lock(priv->code_buffer_lock);
+ for (i = 0; i < priv->coded_buf_num; i++) {
+ g_queue_push_head(priv->available_code_buffers, &priv->coded_bufs[i]);
+ }
+ g_cond_signal(priv->code_buffer_cond);
+ g_mutex_unlock(priv->code_buffer_lock);
+
+end:
+ return ret;
+
+}
+
+static EncoderStatus
+release_coded_buffers(GstVaapiBaseEncoder *base_encoder)
+{
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+ guint32 available_buf_count = priv->coded_buf_num;
+ guint32 i;
+ gboolean is_locked = FALSE;
+
+ ENCODER_ASSERT(display);
+ VAAPI_UNUSED_ARG(va_status);
+ VADisplay va_dpy = gst_vaapi_display_get_display(display);
+
+ /* wait clear all available coded buffers*/
+ g_mutex_lock(priv->code_buffer_lock);
+ while (available_buf_count) {
+ if (g_queue_is_empty(priv->available_code_buffers)) {
+ g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
+ } else {
+ g_queue_pop_head(priv->available_code_buffers);
+ available_buf_count--;
+ }
+ }
+ g_mutex_unlock(priv->code_buffer_lock);
+
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ for (i = 0; i < priv->coded_buf_num; i++) {
+ va_status = vaDestroyBuffer(va_dpy, priv->coded_bufs[i]);
+ }
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+
+ return ENCODER_NO_ERROR;
+}
+
+static EncoderStatus
+gst_vaapi_base_encoder_close_default(GstVaapiEncoder* encoder)
+{
+ GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
+ GstVaapiBaseEncoderClass *base_class =
+ GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ EncoderStatus ret = ENCODER_NO_ERROR;
+
+ /* release buffers first */
+ priv->need_flush = FALSE;
+
+ if (base_class->release_resource) {
+ base_class->release_resource(base_encoder);
+ }
+ release_coded_buffers(base_encoder);
+ priv->frame_count = 0;
+
+ return ret;
+}
+
+static EncoderStatus
+gst_vaapi_base_encoder_open_default(
+ GstVaapiEncoder* encoder,
+ GstVaapiContext **context
+)
+{
+ GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
+ GstVaapiBaseEncoderClass *base_class =
+ GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+
+ GstVaapiContext *out_context = NULL;
+
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ gboolean check_attri_ret = TRUE;
+ /*check and set default values*/
+ if (base_class->validate_attributes) {
+ check_attri_ret = base_class->validate_attributes(base_encoder);
+ } else {
+ check_attri_ret = default_validate_encoder_parameters(base_encoder);
+ }
+ ENCODER_CHECK_STATUS(check_attri_ret,
+ ENCODER_PARAMETER_ERR,
+ "vaapi encoder paramerter error.");
+ ENCODER_CHECK_STATUS(VA_INVALID_PROFILE != priv->profile,
+ ENCODER_PROFILE_ERR,
+ "vaapi encoder profile not set.");
+
+ ENCODER_ASSERT(ENCODER_DISPLAY(encoder));
+
+ out_context = gst_vaapi_context_new(display,
+ gst_vaapi_profile(priv->profile),
+ gst_vaapi_entrypoint(VAEntrypointEncSlice),
+ ENCODER_WIDTH(encoder),
+ ENCODER_HEIGHT(encoder),
+ GST_VAAPI_ENCODER_SURFACE_COUNT);
+ ENCODER_CHECK_STATUS(out_context,
+ ENCODER_CONTEXT_ERR,
+ "gst_vaapi_context_new failed.");
+ ENCODER_CHECK_STATUS(VA_INVALID_ID != GST_VAAPI_OBJECT_ID(out_context),
+ ENCODER_CONTEXT_ERR,
+ "gst_vaapi_context_new failed.");
+
+ if (base_class->pre_alloc_resource) {
+ ENCODER_CHECK_STATUS(
+ base_class->pre_alloc_resource(base_encoder, out_context),
+ ENCODER_MEM_ERR,
+ "encoder <pre_alloc_resource> failed."
+ );
+ }
+ ENCODER_CHECK_STATUS(
+ base_encoder_alloc_coded_buffers(base_encoder, out_context),
+ ENCODER_MEM_ERR,
+ "encoder <base_encoder_alloc_coded_buffers> failed."
+ );
+ *context = out_context;
+
+ return ENCODER_NO_ERROR;
+
+end:
+ // clear resources
+ if (ENCODER_NO_ERROR != ret) {
+ gst_vaapi_base_encoder_close_default(encoder);
+ if (out_context) {
+ g_object_unref(out_context);
+ }
+ }
+ return ret;
+}
+
+static GstBuffer *
+gst_vaapi_base_encoder_copy_buffer_default(
+ GstVaapiBaseEncoder *encoder,
+ guint8 *frame,
+ guint32 frame_size,
+ VABufferID *coded_buf
+)
+{
+ GstBuffer *ret_buffer = NULL;
+#if SHARE_CODED_BUF
+ ret_buffer = gst_base_encode_share_buffer_new(encoder, coded_buf);
+ ENCODER_ASSERT(ret_buffer);
+ GST_BUFFER_MALLOCDATA(ret_buffer) = NULL;
+ GST_BUFFER_DATA(ret_buffer) = frame;
+ GST_BUFFER_SIZE(ret_buffer) = frame_size;
+#else
+ ret_buffer = gst_buffer_new_and_alloc(frame_size);
+ memcpy(GST_BUFFER_DATA(ret_buffer),frame, frame_size);
+#endif
+ return ret_buffer;
+}
+
+static EncoderStatus
+base_query_encoding_status(
+ GstVaapiBaseEncoder *base_encoder,
+ GstVaapiSurface *buffer_surface,
+ gboolean is_key,
+ GstVaapiVideoBuffer *surface_buffer,
+ VABufferID *coded_buf,
+ GList **coded_pics
+)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ VASurfaceStatus surface_status = 0;
+ VACodedBufferSegment *buf_list = NULL;
+ GstBuffer* ret_buffer = NULL;
+ gboolean has_coded_data = FALSE;
+ gboolean is_locked = FALSE;
+ GstVaapiBaseEncoderClass *base_class =
+ GST_VAAPI_BASE_ENCODER_GET_CLASS(base_encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base_encoder);
+
+ ENCODER_ASSERT(display);
+ VASurfaceID surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(base_encoder);
+
+ ENCODER_ASSERT(coded_pics);
+ VAAPI_UNUSED_ARG(has_coded_data);
+
+ /* lock display */
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+
+ va_status = vaSyncSurface(va_dpy, surface_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_QUERY_STATUS_ERR,
+ "vaSyncSurface failed.");
+
+ va_status = vaQuerySurfaceStatus(va_dpy, surface_id, &surface_status);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_QUERY_STATUS_ERR,
+ "vaQuerySurfaceStatus failed.");
+ if (VASurfaceSkipped & surface_status) {
+ ENCODER_LOG_ERROR("frame skipped, dts:%" GST_TIME_FORMAT,
+ GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(surface_buffer)));
+ }
+
+ va_status = vaMapBuffer(va_dpy, *coded_buf, (void **)(&buf_list));
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_QUERY_STATUS_ERR,
+ "vaMapBuffer failed.");
+
+ /*unlock display*/
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+
+ while (buf_list != NULL) {
+ GstBuffer *new_data = NULL;
+ if (priv->frame_notify_flag && base_class->notify_frame) {
+ base_class->notify_frame(base_encoder,
+ buf_list->buf,
+ buf_list->size);
+ }
+
+ if (base_class->copy_coded_frame) {
+ new_data = base_class->copy_coded_frame(
+ base_encoder,
+ buf_list->buf,
+ buf_list->size,
+ coded_buf);
+ } else {
+ new_data = gst_vaapi_base_encoder_copy_buffer_default(
+ base_encoder,
+ buf_list->buf,
+ buf_list->size,
+ coded_buf);
+ }
+
+ if (!ret_buffer)
+ ret_buffer = new_data;
+ else if (new_data)
+ ret_buffer = gst_buffer_join(ret_buffer, new_data);
+ buf_list = (VACodedBufferSegment*)buf_list->next;
+ has_coded_data = TRUE;
+ }
+
+ if (ret_buffer) {
+ GST_BUFFER_TIMESTAMP(ret_buffer) = GST_BUFFER_TIMESTAMP(surface_buffer);
+ GST_BUFFER_DURATION(ret_buffer) = GST_BUFFER_DURATION(surface_buffer);
+ if (!is_key) {
+ GST_BUFFER_FLAG_SET(ret_buffer, GST_BUFFER_FLAG_DELTA_UNIT);
+ }
+ GST_BUFFER_OFFSET_END(ret_buffer) =
+ GST_BUFFER_OFFSET_END(surface_buffer);
+ *coded_pics = g_list_append(*coded_pics, ret_buffer);
+ }
+ FPS_CALCULATION(vaapiencode);
+
+#if SHARE_CODED_BUF
+ if (!has_coded_data)
+#endif
+ { // if non-related, push back to available_code_buffers
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ vaUnmapBuffer(va_dpy, *coded_buf);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ push_available_coded_buffer(priv, coded_buf);
+ }
+
+ return ENCODER_NO_ERROR;
+
+end:
+ /*unlock display*/
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ return ret;
+}
+
+static EncoderStatus
+gst_vaapi_base_encoder_encode_default(
+ GstVaapiEncoder* encoder,
+ GstBuffer *raw_pic,
+ GList **coded_pics
+)
+{
+ GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
+ GstVaapiBaseEncoderClass *base_class =
+ GST_VAAPI_BASE_ENCODER_GET_CLASS(encoder);
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+ GstVaapiContext *context = ENCODER_CONTEXT(encoder);
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ gboolean is_key = FALSE;
+ VABufferID* coded_buf = NULL;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ VASurfaceID buffer_surface_id = VA_INVALID_SURFACE;
+ GstVaapiSurface *buffer_surface = NULL;
+ gboolean is_locked = FALSE;
+ VADisplay va_dpy;
+ VAContextID context_id;
+
+ ENCODER_ASSERT(display && context);
+ va_dpy = ENCODER_VA_DISPLAY(encoder);
+ context_id = ENCODER_VA_CONTEXT(encoder);
+
+ /* Video Buffer */
+ GstVaapiVideoBuffer *video_buffer = NULL;
+
+ ENCODER_CHECK_STATUS(raw_pic || base_class->prepare_next_input_buffer,
+ ENCODER_DATA_ERR,
+ "Need a picture to encode");
+ if (raw_pic) {
+ /* load picture to surface */
+ if (GST_VAAPI_IS_VIDEO_BUFFER(raw_pic)) {
+ video_buffer = GST_VAAPI_VIDEO_BUFFER(raw_pic);
+ gst_buffer_ref(GST_BUFFER_CAST(video_buffer));
+ } else {
+ /* do something else */
+ }
+ } else {
+ priv->need_flush = TRUE;
+ }
+
+again:
+ if (base_class->prepare_next_input_buffer) {
+ GstVaapiVideoBuffer* tmp_buf = NULL;
+ ret = base_class->prepare_next_input_buffer(base_encoder,
+ video_buffer,
+ priv->need_flush,
+ &tmp_buf);
+ priv->need_flush = FALSE;
+ if (video_buffer) {
+ gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
+ video_buffer = NULL;
+ }
+ if (ret != ENCODER_NO_ERROR || !tmp_buf)
+ goto end;
+ video_buffer = tmp_buf;
+ }
+
+ buffer_surface = gst_vaapi_video_buffer_get_surface(video_buffer);
+ buffer_surface_id = (VASurfaceID)GST_VAAPI_OBJECT_ID(buffer_surface);
+ ENCODER_CHECK_STATUS(buffer_surface_id != VA_INVALID_SURFACE,
+ ENCODER_SURFACE_ERR,
+ "surface id == VA_INVALID_SURFACE");
+
+ /* begin surface*/
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ va_status = vaBeginPicture(va_dpy, context_id, buffer_surface_id);
+ //ENCODER_RELEASE_DISPLAY_LOCK(display);
+
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_PICTURE_ERR,
+ "vaBeginPicture error");
+
+ /*get valid coded buffer*/
+ coded_buf = pop_available_coded_buffer(priv);
+ ENCODER_CHECK_STATUS(coded_buf,
+ ENCODER_ENC_RES_ERR,
+ "dequeue_available_coded_buffer error");
+
+ /* prepare frame*/
+ ret = base_class->render_frame(base_encoder,
+ buffer_surface,
+ priv->frame_count,
+ *coded_buf,
+ &is_key);
+ /* prepare failed, push back */
+ if (ENCODER_NO_ERROR != ret) {
+ push_available_coded_buffer(priv, coded_buf);
+ }
+ ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
+ ENCODER_PICTURE_ERR,
+ "base_prepare_encoding failed");
+
+ /* end picture */
+ //ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ va_status = vaEndPicture(va_dpy, context_id);
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_PICTURE_ERR,
+ "vaEndPicture error");
+
+ /*query surface result*/
+ ret = base_query_encoding_status(base_encoder,
+ buffer_surface,
+ is_key,
+ video_buffer,
+ coded_buf,
+ coded_pics);
+ if (ENCODER_NO_ERROR != ret) {
+ goto end;
+ }
+
+ priv->frame_count++;
+
+ if (base_class->prepare_next_input_buffer) {
+ if (video_buffer) {
+ gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
+ }
+ video_buffer = NULL;
+ buffer_surface = NULL;
+ goto again;
+ }
+
+end:
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ if (ret > ENCODER_NO_ERROR) {
+ ret = ENCODER_NO_ERROR;
+ }
+ if (ret < 0 && base_class->encode_frame_failed) {
+ base_class->encode_frame_failed(base_encoder, video_buffer);
+ }
+ if (video_buffer) {
+ gst_buffer_unref(GST_BUFFER_CAST(video_buffer));
+ video_buffer = NULL;
+ }
+ return ret;
+}
+
+static VABufferID *
+pop_available_coded_buffer(GstVaapiBaseEncoderPrivate *priv)
+{
+ VABufferID *coded_buf = NULL;
+ gboolean ret = TRUE;
+
+ g_mutex_lock(priv->code_buffer_lock);
+
+ ENCODER_CHECK_STATUS(priv->available_code_buffers,
+ FALSE,
+ "coded buffer not found");
+ while (g_queue_is_empty(priv->available_code_buffers)) {
+ g_cond_wait(priv->code_buffer_cond, priv->code_buffer_lock);
+ }
+ coded_buf = (VABufferID*)g_queue_pop_head (priv->available_code_buffers);
+
+end:
+ g_mutex_unlock(priv->code_buffer_lock);
+ VAAPI_UNUSED_ARG(ret);
+ return coded_buf;
+}
+
+static gboolean
+push_available_coded_buffer(
+ GstVaapiBaseEncoderPrivate *priv,
+ VABufferID *buf
+)
+{
+ g_mutex_lock(priv->code_buffer_lock);
+ g_queue_push_head(priv->available_code_buffers, buf);
+ g_cond_signal(priv->code_buffer_cond);
+ g_mutex_unlock(priv->code_buffer_lock);
+ return TRUE;
+}
+
+#if 0
+static EncoderStatus
+base_put_raw_buffer_to_surface(GstVaapiBaseEncoder *base_encoder,
+ GstVaapiDisplay *display,
+ GstBuffer *raw_pic,
+ GstVaapiSurface *surface)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiImage *image;
+ GstVaapiImageFormat image_format;
+ guint8 *y_src = NULL, *u_src = NULL, *v_src = NULL;
+ guint8 *y_dst = NULL, *u_dst = NULL, *v_dst = NULL;
+ int y_size = 0, u_size = 0;
+ int row = 0, col = 0;
+ guint32 plane_count = 0;
+ guint32 image_width = 0, image_height = 0;
+ guint32 pitchy = 0, pitchu = 0, pitchv = 0;
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+
+ ENCODER_ASSERT(display);
+ VAAPI_UNUSED_ARG(pitchv);
+ VAAPI_UNUSED_ARG(v_dst);
+ /*map image*/
+ image = gst_vaapi_surface_derive_image(surface);
+ gst_vaapi_image_map(image);
+
+ image_format = gst_vaapi_image_get_format(image);
+ image_width = gst_vaapi_image_get_width(image);
+ image_height = gst_vaapi_image_get_height(image);
+
+ /* copy buffer to surface */
+ ENCODER_ASSERT(GST_BUFFER_SIZE(raw_pic) >= y_size + (y_size>>1));
+
+ y_size = ENCODER_WIDTH(base_encoder) * ENCODER_HEIGHT(base_encoder);
+ u_size = ((ENCODER_WIDTH(base_encoder)+1) >> 1) * ((ENCODER_HEIGHT(base_encoder)+1) >> 1);
+
+ y_src = GST_BUFFER_DATA(raw_pic);
+ u_src = y_src + y_size;
+ v_src = u_src + u_size;
+
+ plane_count = gst_vaapi_image_get_plane_count(image);
+ y_dst = gst_vaapi_image_get_plane(image, 0);
+ u_dst = gst_vaapi_image_get_plane(image, 1);
+ pitchy = gst_vaapi_image_get_pitch(image, 0);
+ pitchu = gst_vaapi_image_get_pitch(image, 1);
+
+ if (plane_count > 2) {
+ v_dst = gst_vaapi_image_get_plane(image, 2);
+ pitchv = gst_vaapi_image_get_pitch(image, 2);
+ }
+
+ /* copy from avcenc.c*/
+ /* Y plane */
+ for (row = 0; row < image_height; row++) {
+ memcpy(y_dst, y_src, image_width);
+ y_dst += pitchy;
+ y_src += ENCODER_WIDTH(base_encoder);
+ }
+
+ if (GST_VAAPI_IMAGE_NV12 == image_format) { /* UV plane */
+ if (GST_VAAPI_IMAGE_I420 == priv->format) {
+ for (row = 0; row < image_height / 2; row++) {
+ for (col = 0; col < image_width / 2; col++) {
+ u_dst[col * 2] = u_src[col];
+ u_dst[col * 2 + 1] = v_src[col];
+ }
+
+ u_dst += pitchu;
+ u_src += (ENCODER_WIDTH(base_encoder)>>1);
+ v_src += (ENCODER_WIDTH(base_encoder)>>1);
+ }
+ } else if (GST_VAAPI_IMAGE_NV12 == priv->format){
+ for (row = 0; row < image_height / 2; row++) {
+ memcpy(u_dst, u_src, image_width);
+ u_src += ENCODER_WIDTH(base_encoder);
+ u_dst += pitchu;
+ }
+ } else {
+ ENCODER_ASSERT(0);
+ }
+ } else {
+ /* FIXME: fix this later */
+ ENCODER_ASSERT(0);
+ }
+
+ /*unmap image*/
+ g_object_unref(image);
+
+ return ret;
+}
+#endif
+
+static EncoderStatus
+gst_vaapi_base_encoder_flush_default(
+ GstVaapiEncoder* encoder,
+ GList **coded_pics
+)
+{
+ GstVaapiBaseEncoder* base_encoder = GST_VAAPI_BASE_ENCODER(encoder);
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiBaseEncoderPrivate *priv = base_encoder->priv;
+
+ priv->frame_count = 0;
+ priv->need_flush = TRUE;
+ /*do we need destroy priv->seq_parameter? */
+
+ //end:
+ return ret;
+}
+
+
+static void
+gst_vaapi_base_encoder_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+ GstVaapiBaseEncoderPrivate *priv =
+ GST_VAAPI_BASE_ENCODER_GET_PRIVATE(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+
+ g_mutex_free(priv->code_buffer_lock);
+ g_cond_free(priv->code_buffer_cond);
+ if (priv->available_code_buffers) {
+ g_queue_free(priv->available_code_buffers);
+ priv->available_code_buffers = NULL;
+ }
+
+ G_OBJECT_CLASS(gst_vaapi_base_encoder_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_base_encoder_init(GstVaapiBaseEncoder *encoder)
+{
+ GstVaapiBaseEncoderPrivate *priv =
+ GST_VAAPI_BASE_ENCODER_GET_PRIVATE(encoder);
+ ENCODER_ASSERT(priv);
+ encoder->priv = priv;
+
+ /* init private values*/
+ priv->format = 0;
+ priv->profile= VA_INVALID_PROFILE;
+ priv->frame_count = 0;
+ priv->frame_notify_flag = FALSE;
+
+ priv->coded_bufs = NULL;
+ priv->coded_buf_num = DEFAULT_VA_CODEDBUF_NUM;
+ priv->code_buffer_lock = g_mutex_new();
+ priv->code_buffer_cond = g_cond_new();
+ priv->available_code_buffers = g_queue_new();
+
+ priv->need_flush = FALSE;
+}
+
+static void
+gst_vaapi_base_encoder_class_init(GstVaapiBaseEncoderClass *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ g_type_class_add_private(klass, sizeof(GstVaapiBaseEncoderPrivate));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_base_encoder_debug,
+ "gst_vaapi_base_encoder",
+ 0,
+ "gst_vaapi_base_encoder element");
+
+ object_class->finalize = gst_vaapi_base_encoder_finalize;
+
+ encoder_class->open = gst_vaapi_base_encoder_open_default;
+ encoder_class->close = gst_vaapi_base_encoder_close_default;
+ encoder_class->encode = gst_vaapi_base_encoder_encode_default;
+ encoder_class->flush = gst_vaapi_base_encoder_flush_default;
+ encoder_class->get_codec_data = NULL;
+
+ /* user defined functions*/
+ klass->validate_attributes = NULL;
+ klass->pre_alloc_resource = NULL;
+ klass->release_resource = NULL;
+ klass->prepare_next_input_buffer = NULL;
+ klass->render_frame = NULL;
+ klass->notify_frame = NULL;
+ klass->copy_coded_frame = NULL;
+ klass->encode_frame_failed = NULL;
+
+ /*
+ object_class->set_property = gst_vaapi_base_encoder_set_property;
+ object_class->get_property = gst_vaapi_base_encoder_get_property;
+ */
+}
--- /dev/null
+/*
+ * gstvaapibaseencoder.h - VA-API base encoder
+ *
+ * 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_BASE_ENCODER_H
+#define GST_VAAPI_BASE_ENCODER_H
+
+#include "gst/vaapi/gstvaapiencoder.h"
+#include "gst/vaapi/gstvaapivideobuffer.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GstVaapiBaseEncoder GstVaapiBaseEncoder;
+typedef struct _GstVaapiBaseEncoderPrivate GstVaapiBaseEncoderPrivate;
+typedef struct _GstVaapiBaseEncoderClass GstVaapiBaseEncoderClass;
+
+#define GST_TYPE_VAAPI_BASE_ENCODER \
+ (gst_vaapi_base_encoder_get_type())
+
+#define GST_IS_VAAPI_BASE_ENCODER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_BASE_ENCODER))
+
+#define GST_IS_VAAPI_BASE_ENCODER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_BASE_ENCODER))
+
+#define GST_VAAPI_BASE_ENCODER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_BASE_ENCODER, \
+ GstVaapiBaseEncoderClass))
+
+#define GST_VAAPI_BASE_ENCODER(obj) \
+(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_BASE_ENCODER, \
+ GstVaapiBaseEncoder))
+
+#define GST_VAAPI_BASE_ENCODER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_BASE_ENCODER, \
+ GstVaapiBaseEncoderClass))
+
+#define GST_VAAPI_BASE_ENCODER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_TYPE_VAAPI_BASE_ENCODER, \
+ GstVaapiBaseEncoderPrivate))
+
+struct _GstVaapiBaseEncoder {
+ GstVaapiEncoder parent;
+
+ GstVaapiBaseEncoderPrivate *priv;
+};
+
+struct _GstVaapiBaseEncoderClass {
+ GstVaapiEncoderClass parent_class;
+
+ /* in <open> function*/
+ gboolean (*validate_attributes) (GstVaapiBaseEncoder* encoder);
+ gboolean (*pre_alloc_resource) (GstVaapiBaseEncoder *encoder,
+ GstVaapiContext* context);
+
+ /* in <close> function */
+ gboolean (*release_resource) (GstVaapiBaseEncoder* encoder);
+
+ /* in <encode> function */
+ EncoderStatus (*prepare_next_input_buffer)(GstVaapiBaseEncoder* encoder,
+ GstVaapiVideoBuffer *display_buf,
+ gboolean need_flush,
+ GstVaapiVideoBuffer **out_buf);
+
+ EncoderStatus (*render_frame) (GstVaapiBaseEncoder *encoder,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key);
+
+ void (*encode_frame_failed) (GstVaapiBaseEncoder *encoder,
+ GstVaapiVideoBuffer* buffer);
+
+ void (*notify_frame) (GstVaapiBaseEncoder *encoder,
+ guint8 *buf, guint32 size);
+
+ GstBuffer *(*copy_coded_frame) (GstVaapiBaseEncoder *encoder,
+ guint8 *buf, guint32 size,
+ VABufferID *coded_buf);
+};
+
+GType
+gst_vaapi_base_encoder_get_type(void);
+
+void
+gst_vaapi_base_encoder_set_frame_notify(
+ GstVaapiBaseEncoder *encoder,
+ gboolean flag
+);
+
+gboolean
+gst_vaapi_base_encoder_set_va_profile(
+ GstVaapiBaseEncoder *encoder,
+ guint profile
+);
+void
+gst_vaapi_base_encoder_set_input_format(
+ GstVaapiBaseEncoder* encoder,
+ guint32 format
+);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_BASE_ENCODER_H */
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <string.h>
+#include <gst/vaapi/gstvaapicontext.h>
+#include "gstvaapicodec_objects.h"
+#include "gstvaapidecoder_priv.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+/* ------------------------------------------------------------------------- */
+/* --- Base Codec Object --- */
+/* ------------------------------------------------------------------------- */
+
+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;
+ args.flags = 0;
+ 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
+)
+{
+ 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
+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
+)
+{
+ return vaapi_create_buffer(GET_VA_DISPLAY(bitplane),
+ GET_VA_CONTEXT(bitplane),
+ VABitPlaneBufferType,
+ args->param_size,
+ args->param,
+ &bitplane->data_id,
+ (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)
+{
+ 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);
+}
+
+/* ------------------------------------------------------------------------- */
+/* --- JPEG Huffman Tables --- */
+/* ------------------------------------------------------------------------- */
+
+#if USE_JPEG_DECODER
+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);
+}
+#endif
--- /dev/null
+/*
+ * 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 <gst/gstminiobject.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+
+G_BEGIN_DECLS
+
+typedef gpointer GstVaapiCodecBase;
+typedef struct _GstVaapiCodecObject GstVaapiCodecObject;
+typedef struct _GstVaapiCodecObjectClass GstVaapiCodecObjectClass;
+typedef struct _GstVaapiIqMatrix GstVaapiIqMatrix;
+typedef struct _GstVaapiIqMatrixClass GstVaapiIqMatrixClass;
+typedef struct _GstVaapiBitPlane GstVaapiBitPlane;
+typedef struct _GstVaapiBitPlaneClass GstVaapiBitPlaneClass;
+typedef struct _GstVaapiHuffmanTable GstVaapiHuffmanTable;
+typedef struct _GstVaapiHuffmanTableClass GstVaapiHuffmanTableClass;
+
+/* ------------------------------------------------------------------------- */
+/* --- 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;
+ guint flags;
+} 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);
+};
+
+G_GNUC_INTERNAL
+GType
+gst_vaapi_codec_object_get_type(void) 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
+);
+
+/* ------------------------------------------------------------------------- */
+/* --- 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;
+};
+
+G_GNUC_INTERNAL
+GType
+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
+);
+
+/* ------------------------------------------------------------------------- */
+/* --- 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;
+};
+
+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);
+
+/* ------------------------------------------------------------------------- */
+/* --- 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;
+};
+
+G_GNUC_INTERNAL
+GType
+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
+);
+
+/* ------------------------------------------------------------------------- */
+/* --- 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)
+
+#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
+
+#endif /* GST_VAAPI_CODEC_OBJECTS_H */
--- /dev/null
+/*
+ * gstvapicompat.h - VA-API compatibility glue
+ *
+ * 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_COMPAT_H
+#define GST_VAAPI_COMPAT_H
+
+#include <va/va.h>
+
+#ifdef HAVE_VA_VA_GLX_H
+# define USE_VAAPI_GLX 1
+#else
+# define USE_VAAPI_GLX 0
+#endif
+
+#if USE_VAAPI_GLX
+# include <va/va_glx.h>
+#else
+# define vaGetDisplayGLX(dpy) vaGetDisplay(dpy)
+#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
+
+/* Compatibility glue with VA-API 0.34 */
+#if VA_CHECK_VERSION(0,34,0)
+# include <va/va_compat.h>
+#endif
+
+#endif /* GST_VAAPI_COMPAT_H */
--- /dev/null
+/*
+ * gstvaapicontext.c - VA context 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:gstvaapicontext
+ * @short_description: VA context abstraction
+ */
+
+#include "sysdeps.h"
+#include <assert.h>
+#include "gstvaapicompat.h"
+#include "gstvaapicontext.h"
+#include "gstvaapisurface.h"
+#include "gstvaapisurface_priv.h"
+#include "gstvaapisurfacepool.h"
+#include "gstvaapiimage.h"
+#include "gstvaapisubpicture.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))
+
+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;
+ guint surface_num;
+ GPtrArray *overlay;
+ GstVaapiProfile profile;
+ GstVaapiEntrypoint entrypoint;
+ guint width;
+ guint height;
+ guint is_constructed : 1;
+};
+
+enum {
+ PROP_0,
+
+ PROP_PROFILE,
+ PROP_ENTRYPOINT,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_SURFACE_NUM
+};
+
+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)
+{
+ GstVaapiSurface * const surface = GST_VAAPI_SURFACE(data);
+
+ gst_vaapi_surface_set_parent_context(surface, NULL);
+ g_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;
+ }
+
+ g_clear_object(&priv->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;
+
+ 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_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_increase_surfaces(GstVaapiContext *context,guint increment)
+{
+ GstVaapiContextPrivate * const priv = context->priv;
+ GstVaapiVideoPool * surface_pool;
+ GstVaapiSurface *surface;
+ guint i;
+
+ surface_pool = priv->surfaces_pool;
+ if (!priv->surfaces || !surface_pool)
+ return FALSE;
+
+ if ((priv->surfaces->len + increment) >
+ gst_vaapi_video_pool_get_capacity(surface_pool))
+ return FALSE;
+
+ for (i = 0; i < increment; ++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;
+ }
+ priv->surface_num = priv->surfaces->len;
+ return TRUE;
+}
+
+
+static gboolean
+gst_vaapi_context_create_surfaces(GstVaapiContext *context, guint surface_num)
+{
+ GstVaapiContextPrivate * const priv = context->priv;
+ GstCaps *caps;
+ GstVaapiSurface *surface;
+ guint i, pool_capacity;
+
+ if (!gst_vaapi_context_create_overlay(context))
+ return FALSE;
+
+ if (!priv->surfaces) {
+ priv->surfaces = g_ptr_array_new();
+ if (!priv->surfaces)
+ return FALSE;
+ }
+
+ if (!priv->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,
+ 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;
+ }
+
+ pool_capacity =
+ ((gst_vaapi_profile_get_codec(priv->profile) == GST_VAAPI_CODEC_H264) ? 20 : 6);
+ if (pool_capacity < surface_num)
+ pool_capacity = surface_num;
+ gst_vaapi_video_pool_set_capacity(priv->surfaces_pool, pool_capacity);
+
+ for (i = priv->surfaces->len; i < surface_num; 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;
+ }
+ priv->surface_num = priv->surfaces->len;
+ 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 attribs[2];
+ guint attribs_num;
+ 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, priv->surface_num))
+ 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);
+ attribs[0].type = VAConfigAttribRTFormat;
+ attribs[1].type = VAConfigAttribRateControl;
+ if (VAEntrypointEncSlice == va_entrypoint)
+ attribs_num = 2;
+ else
+ attribs_num = 1;
+
+ status = vaGetConfigAttributes(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ va_profile,
+ va_entrypoint,
+ attribs, attribs_num
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaGetConfigAttributes()"))
+ goto end;
+ if (!(attribs[0].value & VA_RT_FORMAT_YUV420))
+ goto end;
+ if (attribs_num > 1) {
+ if (attribs[1].value & VA_RC_NONE)
+ attribs[1].value = VA_RC_NONE;
+ else if (attribs[1].value & VA_RC_CBR)
+ attribs[1].value = VA_RC_CBR;
+ else if (attribs[1].value & VA_RC_VBR)
+ attribs[1].value = VA_RC_VBR;
+ else
+ goto end;
+ }
+
+ GST_VAAPI_DISPLAY_LOCK(display);
+ status = vaCreateConfig(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ va_profile,
+ va_entrypoint,
+ attribs, attribs_num,
+ &priv->config_id
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaCreateConfig()"))
+ goto end;
+
+ VASurfaceID *surface_ids = (VASurfaceID*)surfaces->data;
+ int surface_num = surfaces->len;
+#if 0
+ if (VAEntrypointEncSlice == va_entrypoint) {
+ surface_ids = NULL;
+ surface_num = 0;
+ }
+#endif
+ GST_VAAPI_DISPLAY_LOCK(display);
+ status = vaCreateContext(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ priv->config_id,
+ priv->width, priv->height,
+ VA_PROGRESSIVE,
+ (VASurfaceID *)surface_ids, surface_num,
+ &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;
+ case PROP_SURFACE_NUM:
+ priv->surface_num = 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_SURFACE_NUM:
+ g_value_set_uint(value, priv->surface_num);
+ 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_SURFACE_NUM,
+ g_param_spec_uint("surface_num",
+ "Surface Number",
+ "The decoded surfaces number",
+ 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->overlay = 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,
+ unsigned int surface_num
+)
+{
+ 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,
+ "surface_num", surface_num,
+ 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,
+ unsigned int surface_num
+)
+{
+ GstVaapiContextPrivate * const priv = context->priv;
+ gboolean size_changed, codec_changed, surface_increased;
+
+ 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;
+ }
+
+ surface_increased = !size_changed && priv->surfaces &&
+ (priv->surfaces->len < surface_num);
+
+ if (size_changed && !gst_vaapi_context_create_surfaces(context, surface_num))
+ return FALSE;
+ if (surface_increased &&
+ !gst_vaapi_context_increase_surfaces(context,
+ surface_num - priv->surfaces->len))
+ 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,
+ context->priv->surface_num);
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * gst_vaapi_context_get_surface_pool:
+ * @context: a #GstVaapiContext
+ *
+ * Reference the surface pool. The returned surface pool should be released with
+ * g_object_unref(). This function returns %NULL if
+ * there is the surface pool is empty. The surface pool is
+ * created during context creation though.
+ *
+ * Return value: surface pool, or %NULL if it is not created.
+ */
+
+GstVaapiSurfacePool *
+gst_vaapi_context_get_surface_pool(GstVaapiContext *context)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), NULL);
+ return (GstVaapiSurfacePool*)g_object_ref(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_get_surface_left_capability:
+ * @context: a #GstVaapiContext
+ *
+ * Retrieves the number of unallocated surfaces left in the pool.
+ *
+ * Return value: the number of unallocated surfaces in the pool
+ */
+
+guint
+gst_vaapi_context_get_surface_left_capability(GstVaapiContext *context)
+{
+ GstVaapiContextPrivate * const priv = context->priv;
+
+ g_return_val_if_fail(GST_VAAPI_IS_CONTEXT(context), 0);
+ g_return_val_if_fail(priv->surfaces, 0);
+
+ return (gst_vaapi_video_pool_get_capacity(priv->surfaces_pool) -
+ priv->surfaces->len);
+}
+
+/**
+ * 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_surface_set_parent_context(surface, NULL);
+ 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;
+}
+
+/* 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;
+}
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GST_VAAPI_CONTEXT_H
+#define GST_VAAPI_CONTEXT_H
+
+#include <gst/vaapi/gstvaapiobject.h>
+#include <gst/vaapi/gstvaapiprofile.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/video/video-overlay-composition.h>
+#include <gst/vaapi/gstvaapisurfacepool.h>
+
+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) G_GNUC_CONST;
+
+GstVaapiContext *
+gst_vaapi_context_new(
+ GstVaapiDisplay *display,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint,
+ guint width,
+ guint height,
+ guint surface_num
+);
+
+gboolean
+gst_vaapi_context_reset(
+ GstVaapiContext *context,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint,
+ unsigned int width,
+ unsigned int height,
+ unsigned int surface_num
+);
+
+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);
+
+GstVaapiSurfacePool *
+gst_vaapi_context_get_surface_pool(GstVaapiContext *context);
+
+
+guint
+gst_vaapi_context_get_surface_count(GstVaapiContext *context);
+
+guint
+gst_vaapi_context_get_surface_left_capability(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,
+ GstVideoOverlayComposition *composition
+);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_CONTEXT_H */
--- /dev/null
+/*
+ * gstvaapidebug.h - VA-API debugging utilities
+ *
+ * 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_DEBUG_H
+#define GST_VAAPI_DEBUG_H
+
+#include <gst/gstinfo.h>
+#include <sys/time.h>
+#include <gst/gst.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+
+#if DEBUG
+GST_DEBUG_CATEGORY_EXTERN(gst_debug_vaapi);
+#define GST_CAT_DEFAULT gst_debug_vaapi
+#endif
+/* FPS Calculation for DEBUG */
+#define FPS_CALCULATION(objname) \
+ do{ \
+ static guint num_frame = 0; \
+ static struct timeval last_sys_time; \
+ static struct timeval first_sys_time; \
+ static int b_last_sys_time_init = FALSE; \
+ if (!b_last_sys_time_init) { \
+ gettimeofday (&last_sys_time, NULL); \
+ gettimeofday (&first_sys_time, NULL); \
+ b_last_sys_time_init = TRUE; \
+ } else { \
+ if ((num_frame%50)==0) { \
+ double total, current; \
+ struct timeval cur_sys_time; \
+ gettimeofday (&cur_sys_time, NULL); \
+ total = (cur_sys_time.tv_sec - first_sys_time.tv_sec)*1.0f + \
+ (cur_sys_time.tv_usec - first_sys_time.tv_usec)/1000000.0f; \
+ current = (cur_sys_time.tv_sec - last_sys_time.tv_sec)*1.0f + \
+ (cur_sys_time.tv_usec - last_sys_time.tv_usec)/1000000.0f; \
+ printf("%s Current fps: %.2f, Total avg fps: %.2f\n", \
+ #objname, (float)50.0f/current, (float)num_frame/total); \
+ last_sys_time = cur_sys_time; \
+ } \
+ } \
+ ++num_frame; \
+ }while(0)
+
+
+#endif /* GST_VAAPI_DEBUG_H */
--- /dev/null
+/*
+ * gstvaapidecoder.c - VA decoder 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:gstvaapidecoder
+ * @short_description: VA decoder abstraction
+ */
+
+#include "sysdeps.h"
+#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_CAPS,
+
+ N_PROPERTIES
+};
+
+static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
+
+static void
+destroy_buffer(GstBuffer *buffer)
+{
+ gst_buffer_unref(buffer);
+}
+
+static gboolean
+push_buffer(GstVaapiDecoder *decoder, GstBuffer *buffer)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ 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 (%d bytes)",
+ buffer, GST_BUFFER_SIZE(buffer));
+
+ g_queue_push_tail(priv->buffers, 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)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ GstBuffer *buffer;
+
+ buffer = g_queue_pop_head(priv->buffers);
+ if (!buffer)
+ return NULL;
+
+ GST_DEBUG("dequeue buffer %p for decoding (%d bytes)",
+ buffer, GST_BUFFER_SIZE(buffer));
+
+ return buffer;
+}
+
+static GstVaapiDecoderStatus
+decode_step(GstVaapiDecoder *decoder)
+{
+ GstVaapiDecoderStatus status;
+ GstBuffer *buffer;
+
+ /* 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;
+
+ 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 && GST_BUFFER_IS_EOS(buffer))
+ status = GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
+ gst_buffer_unref(buffer);
+ } while (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA);
+ return status;
+}
+
+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)));
+
+ g_queue_push_tail(priv->surfaces, proxy);
+}
+
+static inline GstVaapiSurfaceProxy *
+pop_surface(GstVaapiDecoder *decoder)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ 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)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ 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_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;
+
+ 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)
+{
+ while (!g_queue_is_empty(q))
+ destroy(g_queue_pop_head(q));
+}
+
+static void
+gst_vaapi_decoder_finalize(GObject *object)
+{
+ GstVaapiDecoder * const decoder = GST_VAAPI_DECODER(object);
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+
+ 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;
+ priv->va_context = VA_INVALID_ID;
+ }
+
+ if (priv->buffers) {
+ clear_queue(priv->buffers, (GDestroyNotify)destroy_buffer);
+ g_queue_free(priv->buffers);
+ priv->buffers = NULL;
+ }
+
+ if (priv->surfaces) {
+ clear_queue(priv->surfaces, (GDestroyNotify)g_object_unref);
+ g_queue_free(priv->surfaces);
+ priv->surfaces = NULL;
+ }
+
+ 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);
+}
+
+static void
+gst_vaapi_decoder_set_property(
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+)
+{
+ 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
+)
+{
+ GstVaapiDecoderPrivate * const priv = GST_VAAPI_DECODER(object)->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);
+ 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);
+
+ 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->buffers = g_queue_new();
+ priv->surfaces = g_queue_new();
+ priv->is_interlaced = FALSE;
+}
+
+/**
+ * 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
+ * @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);
+
+ return push_buffer(decoder, buf ? gst_buffer_ref(buf) : NULL);
+}
+
+/**
+ * gst_vaapi_decoder_get_surface:
+ * @decoder: a #GstVaapiDecoder
+ * @pstatus: return location for the decoder status, or %NULL
+ *
+ * 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.
+ */
+GstVaapiSurfaceProxy *
+gst_vaapi_decoder_get_surface(
+ GstVaapiDecoder *decoder,
+ GstVaapiDecoderStatus *pstatus
+)
+{
+ GstVaapiSurfaceProxy *proxy;
+ GstVaapiDecoderStatus status;
+
+ if (pstatus)
+ *pstatus = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
+
+ proxy = pop_surface(decoder);
+ if (!proxy) {
+ do {
+ status = decode_step(decoder);
+ } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
+ proxy = pop_surface(decoder);
+ }
+
+ if (proxy)
+ status = GST_VAAPI_DECODER_STATUS_SUCCESS;
+
+ if (pstatus)
+ *pstatus = status;
+ return proxy;
+}
+
+void
+gst_vaapi_decoder_clear_buffer(GstVaapiDecoder *decoder)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ GstVaapiDecoderClass * const klass = GST_VAAPI_DECODER_GET_CLASS(decoder);
+
+ if (klass->clear_buffer)
+ klass->clear_buffer(decoder);
+
+ if (priv->buffers)
+ clear_queue(priv->buffers, (GDestroyNotify)destroy_buffer);
+
+ if (priv->surfaces)
+ clear_queue(priv->surfaces, (GDestroyNotify)g_object_unref);
+}
+
+void
+gst_vaapi_decoder_set_picture_size(
+ GstVaapiDecoder *decoder,
+ guint width,
+ guint height
+)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ 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);
+ 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);
+ size_changed = TRUE;
+ }
+
+ if (size_changed)
+ g_object_notify_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]);
+}
+
+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_by_pspec(G_OBJECT(decoder), g_properties[PROP_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_by_pspec(G_OBJECT(decoder), g_properties[PROP_CAPS]);
+ }
+}
+
+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]);
+ }
+}
+
+gboolean
+gst_vaapi_decoder_ensure_context(
+ GstVaapiDecoder *decoder,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint,
+ guint width,
+ guint height,
+ guint surface_num
+)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ gboolean ret = TRUE;
+
+ gst_vaapi_decoder_set_picture_size(decoder, width, height);
+
+ if (priv->context) {
+ ret = gst_vaapi_context_reset(priv->context,
+ profile, entrypoint,
+ width, height,
+ surface_num);
+ goto end;
+ }
+
+ priv->context = gst_vaapi_context_new(
+ priv->display,
+ profile,
+ entrypoint,
+ width,
+ height,
+ surface_num
+ );
+ if (!priv->context)
+ return FALSE;
+end:
+ priv->va_context = gst_vaapi_context_get_id(priv->context);
+ return ret;
+}
+
+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,
+ GstVaapiSurfaceProxy *proxy
+)
+{
+ return push_surface(decoder, proxy);
+}
+
+static gboolean
+gst_vaapi_decoder_context_increase_surfaces(
+ GstVaapiDecoder *decoder,
+ guint increment
+)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ guint profile, entrypoint;
+ guint width, height;
+ guint surface_num;
+ gboolean ret = TRUE;
+
+ if (!increment)
+ return TRUE;
+
+ if (!priv->context ||
+ (gst_vaapi_context_get_surface_left_capability(priv->context) < increment))
+ return FALSE;
+ g_object_get(G_OBJECT(priv->context),
+ "profile", &profile,
+ "entrypoint", &entrypoint,
+ "width", &width,
+ "height", &height,
+ "surface_num", &surface_num,
+ NULL);
+ surface_num += increment;
+ ret = gst_vaapi_context_reset(priv->context,
+ (GstVaapiProfile)profile,
+ (GstVaapiEntrypoint)entrypoint,
+ width,
+ height,
+ surface_num);
+ priv->va_context = gst_vaapi_context_get_id(priv->context);
+ return ret;
+}
+
+GstVaapiDecoderStatus
+gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder)
+{
+ GstVaapiDecoderPrivate * const priv = decoder->priv;
+ guint increment;
+
+ if (!priv->context || gst_vaapi_context_get_surface_count(priv->context) > 0)
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+
+ increment = gst_vaapi_context_get_surface_left_capability(priv->context);
+ if (increment < 1) {
+ GST_DEBUG("decoder context surface pool is out of capability");
+ return GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE;
+ }
+ if (increment > 2)
+ increment = 2;
+
+ if (!gst_vaapi_decoder_context_increase_surfaces(decoder, increment)) {
+ GST_ERROR("increase decoder surface failed");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+}
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifndef GST_VAAPI_DECODER_H
+#define GST_VAAPI_DECODER_H
+
+#include <gst/gstbuffer.h>
+#include <gst/vaapi/gstvaapicontext.h>
+#include <gst/vaapi/gstvaapisurfaceproxy.h>
+
+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_END_OF_STREAM: End-Of-Stream.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED: No memory left.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED: Decoder initialization failure.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC: Unsupported codec.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA: Not enough input data to decode.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE: No surface left to hold the decoded picture.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_INVALID_SURFACE: Invalid surface.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER: Invalid or unsupported bitstream data.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE: Unsupported codec profile.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT: Unsupported chroma format.
+ * @GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN: Unknown error.
+ *
+ * Decoder status for gst_vaapi_decoder_get_surface().
+ */
+enum _GstVaapiDecoderStatus {
+ 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_UNKNOWN = -1
+};
+
+/**
+ * GstVaapiDecoder:
+ *
+ * A VA decoder base instance.
+ */
+struct _GstVaapiDecoder {
+ /*< private >*/
+ GObject parent_instance;
+
+ GstVaapiDecoderPrivate *priv;
+};
+
+/**
+ * GstVaapiDecoderClass:
+ *
+ * A VA decoder base class.
+ */
+struct _GstVaapiDecoderClass {
+ /*< private >*/
+ GObjectClass parent_class;
+
+ GstVaapiDecoderStatus (*decode)(GstVaapiDecoder *decoder, GstBuffer *buffer);
+ void (*clear_buffer)(GstVaapiDecoder *decoder);
+};
+
+GType
+gst_vaapi_decoder_get_type(void) G_GNUC_CONST;
+
+GstCaps *
+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
+);
+
+void
+gst_vaapi_decoder_clear_buffer(GstVaapiDecoder *decoder);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_H */
--- /dev/null
+/*
+ * 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->poc < dpb->pictures[lowest_pts_index]->poc)
+ lowest_pts_index = i;
+ }
+ return lowest_pts_index;
+}
+
+static void
+dpb_remove_index(GstVaapiDpb *dpb, guint index)
+{
+ GstVaapiPicture ** const pictures = dpb->pictures;
+ guint num_pictures = --dpb->num_pictures;
+
+ if (index != num_pictures)
+ gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
+ gst_vaapi_picture_replace(&pictures[num_pictures], NULL);
+}
+
+static inline gboolean
+dpb_output(GstVaapiDpb *dpb, GstVaapiPicture *picture)
+{
+ return gst_vaapi_picture_output(picture);
+}
+
+static gboolean
+dpb_bump(GstVaapiDpb *dpb)
+{
+ gint index;
+ gboolean success;
+
+ index = dpb_get_oldest(dpb, FALSE);
+ if (index < 0)
+ return FALSE;
+
+ success = dpb_output(dpb, dpb->pictures[index]);
+ if (!GST_VAAPI_PICTURE_IS_REFERENCE(dpb->pictures[index]))
+ dpb_remove_index(dpb, index);
+ return success;
+}
+
+static void
+dpb_clear(GstVaapiDpb *dpb)
+{
+ guint i;
+
+ for (i = 0; i < dpb->num_pictures; i++)
+ gst_vaapi_picture_replace(&dpb->pictures[i], NULL);
+ dpb->num_pictures = 0;
+}
+
+/* ------------------------------------------------------------------------- */
+/* --- 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]->poc < picture->poc)
+ break;
+ }
+ if (i == dpb->num_pictures)
+ return dpb_output(dpb, picture);
+ if (!dpb_bump(dpb))
+ return FALSE;
+ }
+ }
+ gst_vaapi_picture_replace(&dpb->pictures[dpb->num_pictures++], picture);
+ return TRUE;
+}
+
+static void
+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);
+}
+
+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 --- */
+/* ------------------------------------------------------------------------- */
+
+/* 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
+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 == 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)) {
+ 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, MAX_MPEG2_REFERENCES);
+}
+
+void
+gst_vaapi_dpb_mpeg2_get_references(
+ GstVaapiDpb *dpb,
+ GstVaapiPicture *picture,
+ GstVaapiPicture **prev_picture_ptr,
+ GstVaapiPicture **next_picture_ptr
+)
+{
+ GstVaapiPicture *ref_picture, *ref_pictures[MAX_MPEG2_REFERENCES];
+ GstVaapiPicture **picture_ptr;
+ 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->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];
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidecoder_objects.h>
+
+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);
+};
+
+G_GNUC_INTERNAL
+GType
+gst_vaapi_dpb_get_type(void) G_GNUC_CONST;
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_dpb_flush(GstVaapiDpb *dpb);
+
+G_GNUC_INTERNAL
+gboolean
+gst_vaapi_dpb_add(GstVaapiDpb *dpb, GstVaapiPicture *picture);
+
+G_GNUC_INTERNAL
+guint
+gst_vaapi_dpb_size(GstVaapiDpb *dpb);
+
+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;
+};
+
+G_GNUC_INTERNAL
+GType
+gst_vaapi_dpb_mpeg2_get_type(void) G_GNUC_CONST;
+
+G_GNUC_INTERNAL
+GstVaapiDpb *
+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
+);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_DPB */
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <string.h>
+#include <stdlib.h>
+#include <gst/base/gstadapter.h>
+#include <gst/codecparsers/gsth264parser.h>
+#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;
+ guint output_flag : 1;
+ guint output_needed : 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;
+ picture->output_needed = 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 {
+ GstAdapter *adapter;
+ GstBuffer *sub_buffer;
+ GstH264NalParser *parser;
+ GstH264SPS *sps;
+ GstH264SPS last_sps;
+ GstH264PPS *pps;
+ GstH264PPS last_pps;
+ GstVaapiPictureH264 *current_picture;
+ GstVaapiPictureH264 *dpb[16];
+ guint dpb_count;
+ guint dpb_size;
+ GstVaapiProfile profile;
+ 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 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;
+ guint is_avc : 1;
+ guint has_context : 1;
+};
+
+static gboolean
+decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
+
+static void
+clear_references(
+ GstVaapiDecoderH264 *decoder,
+ GstVaapiPictureH264 **pictures,
+ 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;
+ if (max_dec_frame_buffering > 8)
+ max_dec_frame_buffering = 8;
+
+ /* 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)
+{
+ 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 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_clear_buffer(GstVaapiDecoder *base)
+{
+ GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base);
+ 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 );
+
+ if (priv->sub_buffer) {
+ gst_buffer_unref(priv->sub_buffer);
+ priv->sub_buffer = NULL;
+ }
+
+ if (priv->adapter) {
+ gst_adapter_clear(priv->adapter);
+ }
+}
+
+static void
+gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
+{
+ GstVaapiDecoderH264Private * const priv = decoder->priv;
+
+ gst_vaapi_decoder_h264_clear_buffer(GST_VAAPI_DECODER_CAST(decoder));
+
+ if (priv->parser) {
+ gst_h264_nal_parser_free(priv->parser);
+ priv->parser = NULL;
+ }
+
+ if (priv->adapter) {
+ g_object_unref(priv->adapter);
+ priv->adapter = NULL;
+ }
+}
+
+static gboolean
+gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
+{
+ 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;
+ 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 inline guint
+min_surfaces_count(guint dbp_size)
+{
+ guint count = dbp_size + 4;
+
+ if (count < GST_DECODER_DEFAULT_SURFACES_COUNT)
+ count = GST_DECODER_DEFAULT_SURFACES_COUNT;
+ return count;
+}
+
+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->has_context || 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->has_context ||
+ 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->has_context ||
+ 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) {
+ /* Reset DPB first*/
+ dpb_reset(decoder, sps);
+
+ success = gst_vaapi_decoder_ensure_context(
+ GST_VAAPI_DECODER(decoder),
+ priv->profile,
+ entrypoint,
+ priv->width,
+ priv->height,
+ min_surfaces_count(priv->dpb_size)
+ );
+ if (!success)
+ return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+ priv->has_context = TRUE;
+
+ }
+ 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;
+ 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 * 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);
+
+ return ensure_context(decoder, sps);
+}
+
+static GstVaapiDecoderStatus
+decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
+{
+ GstVaapiDecoderH264Private * const priv = decoder->priv;
+ GstH264PPS * const pps = &priv->last_pps;
+ GstH264ParserResult result;
+
+ 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)
+ 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) {
+ GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType);
+ 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;
+ dpb_flush(decoder);
+ 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 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);
+
+ 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);
+ *picture_count = num_pictures;
+ return TRUE;
+}
+
+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;
+
+ // (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 = 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++) {
+ 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];
+ }
+ }
+ }
+
+#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->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);
+
+ /* Reset decoder state for IDR pictures */
+ if (picture->is_idr) {
+ GST_DEBUG("<IDR>");
+ 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;
+}
+
+/* 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,
+ 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;
+}
+
+/* 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, picture, 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)
+{
+ 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)
+{
+ /* 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)
+{
+ 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;
+ if (!exit_picture(decoder, picture))
+ return FALSE;
+ if (!dpb_add(decoder, picture))
+ return FALSE;
+ 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)
+{
+ 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_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
+{
+ GstVaapiDecoderH264Private * const priv = decoder->priv;
+ GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
+ VASliceParameterBufferH264 * const slice_param = slice->base.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;
+
+ 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,
+ 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 = 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;
+ 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;
+}
+
+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->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;
+ }
+ 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);
+
+ 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);
+ ofs = 0;
+ do {
+ 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) {
+ priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs);
+ 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:
+ /* 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_DEBUG("unsupported NAL unit type %d", nalu.type);
+ 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;
+}
+
+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;
+ }
+
+ priv->is_avc = TRUE;
+ 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);
+
+ 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;
+
+ 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_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;
+ decoder_class->clear_buffer = gst_vaapi_decoder_h264_clear_buffer;
+}
+
+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 = &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->short_ref_count = 0;
+ priv->long_ref_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;
+ 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;
+ 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;
+ priv->is_avc = FALSE;
+ priv->has_context = 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidecoder.h>
+
+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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_H264_H */
--- /dev/null
+/*
+ * 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 <string.h>
+#include <gst/codecparsers/gstjpegparser.h>
+#include "gstvaapicompat.h"
+#include "gstvaapidecoder_jpeg.h"
+#include "gstvaapidecoder_objects.h"
+#include "gstvaapidecoder_priv.h"
+#include "gstvaapidisplay_priv.h"
+#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;
+ GstJpegFrameHdr frame_hdr;
+ GstJpegHuffmanTables huf_tables;
+ GstJpegQuantTables quant_tables;
+ gboolean has_huf_table;
+ gboolean has_quant_table;
+ guint mcu_restart;
+ guint is_opened : 1;
+ guint profile_changed : 1;
+ guint is_constructed : 1;
+};
+
+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)
+{
+ 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;
+}
+
+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,
+ GST_DECODER_DEFAULT_SURFACES_COUNT
+ );
+ if (!reset_context)
+ return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+ }
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+}
+
+static gboolean
+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;
+}
+
+static gboolean
+fill_picture(
+ GstVaapiDecoderJpeg *decoder,
+ GstVaapiPicture *picture,
+ GstJpegFrameHdr *jpeg_frame_hdr
+)
+{
+ VAPictureParameterBufferJPEGBaseline *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->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_frame_hdr->components[i].identifier;
+ pic_param->components[i].h_sampling_factor =
+ jpeg_frame_hdr->components[i].horizontal_factor;
+ pic_param->components[i].v_sampling_factor =
+ jpeg_frame_hdr->components[i].vertical_factor;
+ pic_param->components[i].quantiser_table_selector =
+ jpeg_frame_hdr->components[i].quant_table_selector;
+ }
+ return TRUE;
+}
+
+static gboolean
+fill_quantization_table(
+ GstVaapiDecoderJpeg *decoder,
+ GstVaapiPicture *picture
+)
+{
+ GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
+ 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(JPEGBaseline, decoder);
+ g_assert(picture->iq_matrix);
+ 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;
+
+ 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;
+}
+
+static gboolean
+fill_huffman_table(
+ GstVaapiDecoderJpeg *decoder,
+ GstVaapiPicture *picture
+)
+{
+ GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
+ GstJpegHuffmanTables * const huf_tables = &priv->huf_tables;
+ 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(JPEGBaseline, decoder);
+ g_assert(picture->huf_table);
+ huffman_table = picture->huf_table->param;
+
+ num_tables = MIN(G_N_ELEMENTS(huffman_table->huffman_table),
+ GST_JPEG_MAX_SCAN_COMPONENTS);
+
+ for (i = 0; i < num_tables; i++) {
+ huffman_table->load_huffman_table[i] =
+ huf_tables->dc_tables[i].valid && huf_tables->ac_tables[i].valid;
+ if (!huffman_table->load_huffman_table[i])
+ continue;
+
+ memcpy(huffman_table->huffman_table[i].num_dc_codes,
+ huf_tables->dc_tables[i].huf_bits,
+ sizeof(huffman_table->huffman_table[i].num_dc_codes));
+ memcpy(huffman_table->huffman_table[i].dc_values,
+ huf_tables->dc_tables[i].huf_values,
+ sizeof(huffman_table->huffman_table[i].dc_values));
+ memcpy(huffman_table->huffman_table[i].num_ac_codes,
+ huf_tables->ac_tables[i].huf_bits,
+ sizeof(huffman_table->huffman_table[i].num_ac_codes));
+ memcpy(huffman_table->huffman_table[i].ac_values,
+ huf_tables->ac_tables[i].huf_values,
+ sizeof(huffman_table->huffman_table[i].ac_values));
+ memset(huffman_table->huffman_table[i].pad,
+ 0,
+ sizeof(huffman_table->huffman_table[i].pad));
+ }
+ return TRUE;
+}
+
+static guint
+get_max_horizontal_samples(GstJpegFrameHdr *frame_hdr)
+{
+ guint i, max_factor = 0;
+
+ 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(GstJpegFrameHdr *frame_hdr)
+{
+ guint i, max_factor = 0;
+
+ 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 GstVaapiDecoderStatus
+decode_picture(
+ GstVaapiDecoderJpeg *decoder,
+ guint8 profile,
+ guchar *buf,
+ guint buf_size,
+ GstClockTime pts
+)
+{
+ GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
+ GstJpegFrameHdr * const frame_hdr = &priv->frame_hdr;
+ GstVaapiPicture *picture;
+ GstVaapiDecoderStatus status;
+
+ switch (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;
+ }
+
+ 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 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 = pts;
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+}
+
+static GstVaapiDecoderStatus
+decode_huffman_table(
+ GstVaapiDecoderJpeg *decoder,
+ guchar *buf,
+ guint buf_size
+)
+{
+ 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");
+ return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
+ }
+ 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;
+
+ if (!gst_jpeg_parse_quant_table(&priv->quant_tables, buf, buf_size, 0)) {
+ GST_DEBUG("failed to parse quantization table");
+ return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
+ }
+ 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;
+
+ if (!gst_jpeg_parse_restart_interval(&priv->mcu_restart, buf, buf_size, 0)) {
+ GST_DEBUG("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,
+ guchar *scan_header,
+ guint scan_header_size,
+ guchar *scan_data,
+ guint scan_data_size)
+{
+ GstVaapiDecoderJpegPrivate * const priv = decoder->priv;
+ GstVaapiPicture *picture = priv->current_picture;
+ VASliceParameterBufferJPEGBaseline *slice_param;
+ GstVaapiSlice *gst_slice;
+ 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;
+ }
+
+ memset(&scan_hdr, 0, sizeof(scan_hdr));
+ if (!gst_jpeg_parse_scan_hdr(&scan_hdr, scan_header, scan_header_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_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_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_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);
+ }
+ } 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)
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+ return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
+}
+
+static GstVaapiDecoderStatus
+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, 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) {
+ GST_DEBUG("buffer to short for parsing");
+ return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
+ }
+ ofs += 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_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,
+ 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;
+ }
+
+ /* 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;
+ }
+end:
+ return status;
+}
+
+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->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));
+}
+
+/**
+ * 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidecoder.h>
+
+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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_JPEG_H */
+
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <string.h>
+#include <gst/base/gstbitreader.h>
+#include <gst/codecparsers/gstmpegvideoparser.h>
+#include "gstvaapidecoder_mpeg2.h"
+#include "gstvaapidecoder_objects.h"
+#include "gstvaapidecoder_dpb.h"
+#include "gstvaapidecoder_priv.h"
+#include "gstvaapidisplay_priv.h"
+#include "gstvaapiobject_priv.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
+
+#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
+
+/* 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 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)
+{
+ 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 + 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;
+}
+
+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;
+ GstVaapiProfile hw_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;
+ GstVaapiDpb *dpb;
+ GstAdapter *adapter;
+ 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;
+ guint progressive_sequence : 1;
+ guint closed_gop : 1;
+ 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_clear_buffer(GstVaapiDecoder *base)
+{
+ GstVaapiDecoderMpeg2* const decoder = GST_VAAPI_DECODER_MPEG2(base);
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+
+ priv->closed_gop = FALSE;
+ priv->broken_link = FALSE;
+
+ gst_vaapi_picture_replace(&priv->current_picture, NULL);
+
+ pts_init(&priv->tsg);
+ pts_set_framerate(&priv->tsg, priv->fps_n, priv->fps_d);
+
+ if (priv->dpb) {
+ gst_vaapi_dpb_flush(priv->dpb);
+ }
+
+ if (priv->adapter) {
+ gst_adapter_clear(priv->adapter);
+ }
+}
+
+static void
+gst_vaapi_decoder_mpeg2_close(GstVaapiDecoderMpeg2 *decoder)
+{
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+
+ gst_vaapi_picture_replace(&priv->current_picture, NULL);
+
+ if (priv->dpb) {
+ 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)
+{
+ 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;
+
+ pts_init(&priv->tsg);
+ 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 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 = "<unknown>"; 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;
+ 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;
+
+ 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 (reset_context) {
+ reset_context = gst_vaapi_decoder_ensure_context(
+ GST_VAAPI_DECODER(decoder),
+ priv->hw_profile,
+ entrypoint,
+ priv->width,
+ priv->height,
+ GST_DECODER_DEFAULT_SURFACES_COUNT
+ );
+ 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_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 = 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)
+ 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 gboolean
+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);
+ }
+ }
+ return TRUE;
+}
+
+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, 4)) {
+ GST_ERROR("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;
+ 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->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, 4)) {
+ GST_ERROR("failed to parse sequence-extension");
+ return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
+ }
+ 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);
+ 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) {
+ 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:
+ 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;
+ }
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+}
+
+static GstVaapiDecoderStatus
+decode_sequence_end(GstVaapiDecoderMpeg2 *decoder)
+{
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+
+ if (priv->current_picture && !decode_current_picture(decoder))
+ return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+
+ gst_vaapi_dpb_flush(priv->dpb);
+ 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, 4)) {
+ GST_ERROR("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, 4)) {
+ GST_ERROR("failed to parse GOP");
+ return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
+ }
+
+ 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_adapter_prev_timestamp(priv->adapter, NULL);
+ pts_sync(&priv->tsg, pts);
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+}
+
+static GstVaapiDecoderStatus
+decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
+{
+ 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_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;
+ }
+
+ 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) {
+ 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 */
+ 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;
+}
+
+static GstVaapiDecoderStatus
+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, 4)) {
+ GST_ERROR("failed to parse picture-extension");
+ return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
+ }
+ 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)) {
+ GST_WARNING("invalid picture_structure %d, replacing with \"frame\"",
+ pic_ext->picture_structure);
+ 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;
+ break;
+ case GST_MPEG_VIDEO_PICTURE_STRUCTURE_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;
+ 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;
+}
+
+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;
+ 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);
+
+#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);
+
+ 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 (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;
+ }
+ 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;
+ 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;
+
+ 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;
+
+ slice = GST_VAAPI_SLICE_NEW(MPEG2, decoder, buf, buf_size);
+ if (!slice) {
+ GST_ERROR("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);
+ 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;
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+
+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_buffer(GstVaapiDecoderMpeg2 *decoder, GstBuffer *buffer)
+{
+ GstVaapiDecoderMpeg2Private * const priv = decoder->priv;
+ GstVaapiDecoderStatus status;
+ guchar *buf;
+ guint buf_size, size;
+ guint32 start_code;
+ guint8 type;
+ gint ofs;
+
+ 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;
+
+ status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder));
+ if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
+ break;
+
+ 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;
+
+ 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;
+ }
+
+ buf = GST_BUFFER_DATA(buffer);
+ buf_size = GST_BUFFER_SIZE(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:
+ 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)
+ break;
+ status = decode_picture_ext(decoder, buf, buf_size);
+ break;
+ default:
+ // Ignore unknown extensions
+ GST_WARNING("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, 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)
+ 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);
+ 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;
+ decoder_class->clear_buffer = gst_vaapi_decoder_mpeg2_clear_buffer;
+}
+
+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->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;
+ 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;
+ priv->progressive_sequence = FALSE;
+ priv->closed_gop = FALSE;
+ priv->broken_link = 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;
+
+ 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidecoder.h>
+#include <gst/base/gstadapter.h>
+
+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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_MPEG2_H */
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <string.h>
+#include <stdlib.h>
+#include <gst/base/gstbitreader.h>
+#include <gst/codecparsers/gstmpeg4parser.h>
+#include "gstvaapidecoder_mpeg4.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(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;
+ GstAdapter *adapter;
+ GstBuffer *sub_buffer;
+ 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_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_clear_buffer(GstVaapiDecoder *base)
+{
+ GstVaapiDecoderMpeg4* const decoder = GST_VAAPI_DECODER_MPEG4(base);
+ GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
+
+ 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->prev_t_ref = -1;
+ priv->calculate_pts_diff = TRUE;
+ priv->is_first_field = 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;
+
+ 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);
+ }
+}
+
+static void
+gst_vaapi_decoder_mpeg4_close(GstVaapiDecoderMpeg4 *decoder)
+{
+ GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
+
+ gst_vaapi_decoder_mpeg4_clear_buffer(GST_VAAPI_DECODER_CAST(decoder));
+
+ if (priv->adapter) {
+ g_object_unref(priv->adapter);
+ priv->adapter = 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->adapter = gst_adapter_new();
+ if (!priv->adapter)
+ 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,
+ GST_DECODER_DEFAULT_SURFACES_COUNT
+ );
+ 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_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)
+{
+ 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
+ * (commit buffer to driver for decoding)
+ */
+static GstVaapiDecoderStatus
+decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
+{
+ 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);
+ }
+ 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:
+ 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", profile);
+ return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
+ }
+ if (priv->profile != profile) {
+ priv->profile = profile;
+ priv->profile_changed = TRUE;
+ }
+ priv->seq_pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
+ 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 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;
+ }
+
+ 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);
+
+ 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;
+
+ 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)
+{
+ 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);
+
+ }
+ 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) {
+ 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_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) {
+ if (priv->calculate_pts_diff) {
+ priv->prev_t_ref = priv->svh_hdr.temporal_reference;
+ priv->sync_time = gst_adapter_prev_timestamp(priv->adapter, NULL);
+ if (priv->sync_time == GST_CLOCK_TIME_NONE)
+ priv->sync_time = 0;
+ priv->calculate_pts_diff = FALSE;
+ }
+
+ pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
+ if (pts == GST_CLOCK_TIME_NONE) { /* Buffer without timestamp set*/
+ 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 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)
+{
+ return picture->type - GST_VAAPI_PICTURE_TYPE_I;
+}
+
+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 && 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];
+ }
+ 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->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
+ 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;
+ }
+
+ 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_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;
+ }
+ }
+ return GST_VAAPI_DECODER_STATUS_SUCCESS;
+}
+
+static GstVaapiDecoderStatus
+decode_packet(GstVaapiDecoderMpeg4 *decoder, GstMpeg4Packet packet)
+{
+ GstVaapiDecoderMpeg4Private * const priv = decoder->priv;
+ GstMpeg4Packet *tos = &packet;
+ GstVaapiDecoderStatus status;
+
+ 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);
+ }
+ 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);
+ 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
+ */
+ 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);
+ if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
+ return status;
+ }
+ 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 = 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;
+
+ 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;
+ if (gst_adapter_available(priv->adapter) >= consumed_size)
+ gst_adapter_flush(priv->adapter, 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 ||
+ 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) >= consumed_size)
+ gst_adapter_flush(priv->adapter, 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 ||
+ 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;
+ }
+ return status;
+}
+
+static GstVaapiDecoderStatus
+decode_codec_data(GstVaapiDecoderMpeg4 *decoder, GstBuffer *buffer)
+{
+ 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;
+ decoder_class->clear_buffer = gst_vaapi_decoder_mpeg4_clear_buffer;
+}
+
+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->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;
+ 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;
+}
+
+/**
+ * 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;
+
+ 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidecoder.h>
+#include <gst/base/gstadapter.h>
+
+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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_MPEG4_H */
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <string.h>
+#include <gst/vaapi/gstvaapicontext.h>
+#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)
+
+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)
+{
+ 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->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;
+ }
+
+ if (picture->proxy) {
+ 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;
+
+ vaapi_destroy_buffer(GET_VA_DISPLAY(picture), &picture->param_id);
+ picture->param = NULL;
+}
+
+static gboolean
+gst_vaapi_picture_create(
+ GstVaapiPicture *picture,
+ const GstVaapiCodecObjectConstructorArgs *args
+)
+{
+ gboolean success;
+
+ 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->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(
+ 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);
+ }
+ }
+ 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;
+ GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_FF);
+ }
+ picture->surface_id = gst_vaapi_surface_get_id(picture->surface);
+
+ 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;
+ 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,
+ 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);
+}
+
+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)
+{
+ 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];
+
+ 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;
+}
+
+gboolean
+gst_vaapi_picture_output(GstVaapiPicture *picture)
+{
+ GstVaapiSurfaceProxy *proxy;
+
+ g_return_val_if_fail(GST_VAAPI_IS_PICTURE(picture), FALSE);
+
+ if (!picture->proxy)
+ return FALSE;
+
+ 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);
+ return TRUE;
+}
+
+/* ------------------------------------------------------------------------- */
+/* --- 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;
+ gboolean success;
+
+ 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;
+
+ 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapicodec_objects.h>
+
+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_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
+ *
+ * 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_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),
+};
+
+#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_IS_SKIPPED(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED)
+
+#define GST_VAAPI_PICTURE_IS_REFERENCE(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE)
+
+#define GST_VAAPI_PICTURE_IS_OUTPUT(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_OUTPUT)
+
+#define GST_VAAPI_PICTURE_IS_INTERLACED(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED)
+
+#define GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_FF)
+
+#define GST_VAAPI_PICTURE_IS_TFF(picture) \
+ GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_TFF)
+
+#define GST_VAAPI_PICTURE_IS_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:
+ *
+ * A #GstVaapiCodecObject holding a picture parameter.
+ */
+struct _GstVaapiPicture {
+ /*< private >*/
+ GstVaapiCodecObject parent_instance;
+ 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;
+};
+
+/**
+ * GstVaapiPictureClass:
+ *
+ * The #GstVaapiPicture base class.
+ */
+struct _GstVaapiPictureClass {
+ /*< private >*/
+ GstVaapiCodecObjectClass parent_class;
+};
+
+G_GNUC_INTERNAL
+GType
+gst_vaapi_picture_get_type(void) G_GNUC_CONST;
+
+G_GNUC_INTERNAL
+GstVaapiPicture *
+gst_vaapi_picture_new(
+ GstVaapiDecoder *decoder,
+ gconstpointer param,
+ guint param_size
+);
+
+G_GNUC_INTERNAL
+GstVaapiPicture *
+gst_vaapi_picture_new_field(GstVaapiPicture *picture);
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_picture_add_slice(GstVaapiPicture *picture, GstVaapiSlice *slice);
+
+G_GNUC_INTERNAL
+gboolean
+gst_vaapi_picture_decode(GstVaapiPicture *picture);
+
+G_GNUC_INTERNAL
+gboolean
+gst_vaapi_picture_output(GstVaapiPicture *picture);
+
+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;
+};
+
+G_GNUC_INTERNAL
+GType
+gst_vaapi_slice_get_type(void) G_GNUC_CONST;
+
+G_GNUC_INTERNAL
+GstVaapiSlice *
+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_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 */
--- /dev/null
+/*
+ * gstvaapidecoder_priv.h - VA decoder abstraction (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_DECODER_PRIV_H
+#define GST_VAAPI_DECODER_PRIV_H
+
+#include <glib.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+#include <gst/vaapi/gstvaapicontext.h>
+
+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
+
+/**
+ * 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
+
+/**
+ * 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)
+
+#define GST_BUFFER_IS_EOS(buffer) \
+ GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_EOS)
+
+#define GST_VAAPI_DECODER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_VAAPI_TYPE_DECODER, \
+ GstVaapiDecoderPrivate))
+
+/* Number of scratch surfaces beyond those used as reference */
+/* 5 = 2 + 4; 2 for reference, 4 for scratch*/
+#define GST_DECODER_DEFAULT_SURFACES_COUNT 6
+
+struct _GstVaapiDecoderPrivate {
+ GstVaapiDisplay *display;
+ 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;
+ GQueue *buffers;
+ GQueue *surfaces;
+ guint is_interlaced : 1;
+};
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_decoder_set_picture_size(
+ GstVaapiDecoder *decoder,
+ guint width,
+ guint height
+);
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_decoder_set_framerate(
+ GstVaapiDecoder *decoder,
+ guint fps_n,
+ guint fps_d
+);
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_decoder_set_pixel_aspect_ratio(
+ GstVaapiDecoder *decoder,
+ guint par_n,
+ guint par_d
+);
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_decoder_set_interlaced(GstVaapiDecoder *decoder, gboolean interlaced);
+
+G_GNUC_INTERNAL
+gboolean
+gst_vaapi_decoder_ensure_context(
+ GstVaapiDecoder *decoder,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint,
+ guint width,
+ guint height,
+ guint surface_num
+);
+
+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(
+ GstVaapiDecoder *decoder,
+ GstVaapiSurfaceProxy *proxy
+);
+
+G_GNUC_INTERNAL
+GstVaapiDecoderStatus
+gst_vaapi_decoder_check_status(GstVaapiDecoder *decoder);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_PRIV_H */
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <string.h>
+#include <gst/codecparsers/gstvc1parser.h>
+#include "gstvaapidecoder_vc1.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(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;
+ GstVC1BitPlanes *bitplanes;
+ 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_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)
+{
+ GstVaapiDecoderVC1Private * 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->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)
+{
+ 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;
+ return TRUE;
+}
+
+static void
+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
+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,
+ GST_DECODER_DEFAULT_SURFACES_COUNT
+ );
+ 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)
+{
+ 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);
+ }
+ gst_vaapi_picture_replace(&priv->current_picture, NULL);
+ }
+ return status;
+}
+
+static GstVaapiDecoderStatus
+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;
+
+ 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);
+ }
+
+ 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;
+ }
+
+ 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:
+ 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, 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;
+
+ result = gst_vc1_parse_entry_point_header(
+ rbdu->data + rbdu->offset,
+ rbdu->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;
+}
+
+/* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
+static guint
+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 */
+}
+
+/* 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 */
+}
+
+/* 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)
+{
+ 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 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)
+{
+ 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->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_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 = 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)
+{
+ 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->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 = 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;
+ }
+
+ 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_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;
+}
+
+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;
+ GstVaapiSlice *slice;
+ GstVaapiDecoderStatus status;
+ VASliceParameterBufferVC1 *slice_param;
+ 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_PICTURE_NEW(VC1, decoder);
+ if (!priv->current_picture) {
+ GST_DEBUG("failed to allocate picture");
+ return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
+ }
+ 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(
+ rbdu->data + rbdu->offset,
+ rbdu->size,
+ frame_hdr,
+ seq_hdr,
+ priv->bitplanes
+ );
+ 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;
+ 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;
+ 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 presentation time */
+ pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
+ picture->pts = 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);
+ }
+
+ if (!fill_picture(decoder, picture))
+ return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
+
+ slice = GST_VAAPI_SLICE_NEW(
+ VC1,
+ decoder,
+ 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;
+ }
+ 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;
+
+ /* 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 ebdu;
+ GstBuffer *codec_data;
+ 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);
+
+ 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) {
+ 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;
+ }
+
+ 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;
+}
+
+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(
+ 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);
+
+ 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;
+
+ 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_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->adapter = 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;
+ 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;
+
+ 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidecoder.h>
+#include <gst/base/gstadapter.h>
+
+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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DECODER_VC1_H */
--- /dev/null
+/*
+ * gstvaapidisplay.c - VA display 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:gstvaapidisplay
+ * @short_description: VA display abstraction
+ */
+
+#include "sysdeps.h"
+#include <string.h>
+#include "gstvaapiutils.h"
+#include "gstvaapivalue.h"
+#include "gstvaapidisplay.h"
+#include "gstvaapidisplay_priv.h"
+#include "gstvaapiworkarounds.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+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;
+};
+
+typedef struct _GstVaapiProperty GstVaapiProperty;
+struct _GstVaapiProperty {
+ const gchar *name;
+ VADisplayAttribute attribute;
+ gint old_value;
+};
+
+#define DEFAULT_RENDER_MODE GST_VAAPI_RENDER_MODE_TEXTURE
+#define DEFAULT_ROTATION GST_VAAPI_ROTATION_0
+
+enum {
+ PROP_0,
+
+ PROP_DISPLAY,
+ PROP_DISPLAY_TYPE,
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_RENDER_MODE,
+ PROP_ROTATION,
+ PROP_HUE,
+ PROP_SATURATION,
+ PROP_BRIGHTNESS,
+ PROP_CONTRAST,
+
+ N_PROPERTIES
+};
+
+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 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)
+{
+ 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();
+}
+
+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;
+}
+
+/* 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" },
+#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" },
+#endif
+#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 },
+ };
+
+ 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)
+{
+ g_array_append_val(formats, format);
+}
+
+/* Append VAImageFormats to formats array */
+static void
+append_formats(GArray *formats, const VAImageFormat *va_formats, guint n)
+{
+ GstVaapiImageFormat format;
+ gboolean has_YV12 = FALSE;
+ gboolean has_I420 = FALSE;
+ guint i;
+
+ 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;
+ }
+
+ switch (format) {
+ case GST_VAAPI_IMAGE_YV12:
+ has_YV12 = TRUE;
+ break;
+ case GST_VAAPI_IMAGE_I420:
+ has_I420 = TRUE;
+ break;
+ default:
+ break;
+ }
+ 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)
+ 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 */
+static gint
+compare_yuv_formats(gconstpointer a, gconstpointer b)
+{
+ 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);
+
+ 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));
+}
+
+/* Sort subpicture formats. Prefer RGB formats first */
+static gint
+compare_rgb_formats(gconstpointer a, gconstpointer b)
+{
+ 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);
+
+ 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));
+}
+
+/* Check if configs array contains profile at entrypoint */
+static inline gboolean
+find_config(
+ GArray *configs,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint
+)
+{
+ 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;
+ }
+ 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)
+{
+ GstVaapiConfig *config;
+ GstCaps *out_caps, *caps;
+ guint i;
+
+ if (!configs)
+ 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)
+ gst_caps_merge(out_caps, caps);
+ }
+ return out_caps;
+}
+
+/* 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_format_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;
+}
+
+/* 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 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)
+{
+ GstVaapiDisplayPrivate * const priv = display->priv;
+ 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 */
+ };
+
+ /* 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, 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++) {
+ 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];
+}
+
+static void
+gst_vaapi_display_destroy(GstVaapiDisplay *display)
+{
+ GstVaapiDisplayPrivate * const priv = display->priv;
+
+ 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) {
+ 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;
+ }
+
+ if (priv->display) {
+ if (!priv->parent)
+ 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);
+ }
+
+ g_clear_object(&priv->parent);
+
+ if (g_display_cache) {
+ gst_vaapi_display_cache_remove(get_display_cache(), display);
+ free_display_cache();
+ }
+}
+
+static gboolean
+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;
+ 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;
+
+ 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 || !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 (!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) {
+ g_clear_object(&priv->parent);
+ priv->parent = g_object_ref(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);
+
+ /* 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(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 */
+ 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));
+
+ 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);
+
+ if (!cached_info) {
+ if (!gst_vaapi_display_cache_add(cache, &info))
+ goto end;
+ }
+
+ has_errors = FALSE;
+end:
+ 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)
+{
+ 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)
+{
+ GstVaapiDisplayPrivate *priv = display->priv;
+
+ if (priv->parent)
+ priv = priv->parent->priv;
+ g_static_rec_mutex_unlock(&priv->mutex);
+}
+
+static void
+gst_vaapi_display_finalize(GObject *object)
+{
+ GstVaapiDisplay * const display = GST_VAAPI_DISPLAY(object);
+
+ gst_vaapi_display_destroy(display);
+
+ g_static_rec_mutex_free(&display->priv->mutex);
+
+ 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 * 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
+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;
+
+ 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);
+
+ /**
+ * 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: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);
+}
+
+static void
+gst_vaapi_display_init(GstVaapiDisplay *display)
+{
+ GstVaapiDisplayPrivate *priv = GST_VAAPI_DISPLAY_GET_PRIVATE(display);
+
+ 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;
+
+ g_static_rec_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)
+{
+ 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);
+}
+
+/**
+ * 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)
+{
+ GstVaapiDisplayClass *klass;
+
+ g_return_if_fail(GST_VAAPI_IS_DISPLAY(display));
+
+ klass = GST_VAAPI_DISPLAY_GET_CLASS(display);
+ if (klass->lock)
+ klass->lock(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)
+{
+ GstVaapiDisplayClass *klass;
+
+ g_return_if_fail(GST_VAAPI_IS_DISPLAY(display));
+
+ klass = GST_VAAPI_DISPLAY_GET_CLASS(display);
+ if (klass->unlock)
+ 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_flush:
+ * @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
+ *
+ * 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
+ *
+ * Returns the #VADisplay bound to @display.
+ *
+ * Return value: the #VADisplay
+ */
+VADisplay
+gst_vaapi_display_get_display(GstVaapiDisplay *display)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
+
+ 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: return location for the width, or %NULL
+ * @pheight: 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_get_pixel_aspect_ratio:
+ * @display: a #GstVaapiDisplay
+ * @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.
+ */
+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_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
+ * @entrypoint: a #GstVaaiEntrypoint
+ *
+ * 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,
+ GstVaapiEntrypoint entrypoint
+)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE);
+
+ return find_config(display->priv->decoders, profile, entrypoint);
+}
+
+/**
+ * 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
+ * @entrypoint: a #GstVaapiEntrypoint
+ *
+ * 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,
+ GstVaapiEntrypoint entrypoint
+)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), FALSE);
+
+ return find_config(display->priv->encoders, profile, entrypoint);
+}
+
+/**
+ * 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)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
+
+ return get_format_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,
+ GstVaapiImageFormat 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))
+ 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);
+}
+
+/**
+ * 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)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
+
+ return get_format_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,
+ GstVaapiImageFormat format
+)
+{
+ 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);
+}
+
+/**
+ * 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;
+}
+
+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 = DEFAULT_RENDER_MODE;
+ 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;
+
+ g_object_notify_by_pspec(G_OBJECT(display), g_properties[PROP_RENDER_MODE]);
+ 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), DEFAULT_ROTATION);
+
+ 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;
+
+ 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;
+}
--- /dev/null
+/*
+ * gstvaapidisplay.h - VA display 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_DISPLAY_H
+#define GST_VAAPI_DISPLAY_H
+
+#include <va/va.h>
+#include <gst/gst.h>
+#include <gst/vaapi/gstvaapitypes.h>
+#include <gst/vaapi/gstvaapiimageformat.h>
+#include <gst/vaapi/gstvaapiprofile.h>
+
+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, \
+ 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.
+ * @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 \
+ (gst_vaapi_display_type_get_type())
+
+GType
+gst_vaapi_display_type_get_type(void) G_GNUC_CONST;
+
+/**
+ * GstVaapiDisplayInfo:
+ *
+ * Generic class to retrieve VA display info
+ */
+struct _GstVaapiDisplayInfo {
+ GstVaapiDisplay *display;
+ GstVaapiDisplayType display_type;
+ gchar *display_name;
+ VADisplay va_display;
+ gpointer native_display;
+};
+
+/**
+ * GstVaapiDisplayProperties:
+ * @GST_VAAPI_DISPLAY_PROP_RENDER_MODE: rendering mode (#GstVaapiRenderMode).
+ * @GST_VAAPI_DISPLAY_PROP_ROTATION: rotation angle (#GstVaapiRotation).
+ * @GST_VAAPI_DISPLAY_PROP_HUE: hue (float: [-180 ; 180], default: 0).
+ * @GST_VAAPI_DISPLAY_PROP_SATURATION: saturation (float: [0 ; 2], default: 1).
+ * @GST_VAAPI_DISPLAY_PROP_BRIGHTNESS: brightness (float: [-1 ; 1], default: 0).
+ * @GST_VAAPI_DISPLAY_PROP_CONTRAST: contrast (float: [0 ; 2], default: 1).
+ */
+#define GST_VAAPI_DISPLAY_PROP_RENDER_MODE "render-mode"
+#define GST_VAAPI_DISPLAY_PROP_ROTATION "rotation"
+#define GST_VAAPI_DISPLAY_PROP_HUE "hue"
+#define GST_VAAPI_DISPLAY_PROP_SATURATION "saturation"
+#define GST_VAAPI_DISPLAY_PROP_BRIGHTNESS "brightness"
+#define GST_VAAPI_DISPLAY_PROP_CONTRAST "contrast"
+
+/**
+ * GstVaapiDisplay:
+ *
+ * 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);
+
+void
+gst_vaapi_display_lock(GstVaapiDisplay *display);
+
+void
+gst_vaapi_display_unlock(GstVaapiDisplay *display);
+
+void
+gst_vaapi_display_sync(GstVaapiDisplay *display);
+
+void
+gst_vaapi_display_flush(GstVaapiDisplay *display);
+
+GstVaapiDisplayType
+gst_vaapi_display_get_display_type(GstVaapiDisplay *display);
+
+VADisplay
+gst_vaapi_display_get_display(GstVaapiDisplay *display);
+
+guint
+gst_vaapi_display_get_width(GstVaapiDisplay *display);
+
+guint
+gst_vaapi_display_get_height(GstVaapiDisplay *display);
+
+void
+gst_vaapi_display_get_size(GstVaapiDisplay *display, guint *pwidth, guint *pheight);
+
+void
+gst_vaapi_display_get_pixel_aspect_ratio(
+ GstVaapiDisplay *display,
+ guint *par_n,
+ guint *par_d
+);
+
+GstCaps *
+gst_vaapi_display_get_decode_caps(GstVaapiDisplay *display);
+
+gboolean
+gst_vaapi_display_has_decoder(
+ GstVaapiDisplay *display,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint
+);
+
+GstCaps *
+gst_vaapi_display_get_encode_caps(GstVaapiDisplay *display);
+
+gboolean
+gst_vaapi_display_has_encoder(
+ GstVaapiDisplay *display,
+ GstVaapiProfile profile,
+ GstVaapiEntrypoint entrypoint
+);
+
+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,
+ GstVaapiImageFormat 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
+);
+
+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 */
--- /dev/null
+/*
+ * 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 <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <libudev.h>
+#include <xf86drm.h>
+#include <va/va_drm.h>
+#include "gstvaapiutils.h"
+#include "gstvaapidisplay_priv.h"
+#include "gstvaapidisplay_drm.h"
+#include "gstvaapidisplay_drm_priv.h"
+
+#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;
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidisplay.h>
+
+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 */
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidisplay_drm.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapidisplay_glx.c - VA/GLX display 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:gstvaapidisplay_glx
+ * @short_description: VA/GLX display abstraction
+ */
+
+#include "sysdeps.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapiutils_glx.h"
+#include "gstvaapidisplay_priv.h"
+#include "gstvaapidisplay_x11_priv.h"
+#include "gstvaapidisplay_glx.h"
+#include "gstvaapidisplay_glx_priv.h"
+
+#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);
+
+ 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);
+}
+
+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_display_info;
+}
+
+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);
+}
--- /dev/null
+/*
+ * gstvaapidisplay_glx.h - VA/GLX display abstraction
+ *
+ * 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_DISPLAY_GLX_H
+#define GST_VAAPI_DISPLAY_GLX_H
+
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <gst/vaapi/gstvaapidisplay_x11.h>
+
+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) G_GNUC_CONST;
+
+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 */
--- /dev/null
+/*
+ * gstvaapidisplay_glx_priv.h - Internal VA/GLX 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_DISPLAY_GLX_PRIV_H
+#define GST_VAAPI_DISPLAY_GLX_PRIV_H
+
+#include <gst/vaapi/gstvaapiutils_glx.h>
+#include <gst/vaapi/gstvaapidisplay_glx.h>
+
+G_BEGIN_DECLS
+
+#define GST_VAAPI_DISPLAY_GLX_CAST(display) ((GstVaapiDisplayGLX *)(display))
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DISPLAY_GLX_PRIV_H */
--- /dev/null
+/*
+ * gstvaapidisplay_priv.h - Base VA display (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_DISPLAY_PRIV_H
+#define GST_VAAPI_DISPLAY_PRIV_H
+
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapidisplaycache.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))
+
+/**
+ * GST_VAAPI_DISPLAY_VADISPLAY:
+ * @display_: a #GstVaapiDisplay
+ *
+ * Macro that evaluates to the #VADisplay of @display.
+ * This is an internal macro that does not do any run-time type check.
+ */
+#undef GST_VAAPI_DISPLAY_VADISPLAY
+#define GST_VAAPI_DISPLAY_VADISPLAY(display_) \
+ GST_VAAPI_DISPLAY_CAST(display_)->priv->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))
+
+/**
+ * GstVaapiDisplayPrivate:
+ *
+ * Base class for VA displays.
+ */
+struct _GstVaapiDisplayPrivate {
+ GstVaapiDisplay *parent;
+ GStaticRecMutex 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 create_display : 1;
+};
+
+GstVaapiDisplayCache *
+gst_vaapi_display_get_cache(void);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DISPLAY_PRIV_H */
--- /dev/null
+/*
+ * 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 <string.h>
+#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
+};
+
+#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)
+{
+ static const gchar *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)
+{
+ 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 *cached_name = a;
+ 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(tested_name && is_display_name(tested_name), FALSE);
+ tested_name += NAME_PREFIX_LENGTH;
+ 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;
+}
+
+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)
+{
+ 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)
+{
+ GstVaapiDisplayWaylandPrivate * const priv = display->priv;
+
+ g_free(priv->display_name);
+
+ if (!display_name) {
+ display_name = get_default_display_name();
+ if (!display_name)
+ display_name = "";
+ }
+ priv->display_name = g_strdup_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);
+}
+
+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,
+ 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);
+ 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
+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(get_display_name(display));
+ 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) {
+ if (priv->create_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_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)
+{
+ 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;
+ 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)
+{
+ GstVaapiDisplayWaylandPrivate * const 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->output = NULL;
+ priv->width = 0;
+ priv->height = 0;
+ priv->phys_width = 0;
+ priv->phys_height = 0;
+ 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;
+}
--- /dev/null
+/*
+ * 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 <va/va_wayland.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+
+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 */
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidisplay_wayland.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))
+
+/**
+ * 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;
+ struct wl_output *output;
+ guint width;
+ guint height;
+ guint phys_width;
+ guint phys_height;
+ gint event_fd;
+ guint32 event_mask;
+ guint create_display : 1;
+};
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DISPLAY_WAYLAND_PRIV_H */
--- /dev/null
+/*
+ * gstvaapidisplay_x11.c - VA/X11 display 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:gstvaapidisplay_x11
+ * @short_description: VA/X11 display abstraction
+ */
+
+#include "sysdeps.h"
+#include <string.h>
+#include "gstvaapiutils.h"
+#include "gstvaapidisplay_priv.h"
+#include "gstvaapidisplay_x11.h"
+#include "gstvaapidisplay_x11_priv.h"
+
+#ifdef HAVE_XRANDR
+# include <X11/extensions/Xrandr.h>
+#endif
+
+#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
+
+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)
+{
+ 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 *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? */
+ 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)
+{
+ 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)
+{
+ GstVaapiDisplayX11Private * const priv = display->priv;
+
+ g_free(priv->display_name);
+
+ if (!display_name) {
+ display_name = get_default_display_name();
+ if (!display_name)
+ display_name = "";
+ }
+ priv->display_name = g_strdup_printf("%s%s", NAME_PREFIX, display_name);
+}
+
+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,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+)
+{
+ 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;
+ 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);
+}
+
+static gboolean
+gst_vaapi_display_x11_open_display(GstVaapiDisplay *display)
+{
+ GstVaapiDisplayX11Private * const priv =
+ GST_VAAPI_DISPLAY_X11(display)->priv;
+
+ if (priv->create_display) {
+ priv->x11_display = XOpenDisplay(get_display_name(display));
+ 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);
+
+#ifdef HAVE_XRANDR
+ {
+ int evt_base, err_base;
+ priv->use_xrandr = XRRQueryExtension(
+ priv->x11_display, &evt_base, &err_base);
+ }
+#endif
+ return TRUE;
+}
+
+static void
+gst_vaapi_display_x11_close_display(GstVaapiDisplay *display)
+{
+ GstVaapiDisplayX11Private * const priv =
+ GST_VAAPI_DISPLAY_X11(display)->priv;
+
+ if (priv->x11_display) {
+ if (priv->create_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(display)->priv;
+
+ 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(display)->priv;
+
+ 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(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;
+ 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(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_get_size_mm(
+ GstVaapiDisplay *display,
+ guint *pwidth,
+ guint *pheight
+)
+{
+ 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 = width_mm;
+
+ if (pheight)
+ *pheight = height_mm;
+}
+
+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->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;
+ 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;
+
+ /**
+ * 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)
+{
+ GstVaapiDisplayX11Private *priv = GST_VAAPI_DISPLAY_X11_GET_PRIVATE(display);
+
+ display->priv = priv;
+ priv->create_display = TRUE;
+ priv->x11_display = NULL;
+ priv->x11_screen = 0;
+ priv->display_name = NULL;
+ priv->use_xrandr = FALSE;
+}
+
+/**
+ * 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)
+{
+ return g_object_new(GST_VAAPI_TYPE_DISPLAY_X11,
+ "display-name", 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)
+{
+ 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);
+}
+
+/**
+ * gst_vaapi_display_x11_get_display:
+ * @display: a #GstVaapiDisplayX11
+ *
+ * Returns the underlying X11 #Display that was created by
+ * gst_vaapi_display_x11_new() or that was bound from
+ * gst_vaapi_display_x11_new_with_display().
+ *
+ * Return value: the X11 #Display attached to @display
+ */
+Display *
+gst_vaapi_display_x11_get_display(GstVaapiDisplayX11 *display)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY_X11(display), NULL);
+
+ return 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;
+}
--- /dev/null
+/*
+ * gstvaapidisplay_x11.h - VA/X11 display abstraction
+ *
+ * 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_DISPLAY_X11_H
+#define GST_VAAPI_DISPLAY_X11_H
+
+#include <va/va_x11.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+
+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, \
+ GstVaapiDisplayX11Class))
+
+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);
+
+GstVaapiDisplay *
+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 */
--- /dev/null
+/*
+ * gstvaapidisplay_x11_priv.h - Internal VA/X11 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_DISPLAY_X11_PRIV_H
+#define GST_VAAPI_DISPLAY_X11_PRIV_H
+
+#include <gst/vaapi/gstvaapiutils_x11.h>
+#include <gst/vaapi/gstvaapidisplay_x11.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))
+
+/**
+ * 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;
+ guint use_xrandr : 1;
+};
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_DISPLAY_X11_PRIV_H */
--- /dev/null
+/*
+ * 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 "sysdeps.h"
+#include <glib.h>
+#include <string.h>
+#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_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;
+
+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_static_mutex_free(&cache->mutex);
+ 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;
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidisplay.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapiencoder.c - VA-API encoder interface
+ *
+ * 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 "gstvaapiencoder.h"
+
+#include <string.h>
+
+#include "gstvaapidisplay_x11.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_encoder_debug);
+#define GST_CAT_DEFAULT gst_vaapi_encoder_debug
+
+
+G_DEFINE_TYPE(GstVaapiEncoder, gst_vaapi_encoder, G_TYPE_OBJECT)
+
+gboolean
+gst_vaapi_encoder_set_display(
+ GstVaapiEncoder* encoder,
+ GstVaapiDisplay *display
+)
+{
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+ if (display == priv->display) {
+ return TRUE;
+ }
+
+ if (VAAPI_ENC_INIT < priv->state) {
+ return FALSE;
+ }
+ if (priv->display) {
+ g_object_unref(priv->display);
+ priv->display = NULL;
+ priv->va_display = NULL;
+ }
+ if (display) {
+ priv->display = g_object_ref(display);
+ priv->va_display = gst_vaapi_display_get_display(display);
+ }
+ return TRUE;
+}
+
+GstVaapiDisplay *
+gst_vaapi_encoder_get_display(GstVaapiEncoder* encoder)
+{
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+ return (priv->display ? g_object_ref(priv->display) : NULL);
+}
+
+GstVaapiContext *
+gst_vaapi_encoder_get_context(GstVaapiEncoder* encoder)
+{
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+ return (priv->context ? g_object_ref(priv->context) : NULL);
+}
+
+
+VAAPI_Encode_State
+gst_vaapi_encoder_get_state(GstVaapiEncoder* encoder)
+{
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+ return priv->state;
+}
+
+
+EncoderStatus
+gst_vaapi_encoder_initialize(GstVaapiEncoder* encoder)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ /* check state */
+ if (VAAPI_ENC_INIT == priv->state) {
+ return ENCODER_NO_ERROR;
+ }
+ ENCODER_ASSERT(VAAPI_ENC_NULL == priv->state);
+ if (VAAPI_ENC_NULL != priv->state) {
+ return ENCODER_STATE_ERR;
+ }
+
+ /* create va_dpy*/
+ if (!priv->display) {
+ priv->display = gst_vaapi_display_x11_new(NULL);
+ ENCODER_CHECK_STATUS(priv->display,
+ ENCODER_DISPLAY_ERR,
+ "gst_vaapi_display_x11_new failed.");
+ priv->va_display = gst_vaapi_display_get_display(priv->display);
+ }
+
+ if (encoder_class->initialize) {
+ ret = encoder_class->initialize(encoder);
+ ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == ret,
+ ret,
+ "encoder <initialize> failed.");
+ }
+ priv->state = VAAPI_ENC_INIT;
+
+end:
+ return ret;
+}
+
+EncoderStatus
+gst_vaapi_encoder_open(GstVaapiEncoder* encoder)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ /* check state */
+ if (VAAPI_ENC_OPENED == priv->state) {
+ return ENCODER_NO_ERROR;
+ }
+ ENCODER_ASSERT(VAAPI_ENC_INIT == priv->state);
+ if (VAAPI_ENC_INIT != priv->state) {
+ return ENCODER_STATE_ERR;
+ }
+ ENCODER_ASSERT(!priv->context);
+
+ ENCODER_CHECK_STATUS(encoder_class->open,
+ ENCODER_FUNC_PTR_ERR,
+ "encoder <open> function pointer empty.");
+ ret = encoder_class->open(encoder, &priv->context);
+ ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
+ ret,
+ "encoder <open> failed.");
+ ENCODER_CHECK_STATUS(priv->context,
+ ENCODER_CONTEXT_ERR,
+ "encoder <open> context failed.");
+ priv->va_context = gst_vaapi_context_get_id(priv->context);
+ priv->state = VAAPI_ENC_OPENED;
+
+end:
+ return ret;
+}
+
+EncoderStatus
+gst_vaapi_encoder_encode(
+ GstVaapiEncoder* encoder,
+ GstBuffer *raw_pic,
+ GList **coded_pics
+)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ ENCODER_CHECK_STATUS(priv->state >= VAAPI_ENC_OPENED,
+ ENCODER_STATE_ERR,
+ "encoder was not opened before <encode>.");
+ ENCODER_CHECK_STATUS(encoder_class->encode,
+ ENCODER_FUNC_PTR_ERR,
+ "encoder <encode> function pointer empty.");
+ ret = encoder_class->encode(encoder, raw_pic, coded_pics);
+ ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
+ ret,
+ "encoder <encode> failed.");
+ if (priv->state < VAAPI_ENC_ENCODING) {
+ priv->state = VAAPI_ENC_ENCODING;
+ }
+end:
+ return ret;
+}
+
+EncoderStatus
+gst_vaapi_encoder_get_codec_data(
+ GstVaapiEncoder* encoder,
+ GstBuffer **codec_data
+)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ ENCODER_CHECK_STATUS(priv->state >= VAAPI_ENC_OPENED,
+ ENCODER_STATE_ERR,
+ "encoder was not opened before <get_codec_data>.");
+ if (!encoder_class->get_codec_data) {
+ *codec_data = NULL;
+ ENCODER_LOG_INFO("There's no codec_data");
+ return ret;
+ }
+ ret = encoder_class->get_codec_data(encoder, codec_data);
+
+end:
+ return ret;
+}
+
+EncoderStatus
+gst_vaapi_encoder_flush(
+ GstVaapiEncoder* encoder,
+ GList **coded_pics
+)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ if (priv->state < VAAPI_ENC_OPENED) {
+ return ENCODER_STATE_ERR;
+ }
+ ENCODER_CHECK_STATUS(encoder_class->flush,
+ ENCODER_FUNC_PTR_ERR,
+ "encoder <flush> function pointer empty.");
+ ret = encoder_class->flush(encoder, coded_pics);
+ ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
+ ret,
+ "encoder <flush> failed.");
+ if (priv->state > VAAPI_ENC_OPENED) {
+ priv->state = VAAPI_ENC_OPENED;
+ }
+end:
+ return ret;
+}
+
+EncoderStatus
+gst_vaapi_encoder_close(GstVaapiEncoder* encoder)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ if (VAAPI_ENC_INIT >= priv->state) {
+ return ENCODER_NO_ERROR;
+ }
+ ENCODER_CHECK_STATUS(encoder_class->close,
+ ENCODER_FUNC_PTR_ERR,
+ "encoder <close> function pointers empty.");
+ ret = encoder_class->close(encoder);
+ ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
+ ret,
+ "encoder <close> failed.");
+end:
+ if (priv->context) {
+ g_object_unref(priv->context);
+ priv->context = NULL;
+ priv->va_context = VA_INVALID_ID;
+ }
+
+ priv->state = VAAPI_ENC_INIT;
+ return ret;
+}
+
+EncoderStatus
+gst_vaapi_encoder_uninitialize(GstVaapiEncoder* encoder)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderClass *encoder_class = GST_VAAPI_ENCODER_GET_CLASS(encoder);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+
+ if (VAAPI_ENC_NULL == priv->state) {
+ return ENCODER_NO_ERROR;
+ }
+
+ if (VAAPI_ENC_INIT < priv->state) {
+ ret = gst_vaapi_encoder_close(encoder);
+ }
+ ENCODER_ASSERT(VAAPI_ENC_INIT == priv->state);
+ if (encoder_class->uninitialize) {
+ ret = encoder_class->uninitialize(encoder);
+ ENCODER_CHECK_STATUS(ENCODER_NO_ERROR == ret,
+ ret,
+ "encoder <uninitialize> failed.");
+ }
+
+end:
+ if (priv->display) {
+ g_object_unref(priv->display);
+ priv->display = NULL;
+ priv->va_display = NULL;
+ }
+ priv->state = VAAPI_ENC_NULL;
+ return ret;
+
+}
+
+char *
+vaapi_encoder_dump_bytes(const guint8 *buf, guint32 num)
+{
+ static char tmp[1024];
+ guint32 i = 0;
+ memset(tmp, 0, sizeof(tmp));
+
+ char *p = tmp;
+ for (i = 0; i < num; i++) {
+ snprintf(p, 1024-(p-tmp), "%02x", (guint8)buf[i]);
+ p += strlen(p);
+ }
+ return tmp;
+}
+
+static void
+gst_vaapi_encoder_init(GstVaapiEncoder *encoder)
+{
+ GstVaapiEncoderPrivate *priv;
+
+ encoder->priv = GST_VAAPI_ENCODER_GET_PRIVATE(encoder);
+ priv = encoder->priv;
+ ENCODER_ASSERT(priv);
+
+ priv->display = NULL;
+ priv->va_display = NULL;
+ priv->context = NULL;
+ priv->va_context = VA_INVALID_ID;
+ priv->state = VAAPI_ENC_NULL;
+
+ encoder->width = 0;
+ encoder->height = 0;
+ encoder->frame_rate = 0;
+}
+
+static void
+gst_vaapi_encoder_finalize(GObject *object)
+{
+ GstVaapiEncoder* encoder = GST_VAAPI_ENCODER(object);
+ GstVaapiEncoderPrivate *priv = encoder->priv;
+ if (VAAPI_ENC_NULL != priv->state) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+
+ if (priv->context) {
+ g_object_unref(priv->context);
+ priv->context = NULL;
+ priv->va_context = VA_INVALID_ID;
+ }
+
+ if (priv->display) {
+ g_object_unref(priv->display);
+ priv->display = NULL;
+ priv->va_display = NULL;
+ }
+
+ G_OBJECT_CLASS (gst_vaapi_encoder_parent_class)->finalize (object);
+}
+
+static void
+gst_vaapi_encoder_class_init(GstVaapiEncoderClass *kclass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(kclass);
+ g_type_class_add_private(kclass, sizeof(GstVaapiEncoderPrivate));
+
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_encoder_debug,
+ "gst_va_encoder",
+ 0,
+ "gst_va_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_finalize;
+}
--- /dev/null
+/*
+ * gstvaapiencoder.h - VA-API encoder interface
+ *
+ * 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_ENCODER_H
+#define GST_VAAPI_ENCODER_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "gst/gstinfo.h"
+#include "gst/gstbuffer.h"
+
+#include "gst/vaapi/gstvaapidisplay.h"
+#include "gst/vaapi/gstvaapicontext.h"
+
+G_BEGIN_DECLS
+
+#define ENCODER_NO_ERROR 0
+#define ENCODER_NO_DATA 1
+#define ENCODER_BUFFER_WAITING 2
+#define ENCODER_BUFFER_EMPTY 3
+
+
+#define ENCODER_MEM_ERR -1
+#define ENCODER_DISPLAY_ERR -2
+#define ENCODER_CONFIG_ERR -3
+#define ENCODER_CONTEXT_ERR -3
+#define ENCODER_STATE_ERR -4
+#define ENCODER_ENC_RES_ERR -5
+#define ENCODER_PICTURE_ERR -6
+#define ENCODER_SURFACE_ERR -7
+#define ENCODER_QUERY_STATUS_ERR -8
+#define ENCODER_DATA_NOT_READY -9
+#define ENCODER_DATA_ERR -10
+#define ENCODER_PROFILE_ERR -11
+#define ENCODER_PARAMETER_ERR -12
+#define ENCODER_FUNC_PTR_ERR -13
+
+#ifdef DEBUG
+ #define ENCODER_LOG_ERROR(str_fmt,...) \
+ fprintf(stdout, str_fmt "\n", ## __VA_ARGS__)
+ #define ENCODER_LOG_WARNING(str_fmt,...) \
+ fprintf(stdout, str_fmt "\n", ## __VA_ARGS__)
+ #define ENCODER_LOG_DEBUG(str_fmt,...) \
+ fprintf(stdout, str_fmt "\n", ## __VA_ARGS__)
+ #define ENCODER_LOG_INFO(str_fmt,...) \
+ fprintf(stdout, str_fmt "\n", ## __VA_ARGS__)
+#else
+ #define ENCODER_LOG_ERROR(...) GST_ERROR( __VA_ARGS__)
+ #define ENCODER_LOG_WARNING(...) GST_WARNING( __VA_ARGS__)
+ #define ENCODER_LOG_DEBUG(...) GST_DEBUG( __VA_ARGS__)
+ #define ENCODER_LOG_INFO(...) GST_INFO( __VA_ARGS__)
+#endif
+
+#define VAAPI_UNUSED_ARG(arg) (void)(arg)
+
+#ifdef DEBUG
+#include <assert.h>
+#define ENCODER_ASSERT(exp) assert(exp)
+#else
+#define ENCODER_ASSERT(exp) g_assert(exp)
+#endif
+
+#define ENCODER_CHECK_STATUS(exp, err_num, err_reason, ...) \
+ if (!(exp)) { \
+ ENCODER_ASSERT(FALSE); \
+ ret = err_num; \
+ ENCODER_LOG_ERROR(err_reason, ## __VA_ARGS__); \
+ goto end; \
+ }
+
+/* must have <gboolean is_locked = FALSE;> declared first*/
+#define ENCODER_ACQUIRE_DISPLAY_LOCK(display) \
+ if (!is_locked) { \
+ GST_VAAPI_DISPLAY_LOCK(display); \
+ is_locked = TRUE; \
+ }
+
+#define ENCODER_RELEASE_DISPLAY_LOCK(display) \
+ if (is_locked) { \
+ GST_VAAPI_DISPLAY_UNLOCK(display); \
+ is_locked = FALSE; \
+ }
+
+
+typedef enum {
+ VAAPI_ENC_NULL,
+ VAAPI_ENC_INIT,
+ VAAPI_ENC_OPENED,
+ VAAPI_ENC_ENCODING,
+} VAAPI_Encode_State;
+
+typedef int EncoderStatus;
+typedef struct _GstVaapiEncoder GstVaapiEncoder;
+typedef struct _GstVaapiEncoderPrivate GstVaapiEncoderPrivate;
+typedef struct _GstVaapiEncoderClass GstVaapiEncoderClass;
+
+#define GST_TYPE_VAAPI_ENCODER \
+ (gst_vaapi_encoder_get_type())
+
+#define GST_IS_VAAPI_ENCODER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODER))
+
+#define GST_IS_VAAPI_ENCODER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODER))
+
+#define GST_VAAPI_ENCODER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODER, \
+ GstVaapiEncoderClass))
+
+#define GST_VAAPI_ENCODER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODER, \
+ GstVaapiEncoder))
+
+#define GST_VAAPI_ENCODER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODER, \
+ GstVaapiEncoderClass))
+
+#define GST_VAAPI_ENCODER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_TYPE_VAAPI_ENCODER, \
+ GstVaapiEncoderPrivate))
+
+#define GST_VAAPI_ENCODER_CAST(encoder) \
+ ((GstVaapiEncoder *)(encoder))
+
+/* Get GstVaapiDisplay* */
+#define ENCODER_DISPLAY(encoder) \
+ (((GstVaapiEncoder*)(encoder))->priv->display)
+
+/* Get VADisplay */
+#define ENCODER_VA_DISPLAY(encoder) \
+ (((GstVaapiEncoder*)(encoder))->priv->va_display)
+
+/* Get GstVaapiContext* */
+#define ENCODER_CONTEXT(encoder) \
+ (((GstVaapiEncoder*)(encoder))->priv->context)
+
+/* Get VAContext */
+#define ENCODER_VA_CONTEXT(encoder) \
+ (((GstVaapiEncoder*)(encoder))->priv->va_context)
+
+#define ENCODER_WIDTH(encoder) (((GstVaapiEncoder*)(encoder))->width)
+#define ENCODER_HEIGHT(encoder) (((GstVaapiEncoder*)(encoder))->height)
+#define ENCODER_FPS(encoder) (((GstVaapiEncoder*)(encoder))->frame_rate)
+
+struct _GstVaapiEncoder {
+ GObject parent;
+ GstVaapiEncoderPrivate *priv;
+
+ guint32 width;
+ guint32 height;
+ guint32 frame_rate;
+};
+
+struct _GstVaapiEncoderClass {
+ GObjectClass parent_class;
+
+ EncoderStatus (*initialize) (GstVaapiEncoder* encoder); /* can be NULL */
+ EncoderStatus (*uninitialize) (GstVaapiEncoder* encoder); /* can be NULL */
+
+ /* context [out] */
+ EncoderStatus (*open) (GstVaapiEncoder* encoder,
+ GstVaapiContext **context);
+
+ EncoderStatus (*close) (GstVaapiEncoder* encoder);
+ /* coded_pics [out] */
+ EncoderStatus (*encode) (GstVaapiEncoder* encoder,
+ GstBuffer *raw_pic,
+ GList **coded_pics);
+ /* coded_pics [out] */
+ EncoderStatus (*flush) (GstVaapiEncoder* encoder, GList **coded_pics);
+
+ /* get_codec_data can be NULL */
+ EncoderStatus (*get_codec_data)(GstVaapiEncoder* encoder, GstBuffer **codec_data);
+};
+
+struct _GstVaapiEncoderPrivate {
+ GstVaapiDisplay *display;
+ VADisplay va_display;
+ GstVaapiContext *context;
+ VAContextID va_context;
+ VAAPI_Encode_State state;
+};
+
+GType
+gst_vaapi_encoder_get_type(void);
+
+/* set/get display */
+gboolean
+gst_vaapi_encoder_set_display(
+ GstVaapiEncoder* encoder,
+ GstVaapiDisplay *display
+);
+GstVaapiDisplay *
+gst_vaapi_encoder_get_display(GstVaapiEncoder* encoder);
+
+/* get context */
+GstVaapiContext *
+gst_vaapi_encoder_get_context(GstVaapiEncoder* encoder);
+
+/* get encoding state */
+VAAPI_Encode_State
+gst_vaapi_encoder_get_state(GstVaapiEncoder* encoder);
+
+/* check/open display */
+EncoderStatus
+gst_vaapi_encoder_initialize(GstVaapiEncoder* encoder);
+
+/* check/open context */
+EncoderStatus
+gst_vaapi_encoder_open(GstVaapiEncoder* encoder);
+
+/* encode one frame */
+EncoderStatus
+gst_vaapi_encoder_encode(
+ GstVaapiEncoder* encoder,
+ GstBuffer *raw_pic,
+ GList **coded_pics
+);
+
+EncoderStatus
+gst_vaapi_encoder_get_codec_data(
+ GstVaapiEncoder* encoder,
+ GstBuffer **codec_data
+);
+
+/* flush all frames */
+EncoderStatus
+gst_vaapi_encoder_flush(GstVaapiEncoder* encoder, GList **coded_pics);
+
+/* close context */
+EncoderStatus
+gst_vaapi_encoder_close(GstVaapiEncoder* encoder);
+
+/* close display */
+EncoderStatus
+gst_vaapi_encoder_uninitialize(GstVaapiEncoder* encoder);
+
+static inline void
+gst_vaapi_encoder_unref (GstVaapiEncoder *encoder)
+{
+ g_object_unref (encoder);
+}
+
+/* other functions */
+char *vaapi_encoder_dump_bytes(const guint8 *buf, guint32 num);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODER_H */
--- /dev/null
+/*
+ * gstvaapiencoder_h263.c - H.263 encoder
+ *
+ * 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 "gstvaapiencoder_h263.h"
+
+#include <string.h>
+#include <gst/gstclock.h>
+
+#include "gstvaapiobject.h"
+#include "gstvaapiobject_priv.h"
+#include "gstvaapicontext.h"
+#include "gstvaapisurface.h"
+#include "gstvaapivideobuffer.h"
+#include "gstvaapidisplay_priv.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h263_encoder_debug);
+#define GST_CAT_DEFAULT gst_vaapi_h263_encoder_debug
+
+#define GST_VAAPI_ENCODER_H263_CAST(encoder) ((GstVaapiEncoderH263 *)(encoder))
+
+struct _GstVaapiEncoderH263Private {
+ GstVaapiSurface *ref_surface; /* reference buffer*/
+ GstVaapiSurface *recon_surface; /* reconstruct buffer*/
+
+ VABufferID seq_param_id;
+ VABufferID pic_param_id;
+ VABufferID slic_param_id;
+};
+
+G_DEFINE_TYPE(GstVaapiEncoderH263, gst_vaapi_encoder_h263, GST_TYPE_VAAPI_BASE_ENCODER)
+
+GstVaapiEncoderH263 *
+gst_vaapi_encoder_h263_new(void)
+{
+ return GST_VAAPI_ENCODER_H263_CAST(g_object_new(GST_TYPE_VAAPI_ENCODER_H263, NULL));
+}
+
+static gboolean
+gst_vaapi_encoder_h263_validate_attributes(
+ GstVaapiBaseEncoder* base
+)
+{
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+ if (!ENCODER_WIDTH(encoder) ||
+ !ENCODER_HEIGHT(encoder) ||
+ !ENCODER_FPS(encoder))
+ {
+ return FALSE;
+ }
+ if (!encoder->intra_period) {
+ encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
+ }
+ if (-1 == encoder->init_qp) {
+ encoder->init_qp = H263_DEFAULT_INIT_QP;
+ }
+ if (-1 == encoder->min_qp) {
+ encoder->min_qp = H263_DEFAULT_MIN_QP;
+ }
+
+ /* default compress ratio 1: (4*8*1.5) */
+ if (!encoder->bitrate) {
+ encoder->bitrate =
+ ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
+ }
+ gst_vaapi_base_encoder_set_va_profile(GST_VAAPI_BASE_ENCODER(encoder),
+ VAProfileH263Baseline);
+ return TRUE;
+
+}
+
+
+static void
+h263_release_parameters(
+ GstVaapiEncoderH263 *encoder
+)
+{
+ GstVaapiEncoderH263Private *priv = encoder->priv;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ VAAPI_UNUSED_ARG(va_status);
+
+ if (VA_INVALID_ID != priv->seq_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->seq_param_id);
+ priv->seq_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->pic_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->slic_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->slic_param_id);
+ priv->slic_param_id = VA_INVALID_ID;
+ }
+
+}
+
+static gboolean
+gst_vaapi_encoder_h263_release_resource(
+ GstVaapiBaseEncoder* base
+)
+{
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+ GstVaapiEncoderH263Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+
+ h263_release_parameters(encoder);
+
+ /*remove ref_surface*/
+ if (priv->ref_surface) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->ref_surface);
+ } else {
+ g_object_unref(priv->ref_surface);
+ }
+ priv->ref_surface = NULL;
+ }
+
+ /*remove recon_surface*/
+ if (priv->recon_surface) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->recon_surface);
+ } else {
+ g_object_unref(priv->recon_surface);
+ }
+ priv->recon_surface = NULL;
+ }
+
+ return TRUE;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_h263_rendering(
+ GstVaapiBaseEncoder *base,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key
+)
+
+{
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263_CAST(base);
+ GstVaapiEncoderH263Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(base);
+ VAContextID context_id = ENCODER_VA_CONTEXT(base);
+
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ EncoderStatus ret = ENCODER_NO_ERROR;
+
+ *is_key = (frame_index % encoder->intra_period == 0);
+
+ /* initialize sequence parameter set, only first time */
+ if (VA_INVALID_ID == priv->seq_param_id) { /*only the first time*/
+ VAEncSequenceParameterBufferH263 seq_param = {0};
+
+ seq_param.intra_period = encoder->intra_period;
+ seq_param.bits_per_second = encoder->bitrate;
+ seq_param.frame_rate = ENCODER_FPS(encoder);
+ seq_param.initial_qp = encoder->init_qp;
+ seq_param.min_qp = encoder->min_qp;
+
+ va_status = vaCreateBuffer(va_dpy, context_id,
+ VAEncSequenceParameterBufferType,
+ sizeof(seq_param), 1,
+ &seq_param,
+ &priv->seq_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_ENC_RES_ERR,
+ "h263 alloc seq-buffer failed.");
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_param_id, 1);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_PICTURE_ERR,
+ "h263 vaRenderPicture seq-parameters failed.");
+ }
+
+ /* set reference and reconstructed surfaces */
+ if (!priv->ref_surface) {
+ priv->ref_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface,
+ ENCODER_SURFACE_ERR,
+ "h263 reference surface, h263_pop_free_surface failed.");
+ }
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface,
+ ENCODER_SURFACE_ERR,
+ "h263 reconstructed surface, h263_pop_free_surface failed.");
+ }
+
+ /* initialize picture, every time, every frame */
+ VAEncPictureParameterBufferH263 pic_param = {0};
+ pic_param.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface);
+ pic_param.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_param.coded_buf = coded_buf;
+ pic_param.picture_width = ENCODER_WIDTH(encoder);
+ pic_param.picture_height = ENCODER_HEIGHT(encoder);
+ pic_param.picture_type = (*is_key) ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
+ if (VA_INVALID_ID != priv->pic_param_id) { /* destroy first*/
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+
+ va_status = vaCreateBuffer(va_dpy, context_id, VAEncPictureParameterBufferType,
+ sizeof(pic_param), 1, &pic_param, &priv->pic_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_ENC_RES_ERR, "h263 creating pic-param buffer failed.");
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_param_id, 1);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_PICTURE_ERR, "h263 rendering pic-param buffer failed.");
+ /*initialize slice parameters, only ONE slice for h263*/
+ VAEncSliceParameterBuffer slice_param = { 0 };
+ slice_param.start_row_number = 0;
+ slice_param.slice_height = (ENCODER_HEIGHT(encoder)+15)/16; /*MB?*/
+ slice_param.slice_flags.bits.is_intra = *is_key;
+ slice_param.slice_flags.bits.disable_deblocking_filter_idc = 0;
+ if (VA_INVALID_ID != priv->slic_param_id) {
+ vaDestroyBuffer(va_dpy, priv->slic_param_id);
+ priv->slic_param_id = VA_INVALID_ID;
+ }
+
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncSliceParameterBufferType,
+ sizeof(slice_param),
+ 1,
+ &slice_param,
+ &priv->slic_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_ENC_RES_ERR,
+ "h263 creating slice-parameters buffer failed.");
+
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->slic_param_id, 1);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_PICTURE_ERR,
+ "h263 rendering slice-parameters buffer failed.");
+
+ /*swap ref_surface and recon_surface */
+ GstVaapiSurface *swap = priv->ref_surface;
+ priv->ref_surface = priv->recon_surface;
+ priv->recon_surface = swap;
+
+end:
+ return ret;
+}
+
+static void
+gst_vaapi_encoder_h263_init(GstVaapiEncoderH263 *encoder)
+{
+ GstVaapiEncoderH263Private *priv = GST_VAAPI_ENCODER_H263_GET_PRIVATE(encoder);
+ encoder->priv = priv;
+ ENCODER_ASSERT(priv);
+
+ /* init public */
+ encoder->bitrate = 0;
+ encoder->intra_period = H263_DEFAULT_INTRA_PERIOD;
+ encoder->init_qp = H263_DEFAULT_INIT_QP;
+ encoder->min_qp = H263_DEFAULT_MIN_QP;
+
+ /* init private */
+ priv->ref_surface = NULL;
+ priv->recon_surface = NULL;
+
+ priv->seq_param_id = VA_INVALID_ID;
+ priv->pic_param_id = VA_INVALID_ID;
+ priv->slic_param_id = VA_INVALID_ID;
+}
+
+static void
+gst_vaapi_encoder_h263_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+ G_OBJECT_CLASS(gst_vaapi_encoder_h263_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_h263_class_init(GstVaapiEncoderH263Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ g_type_class_add_private(klass, sizeof(GstVaapiEncoderH263Private));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_h263_encoder_debug, "gst_va_h263_encoder", 0,
+ "gst_va_h263_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_h263_finalize;
+
+ base_class->validate_attributes = gst_vaapi_encoder_h263_validate_attributes;
+ base_class->pre_alloc_resource = NULL;
+ base_class->release_resource = gst_vaapi_encoder_h263_release_resource;
+ base_class->render_frame = gst_vaapi_encoder_h263_rendering;
+ base_class->notify_frame = NULL;
+ base_class->copy_coded_frame = NULL;
+
+ /*
+ encoder_class->flush = gst_vaapi_encoder_h263_flush;
+ */
+ encoder_class->get_codec_data = NULL;
+
+}
--- /dev/null
+/*
+ * gstvaapiencoder_h263.h - H.263 encoder
+ *
+ * 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_ENCODER_H263_H
+#define GST_VAAPI_ENCODER_H263_H
+
+#include "gst/vaapi/gstvaapisurfacepool.h"
+#include "gst/vaapi/gstvaapibaseencoder.h"
+
+G_BEGIN_DECLS
+
+#define H263_DEFAULT_INTRA_PERIOD 30
+#define H263_DEFAULT_INIT_QP 15
+#define H263_DEFAULT_MIN_QP 1
+
+
+typedef struct _GstVaapiEncoderH263 GstVaapiEncoderH263;
+typedef struct _GstVaapiEncoderH263Private GstVaapiEncoderH263Private;
+typedef struct _GstVaapiEncoderH263Class GstVaapiEncoderH263Class;
+
+
+#define GST_TYPE_VAAPI_ENCODER_H263 \
+ (gst_vaapi_encoder_h263_get_type())
+
+#define GST_IS_VAAPI_ENCODER_H263(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODER_H263))
+
+#define GST_IS_VAAPI_ENCODER_H263_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODER_H263))
+
+#define GST_VAAPI_ENCODER_H263_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODER_H263, \
+ GstVaapiEncoderH263Class))
+
+#define GST_VAAPI_ENCODER_H263(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODER_H263, \
+ GstVaapiEncoderH263))
+
+#define GST_VAAPI_ENCODER_H263_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODER_H263, \
+ GstVaapiEncoderH263Class))
+
+#define GST_VAAPI_ENCODER_H263_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_TYPE_VAAPI_ENCODER_H263, \
+ GstVaapiEncoderH263Private))
+
+struct _GstVaapiEncoderH263 {
+ GstVaapiBaseEncoder parent; /*based on gobject*/
+
+ guint32 bitrate;
+ guint32 intra_period;
+ guint32 init_qp; /*default 15, 1~31*/
+ guint32 min_qp; /*default 1, 1~31*/
+
+ GstVaapiEncoderH263Private *priv;
+};
+
+struct _GstVaapiEncoderH263Class {
+ GstVaapiBaseEncoderClass parent_class;
+};
+
+
+GType
+gst_vaapi_encoder_h263_get_type(void);
+
+GstVaapiEncoderH263 *
+gst_vaapi_encoder_h263_new(void);
+
+static inline void
+gst_vaapi_encoder_h263_unref (GstVaapiEncoderH263 * encoder)
+{
+ g_object_unref (encoder);
+}
+
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODER_H263_H */
--- /dev/null
+/*
+ * gstvaapiencoder_h264.c - H.264 encoder
+ *
+ * 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 "gstvaapiencoder_h264.h"
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <va/va.h>
+#include <va/va_x11.h>
+#if !HAVE_OLD_H264_ENCODER
+#include <va/va_enc_h264.h>
+#endif
+#include <X11/Xlib.h>
+#include <glib.h>
+
+#include "gst/gstclock.h"
+#include "gst/gstvalue.h"
+
+#include "gstvaapiobject.h"
+#include "gstvaapiobject_priv.h"
+#include "gstvaapicontext.h"
+#include "gstvaapisurface.h"
+#include "gstvaapivideobuffer.h"
+#include "gstvaapidisplay_priv.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encoder_debug);
+
+#define GST_CAT_DEFAULT gst_vaapi_h264_encoder_debug
+
+#define GST_VAAPI_ENCODER_H264_CAST(encoder) ((GstVaapiEncoderH264 *)(encoder))
+
+#define SHARE_CODED_BUF 0
+
+#define DEFAULT_SURFACE_NUMBER 3
+#define DEFAULT_CODEDBUF_NUM 5
+#define DEFAULT_SID_INPUT 0 // suface_ids[0]
+
+#define REF_RECON_SURFACE_NUM 2
+
+#define ENTROPY_MODE_CAVLC 0
+#define ENTROPY_MODE_CABAC 1
+
+#define BR_CBR 0
+#define BR_VBR 1
+#define BR_CQP 2
+
+#define NAL_REF_IDC_NONE 0
+#define NAL_REF_IDC_LOW 1
+#define NAL_REF_IDC_MEDIUM 2
+#define NAL_REF_IDC_HIGH 3
+
+
+typedef enum {
+ NAL_UNKNOWN = 0,
+ NAL_NON_IDR = 1,
+ NAL_IDR = 5, /* ref_idc != 0 */
+ NAL_SEI = 6, /* ref_idc == 0 */
+ NAL_SPS = 7,
+ NAL_PPS = 8,
+ NAL_AUD = 9,
+ NAL_FILLER = 12,
+}H264_NAL_TYPE;
+
+
+typedef enum {
+ SLICE_TYPE_P = 0,
+ SLICE_TYPE_B = 1,
+ SLICE_TYPE_I = 2
+} H264_SLICE_TYPE;
+
+struct _GstVaapiEncoderH264Private {
+ GstVaapiEncoderH264 *public;
+ guint32 format; /*NV12, I420,*/
+ gboolean avc_flag; /*elementary flag*/
+
+ /* private data*/
+ GQueue *video_buffer_caches; /*not used for baseline*/
+
+ GstVaapiSurface *ref_surface1; /* reference buffer*/
+ GstVaapiSurface *ref_surface2; /* for B frames */
+ GstVaapiSurface *recon_surface; /* reconstruct buffer*/
+
+ VABufferID seq_param_id;
+ VABufferID pic_param_id;
+ VABufferID slice_param_id;
+ VABufferID packed_seq_param_id;
+ VABufferID packed_seq_data_id;
+ VABufferID packed_pic_param_id;
+ VABufferID packed_pic_data_id;
+ gboolean is_seq_param_set;
+#if HAVE_OLD_H264_ENCODER
+ VAEncSliceParameterBuffer *slice_param_buffers;
+#else
+ VAEncSliceParameterBufferH264 *slice_param_buffers;
+#endif
+ guint32 default_slice_height;
+ guint32 slice_mod_mb_num;
+ guint32 default_cts_offset;
+
+ GstBuffer *sps_data;
+ GstBuffer *pps_data;
+
+ GQueue *queued_buffers; /* GstVaapiVideoBuffers with surface*/
+
+ guint32 gop_count;
+ guint32 cur_display_num;
+ guint32 cur_decode_num;
+ H264_SLICE_TYPE cur_slice_type;
+ guint64 last_decode_time;
+ guint32 max_frame_num;
+ guint32 max_pic_order_cnt;
+ guint16 idr_num;
+};
+
+G_DEFINE_TYPE(GstVaapiEncoderH264, gst_vaapi_encoder_h264, GST_TYPE_VAAPI_BASE_ENCODER)
+
+// 4096-1
+#define H264_BITSTREAM_ALLOC_ALIGN_MASK 0x0FFF
+
+#define BIT_STREAM_BUFFER(stream) ((stream)->buffer)
+#define BIT_STREAM_BIT_SIZE(stream) ((stream)->bit_size)
+
+struct _H264Bitstream {
+ guint8 *buffer;
+ guint32 bit_size;
+ guint32 max_bit_capability;
+};
+
+typedef struct _H264Bitstream H264Bitstream;
+
+static const guint8 h264_bit_mask[9] = {0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF};
+
+/* h264 bitstream functions */
+static void
+h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability);
+
+static gboolean
+h264_bitstream_write_uint(
+ H264Bitstream *bitstream,
+ guint32 value,
+ guint32 bit_size
+);
+
+static gboolean
+h264_bitstream_align(H264Bitstream *bitstream, guint32 value);
+
+static gboolean
+h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value);
+
+static gboolean
+h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value);
+
+static gboolean
+h264_bitstream_write_trailing_bits(H264Bitstream *bitstream);
+
+static gboolean
+h264_bitstream_write_byte_array(
+ H264Bitstream *bitstream,
+ const guint8 *buf,
+ guint32 byte_size
+);
+
+static void
+h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag);
+
+static gboolean
+h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size);
+
+static gboolean
+h264_bitstream_write_sps(
+ H264Bitstream *bitstream,
+ VAEncSequenceParameterBufferH264 *seq,
+ H264_Profile profile
+);
+static gboolean
+h264_bitstream_write_pps(
+ H264Bitstream *bitstream,
+ VAEncPictureParameterBufferH264 *pic
+);
+
+static gboolean
+h264_bitstream_write_nal_header(
+ H264Bitstream *bitstream,
+ guint nal_ref_idc,
+ guint nal_unit_type
+);
+
+static VAProfile
+h264_get_va_profile(guint32 profile)
+{
+ switch (profile) {
+ case H264_PROFILE_BASELINE:
+ return VAProfileH264Baseline;
+
+ case H264_PROFILE_MAIN:
+ return VAProfileH264Main;
+
+ case H264_PROFILE_HIGH:
+ return VAProfileH264High;
+
+ default:
+ break;
+ }
+ return (-1);
+}
+
+GstVaapiEncoderH264 *
+gst_vaapi_encoder_h264_new(void)
+{
+ return GST_VAAPI_ENCODER_H264_CAST(
+ g_object_new(GST_TYPE_VAAPI_ENCODER_H264, NULL));
+}
+
+static void
+gst_vaapi_encoder_h264_init_public_values(GstVaapiEncoderH264* encoder)
+{
+ encoder->profile = 0;
+ encoder->level = 0;
+ encoder->bitrate = 0;
+ encoder->intra_period = 0;
+ encoder->init_qp = -1;
+ encoder->min_qp = -1;
+ encoder->slice_num = 0;
+ encoder->b_frame_num = 0;
+}
+
+void
+gst_vaapi_encoder_h264_set_avc_flag(GstVaapiEncoderH264* encoder, gboolean avc)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ priv->avc_flag = avc;
+}
+
+gboolean
+gst_vaapi_encoder_h264_get_avc_flag(GstVaapiEncoderH264* encoder)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ return priv->avc_flag;
+}
+
+gboolean
+gst_vaapi_encoder_h264_validate_attributes(GstVaapiBaseEncoder *base)
+{
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ if (!ENCODER_WIDTH(encoder) ||
+ !ENCODER_HEIGHT(encoder) ||
+ !ENCODER_FPS(encoder)) {
+ return FALSE;
+ }
+ if (!encoder->profile) {
+ encoder->profile = H264_DEFAULT_PROFILE;
+ }
+ gst_vaapi_base_encoder_set_va_profile(base, h264_get_va_profile(encoder->profile));
+ if (!encoder->level) {
+ if (encoder->profile <= H264_PROFILE_BASELINE)
+ encoder->level = H264_LEVEL_30;
+ else
+ encoder->level = H264_LEVEL_41;
+ }
+ if (!encoder->intra_period) {
+ encoder->intra_period = H264_DEFAULT_INTRA_PERIOD;
+ }
+ if (-1 == encoder->init_qp) {
+ encoder->init_qp = H264_DEFAULT_INIT_QP;
+ }
+ if (-1 == encoder->min_qp) {
+ encoder->min_qp = 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 (!encoder->bitrate) {
+ encoder->bitrate = 0; //ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
+ }
+
+ if (!encoder->slice_num) {
+ encoder->slice_num = H264_DEFAULT_SLICE_NUM;
+ }
+
+ /* need calculate slice-num and each slice-height
+ suppose: ((encoder->height+15)/16) = 13, slice_num = 8
+ then: slice_1_height = 2
+ slice_2_height = 2
+ slice_3_height = 2
+ slice_4_height = 2
+ slice_5_height = 2
+ slice_6_height = 1
+ slice_7_height = 1
+ slice_8_height = 1
+ */
+ priv->default_slice_height = (ENCODER_HEIGHT(encoder)+15)/16/encoder->slice_num;
+ if (0 == priv->default_slice_height) { /* special value */
+ priv->default_slice_height = 1;
+ priv->slice_mod_mb_num = 0;
+ encoder->slice_num = (ENCODER_HEIGHT(encoder)+15)/16;
+ } else {
+ priv->slice_mod_mb_num = ((ENCODER_HEIGHT(encoder)+15)/16)%encoder->slice_num;
+ }
+
+ if (encoder->b_frame_num) {
+ priv->default_cts_offset = GST_SECOND/ENCODER_FPS(encoder);
+ } else {
+ priv->default_cts_offset = 0;
+ }
+ return TRUE;
+}
+
+
+static gboolean
+h264_encoder_release_parameters(GstVaapiEncoderH264 *encoder)
+{
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(encoder);
+ GstVaapiContext *context = ENCODER_CONTEXT(encoder);
+
+ gboolean is_locked = FALSE;
+
+ ENCODER_ASSERT(display);
+ ENCODER_ASSERT(context);
+ VAAPI_UNUSED_ARG(va_status);
+ VADisplay va_dpy = gst_vaapi_display_get_display(display);
+
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+ if (VA_INVALID_ID != priv->seq_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->seq_param_id);
+ priv->seq_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->pic_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->slice_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->slice_param_id);
+ priv->slice_param_id = VA_INVALID_ID;
+ }
+
+ if (VA_INVALID_ID != priv->packed_seq_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_seq_param_id);
+ priv->packed_seq_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->packed_seq_data_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_seq_data_id);
+ priv->packed_seq_data_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->packed_pic_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_pic_param_id);
+ priv->packed_pic_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->packed_pic_data_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->packed_pic_data_id);
+ priv->packed_pic_data_id = VA_INVALID_ID;
+ }
+
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+
+ if (priv->slice_param_buffers) {
+ g_free(priv->slice_param_buffers);
+ priv->slice_param_buffers = NULL;
+ }
+
+ if (priv->sps_data) {
+ gst_buffer_unref(priv->sps_data);
+ priv->sps_data = NULL;
+ }
+ if (priv->pps_data) {
+ gst_buffer_unref(priv->pps_data);
+ priv->pps_data = NULL;
+ }
+
+ return TRUE;
+}
+
+static void
+h264_release_queued_buffers(GstVaapiEncoderH264Private *priv)
+{
+ while (!g_queue_is_empty(priv->queued_buffers)) {
+ GstBuffer* tmp = g_queue_pop_head(priv->queued_buffers);
+ if (tmp)
+ gst_buffer_unref(tmp);
+ }
+}
+
+
+static gboolean
+gst_vaapi_encoder_h264_release_resource(
+ GstVaapiBaseEncoder* base
+)
+{
+ GstVaapiEncoderH264* encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ gboolean ret = TRUE;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+
+ /* release buffers first */
+ h264_encoder_release_parameters(encoder);
+ h264_release_queued_buffers(priv);
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->gop_count = 0;
+ priv->last_decode_time = 0LL;
+ priv->default_cts_offset = 0;
+ priv->is_seq_param_set = FALSE;
+
+ /*remove ref_surface1*/
+ if (priv->ref_surface1) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->ref_surface1);
+ } else {
+ g_object_unref(priv->ref_surface1);
+ }
+ priv->ref_surface1 = NULL;
+ }
+
+ if (priv->ref_surface2) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->ref_surface2);
+ } else {
+ g_object_unref(priv->ref_surface2);
+ }
+ priv->ref_surface2 = NULL;
+ }
+
+ /*remove recon_surface*/
+ if (priv->recon_surface) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->recon_surface);
+ } else {
+ g_object_unref(priv->recon_surface);
+ }
+ priv->recon_surface = NULL;
+ }
+
+ return ret;
+}
+
+static gboolean
+gst_vaapi_encoder_h264_alloc_slices(
+ GstVaapiBaseEncoder *base,
+ GstVaapiContext *context
+)
+{
+ gboolean ret = TRUE;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ priv->slice_param_buffers =
+#if HAVE_OLD_H264_ENCODER
+ (VAEncSliceParameterBuffer*)
+#else
+ (VAEncSliceParameterBufferH264*)
+#endif
+ g_malloc0_n(encoder->slice_num,
+ sizeof(priv->slice_param_buffers[0]));
+
+ return ret;
+}
+
+static void
+gst_vaapi_encoder_h264_frame_failed(
+ GstVaapiBaseEncoder *base,
+ GstVaapiVideoBuffer* buffer
+)
+{
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ h264_release_queued_buffers(priv);
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->gop_count = 0;
+ priv->last_decode_time = 0LL;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_h264_prepare_next_buffer(
+ GstVaapiBaseEncoder* base,
+ GstVaapiVideoBuffer *display_buf,
+ gboolean need_flush,
+ GstVaapiVideoBuffer **out_buf
+)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiVideoBuffer *return_buf = NULL;
+ //guint64 pts = 0;
+
+ if (NULL == display_buf && g_queue_is_empty(priv->queued_buffers)) {
+ ret = ENCODER_BUFFER_EMPTY;
+ if (priv->gop_count >= encoder->intra_period || need_flush)
+ priv->gop_count = 0;
+ goto end;
+ }
+
+ if (display_buf) {
+ ++priv->gop_count;
+ gst_buffer_ref(GST_BUFFER_CAST(display_buf));
+ priv->last_decode_time = GST_BUFFER_TIMESTAMP(display_buf);
+ }
+
+ /* first frame */
+ if (priv->gop_count == 1) {
+ ENCODER_ASSERT(display_buf);
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ ++priv->idr_num;
+ return_buf = display_buf;
+ goto end;
+ }
+
+ if (display_buf) {
+ if (encoder->b_frame_num &&
+ priv->gop_count < encoder->intra_period &&
+ g_queue_get_length(priv->queued_buffers) < encoder->b_frame_num
+ )
+ {
+ g_queue_push_tail(priv->queued_buffers, display_buf);
+ ret = ENCODER_BUFFER_WAITING;
+ goto end;
+ }
+ priv->cur_slice_type = SLICE_TYPE_P;
+ priv->cur_display_num = priv->gop_count-1;
+ ++priv->cur_decode_num;
+ return_buf = display_buf;
+ } else {
+ if (need_flush) {
+ return_buf = (GstVaapiVideoBuffer*)g_queue_pop_tail(priv->queued_buffers);
+ priv->cur_slice_type = SLICE_TYPE_P;
+ priv->cur_display_num = priv->gop_count - 1;
+ ++priv->cur_decode_num;
+ } else {
+ return_buf = (GstVaapiVideoBuffer*)g_queue_pop_head(priv->queued_buffers);
+ priv->cur_slice_type = SLICE_TYPE_B;
+ priv->cur_display_num =
+ priv->gop_count - 2 - g_queue_get_length(priv->queued_buffers);
+ }
+ }
+
+end:
+ *out_buf = return_buf;
+
+ return ret;
+}
+
+static inline void
+h264_swap_surface(GstVaapiSurface **s1, GstVaapiSurface **s2)
+{
+ GstVaapiSurface *tmp;
+
+ g_return_if_fail(s1 && s2);
+ tmp = *s1;
+ *s1 = *s2;
+ *s2 = tmp;
+}
+
+static inline const char *
+get_slice_type(H264_SLICE_TYPE type)
+{
+ switch (type) {
+ case SLICE_TYPE_I:
+ return "I";
+ case SLICE_TYPE_P:
+ return "P";
+ case SLICE_TYPE_B:
+ return "B";
+ default:
+ return "Unknown";
+ }
+}
+
+#if HAVE_OLD_H264_ENCODER
+
+static gboolean
+set_sequence_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSequenceParameterBufferH264 *seq_param
+)
+{
+ seq_param->seq_parameter_set_id = 0;
+ seq_param->level_idc = encoder->level; /* 3.0 */
+ seq_param->intra_period = encoder->intra_period;
+ seq_param->intra_idr_period = encoder->intra_period;
+ seq_param->max_num_ref_frames = 1; /*Only I, P frames*/
+ seq_param->picture_width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+ seq_param->picture_height_in_mbs = (ENCODER_HEIGHT(encoder)+15)/16;
+
+ seq_param->bits_per_second = encoder->bitrate;
+ seq_param->frame_rate = ENCODER_FPS(encoder);
+ seq_param->initial_qp = encoder->init_qp; /*qp_value; 15, 24, 26?*/
+ seq_param->min_qp = encoder->min_qp; /*1, 6, 10*/
+ seq_param->basic_unit_size = 0;
+ seq_param->vui_flag = FALSE;
+
+ return TRUE;
+}
+
+static gboolean
+set_picture_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncPictureParameterBufferH264 *pic_param,
+ VABufferID coded_buf
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ pic_param->reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ pic_param->reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_param->coded_buf = coded_buf;
+ pic_param->picture_width = ENCODER_WIDTH(encoder);
+ pic_param->picture_height = ENCODER_HEIGHT(encoder);
+ pic_param->last_picture = 0; // last pic or not
+
+ return TRUE;
+}
+
+static gboolean
+set_slices_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSliceParameterBuffer *slices,
+ guint slice_num
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncSliceParameterBuffer *slice_param;
+
+ int i = 0;
+ guint32 last_row_num = 0;
+ guint32 slice_mod_num = priv->slice_mod_mb_num;
+
+ for (i = 0; i < slice_num; ++i) {
+ slice_param = &slices[i];
+ slice_param->start_row_number = last_row_num; /* unit MB*/
+ slice_param->slice_height = priv->default_slice_height; /* unit MB */
+ if (slice_mod_num) {
+ ++slice_param->slice_height;
+ --slice_mod_num;
+ }
+ last_row_num += slice_param->slice_height;
+ slice_param->slice_flags.bits.is_intra =
+ (priv->cur_slice_type == SLICE_TYPE_I);
+ slice_param->slice_flags.bits.disable_deblocking_filter_idc = FALSE;
+ slice_param->slice_flags.bits.uses_long_term_ref = FALSE;
+ slice_param->slice_flags.bits.is_long_term_ref = FALSE;
+ }
+
+ ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(encoder)+15)/16);
+ return TRUE;
+}
+
+#else /* extended libva, new parameter structures*/
+
+static gboolean
+set_sequence_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSequenceParameterBufferH264 *seq_param
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ guint width_in_mbs, height_in_mbs;
+
+ width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+ height_in_mbs = (ENCODER_HEIGHT(encoder)+15)/16;
+
+ seq_param->seq_parameter_set_id = 0;
+ seq_param->level_idc = encoder->level; /* 3.0 */
+ seq_param->intra_period = encoder->intra_period;
+ seq_param->ip_period = 0; // ?
+ if (encoder->bitrate> 0)
+ seq_param->bits_per_second = encoder->bitrate; /* use kbps as input */
+ else
+ seq_param->bits_per_second = 0;
+
+ seq_param->max_num_ref_frames =
+ (encoder->b_frame_num < 2 ? 3 : encoder->b_frame_num+1); // ?, why 4
+ seq_param->picture_width_in_mbs = width_in_mbs;
+ seq_param->picture_height_in_mbs = height_in_mbs;
+
+ /*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;
+ seq_param->seq_fields.bits.log2_max_frame_num_minus4 = 4; // log2(seq.intra_period)-3 : 0
+ /* picture order count */
+ seq_param->seq_fields.bits.pic_order_cnt_type = 0;
+ seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 =
+ seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 2;
+ seq_param->seq_fields.bits.delta_pic_order_always_zero_flag = TRUE;
+
+ priv->max_frame_num =
+ 1<<(seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4);
+ priv->max_pic_order_cnt =
+ 1 <<(seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4);
+
+ seq_param->bit_depth_luma_minus8 = 0;
+ seq_param->bit_depth_chroma_minus8 = 0;
+
+ /* not used if pic_order_cnt_type == 0 */
+ 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 - 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 =
+ ((height_in_mbs * 16 - ENCODER_HEIGHT(encoder))/
+ (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)));
+ }
+#if 0
+ if (h264_encoder->init_qp == -1)
+ seq.rate_control_method = BR_CBR;
+ else if (h264_encoder->init_qp == -2)
+ seq.rate_control_method = BR_VBR;
+ else {
+ ENCODER_ASSERT(h264_encoder->init_qp >= 0 && h264_encoder->init_qp <= 51);
+ seq.rate_control_method = BR_CQP;
+ }
+#endif
+
+ /*vui not set*/
+ seq_param->vui_parameters_present_flag = FALSE;
+ return TRUE;
+}
+
+static gboolean
+ensure_packed_sps_data(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSequenceParameterBufferH264 *seq_param
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ guint32 length_in_bits;
+ guint8 *packed_seq_buffer = NULL;
+ H264Bitstream bitstream;
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ if (priv->sps_data)
+ return TRUE;
+
+ h264_bitstream_init(&bitstream, 128*8);
+ h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
+ h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_SPS);
+ h264_bitstream_write_sps(&bitstream, seq_param, encoder->profile);
+ ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
+ length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
+ packed_seq_buffer = BIT_STREAM_BUFFER(&bitstream);
+
+ /* set codec data sps */
+ priv->sps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+ GST_BUFFER_SIZE(priv->sps_data) = (length_in_bits+7)/8-4; /* start code size == 4*/
+ memcpy(GST_BUFFER_DATA(priv->sps_data),
+ packed_seq_buffer+4,
+ GST_BUFFER_SIZE(priv->sps_data));
+
+ packed_header_param_buffer.type = VAEncPackedHeaderSequence;
+ packed_header_param_buffer.bit_length = length_in_bits;
+ packed_header_param_buffer.has_emulation_bytes = 0;
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderParameterBufferType,
+ sizeof(packed_header_param_buffer), 1,
+ &packed_header_param_buffer,
+ &priv->packed_seq_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "EncPackedSeqHeaderParameterBuffer failed");
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderDataBufferType,
+ (length_in_bits + 7) / 8, 1,
+ packed_seq_buffer,
+ &priv->packed_seq_data_id);
+ h264_bitstream_destroy(&bitstream, TRUE);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "EncPackedSeqHeaderDataBuffer failed");
+end:
+ return ret;
+
+}
+
+static gboolean
+set_picture_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncPictureParameterBufferH264 *pic_param,
+ VABufferID coded_buf
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ 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 = (priv->cur_slice_type == SLICE_TYPE_B ?
+ (priv->cur_decode_num + 1) : priv->cur_decode_num);
+ //pic_param.coding_type = 0;
+ pic_param->pic_init_qp = (encoder->init_qp >= 0 ? encoder->init_qp : 26);
+ pic_param->num_ref_idx_l0_active_minus1 = 0; /* only 1 reference */
+ pic_param->num_ref_idx_l1_active_minus1 = 0; /* B frames only have 1 backward and 1 forward reference*/
+ 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 = (priv->cur_slice_type == SLICE_TYPE_I);
+ pic_param->pic_fields.bits.reference_pic_flag = (priv->cur_slice_type != SLICE_TYPE_B);
+ pic_param->pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_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 = TRUE; /* enable 8x8 */
+ pic_param->pic_fields.bits.deblocking_filter_control_present_flag = TRUE; /* enable debloking */
+ 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;
+
+ /* reference list, */
+ pic_param->CurrPic.picture_id = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_param->CurrPic.TopFieldOrderCnt = priv->cur_display_num * 2; // ??? /**/
+ pic_param->ReferenceFrames[0].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ pic_param->ReferenceFrames[1].picture_id = GST_VAAPI_OBJECT_ID(priv->ref_surface2);
+ pic_param->ReferenceFrames[2].picture_id = VA_INVALID_ID;
+ pic_param->coded_buf = coded_buf;
+
+ ENCODER_LOG_INFO("type:%s, frame_num:%d, display_num:%d",
+ get_slice_type(priv->cur_slice_type),
+ pic_param->frame_num,
+ pic_param->CurrPic.TopFieldOrderCnt);
+ return TRUE;
+}
+
+static gboolean
+ensure_packed_pps_data(
+ GstVaapiEncoderH264 *encoder,
+ VAEncPictureParameterBufferH264 *pic_param
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncPackedHeaderParameterBuffer packed_header_param_buffer = { 0 };
+ H264Bitstream bitstream;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ guint32 length_in_bits;
+ guint8 *packed_pic_buffer = NULL;
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ if (VA_INVALID_ID != priv->packed_pic_data_id)
+ return TRUE;
+
+ h264_bitstream_init(&bitstream, 128*8);
+ h264_bitstream_write_uint(&bitstream, 0x00000001, 32); /* start code*/
+ h264_bitstream_write_nal_header(&bitstream, NAL_REF_IDC_HIGH, NAL_PPS);
+ h264_bitstream_write_pps(&bitstream, pic_param);
+ ENCODER_ASSERT(BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
+ length_in_bits = BIT_STREAM_BIT_SIZE(&bitstream);
+ packed_pic_buffer = BIT_STREAM_BUFFER(&bitstream);
+
+ /*set codec data pps*/
+ priv->pps_data = gst_buffer_new_and_alloc((length_in_bits+7)/8);
+ GST_BUFFER_SIZE(priv->pps_data) = (length_in_bits+7)/8-4;
+ memcpy(GST_BUFFER_DATA(priv->pps_data),
+ packed_pic_buffer+4,
+ GST_BUFFER_SIZE(priv->pps_data));
+
+ packed_header_param_buffer.type = VAEncPackedHeaderPicture;
+ packed_header_param_buffer.bit_length = length_in_bits;
+ packed_header_param_buffer.has_emulation_bytes = 0;
+
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderParameterBufferType,
+ sizeof(packed_header_param_buffer), 1,
+ &packed_header_param_buffer,
+ &priv->packed_pic_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "EncPackedPicHeaderParameterBuffer failed");
+
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPackedHeaderDataBufferType,
+ (length_in_bits + 7) / 8, 1,
+ packed_pic_buffer,
+ &priv->packed_pic_data_id);
+ h264_bitstream_destroy(&bitstream, TRUE);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "EncPackedPicHeaderDataBuffer failed");
+end:
+ return ret;
+}
+
+static gboolean
+set_slices_parameters(
+ GstVaapiEncoderH264 *encoder,
+ VAEncSliceParameterBufferH264 *slices,
+ guint slice_num
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncSliceParameterBufferH264 *slice_param;
+
+ guint width_in_mbs = (ENCODER_WIDTH(encoder)+15)/16;
+ int i = 0;
+ guint32 last_row_num = 0;
+ guint32 slice_mod_num = priv->slice_mod_mb_num;
+
+ for (i = 0; i < slice_num; ++i) {
+ int i_pic = 0;
+ slice_param = slices + i;
+
+ slice_param->macroblock_address = last_row_num*width_in_mbs;
+ slice_param->num_macroblocks = width_in_mbs*priv->default_slice_height;
+ last_row_num += priv->default_slice_height;
+ if (slice_mod_num) {
+ slice_param->num_macroblocks += width_in_mbs;
+ ++last_row_num;
+ --slice_mod_num;
+ }
+ slice_param->macroblock_info = VA_INVALID_ID;
+ slice_param->slice_type = priv->cur_slice_type;
+ slice_param->pic_parameter_set_id = 0;
+ slice_param->idr_pic_id = priv->idr_num;
+ slice_param->pic_order_cnt_lsb =
+ (priv->cur_display_num*2) % priv->max_pic_order_cnt;
+
+ /* 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;
+ slice_param->num_ref_idx_l0_active_minus1 = 0;
+ slice_param->num_ref_idx_l1_active_minus1 = 0;
+
+ slice_param->RefPicList0[0].picture_id =
+ GST_VAAPI_OBJECT_ID(priv->ref_surface1);
+ for (i_pic = 1;
+ i_pic < sizeof(slice_param->RefPicList0)/sizeof(slice_param->RefPicList0[0]);
+ i_pic++) {
+ slice_param->RefPicList0[i_pic].picture_id = VA_INVALID_ID;
+ }
+
+ if (SLICE_TYPE_B == priv->cur_slice_type) {
+ slice_param->RefPicList1[0].picture_id =
+ GST_VAAPI_OBJECT_ID(priv->ref_surface2);
+ i_pic = 1;
+ } else
+ i_pic = 0;
+ for (;
+ i_pic < sizeof(slice_param->RefPicList1)/sizeof(slice_param->RefPicList1[0]);
+ i_pic++)
+ slice_param->RefPicList1[i_pic].picture_id = VA_INVALID_ID;
+
+ /* 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 = 0;
+ slice_param->disable_deblocking_filter_idc = 0;
+ slice_param->slice_alpha_c0_offset_div2 = 2;
+ slice_param->slice_beta_offset_div2 = 2;
+
+ }
+ ENCODER_ASSERT(last_row_num == (ENCODER_HEIGHT(encoder)+15)/16);
+ return TRUE;
+}
+
+#endif
+
+static gboolean
+h264_fill_sequence_buffer(GstVaapiEncoderH264 *encoder)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncSequenceParameterBufferH264 seq_param = { 0 };
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ /* only once */
+ if (VA_INVALID_ID != priv->seq_param_id)
+ return TRUE;
+
+ set_sequence_parameters(encoder, &seq_param);
+ va_status = vaCreateBuffer(va_dpy, context_id,
+ VAEncSequenceParameterBufferType,
+ sizeof(seq_param), 1,
+ &seq_param, &priv->seq_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "alloc seq-buffer failed.");
+
+#if !HAVE_OLD_H264_ENCODER
+ ensure_packed_sps_data(encoder, &seq_param);
+#endif
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_fill_picture_buffer(
+ GstVaapiEncoderH264 *encoder,
+ VABufferID coded_buf
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VAEncPictureParameterBufferH264 pic_param;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ VAAPI_UNUSED_ARG(va_status);
+ memset(&pic_param, 0, sizeof(pic_param));
+ set_picture_parameters(encoder, &pic_param, coded_buf);
+
+ if (VA_INVALID_ID != priv->pic_param_id) { /* share the same pic_param_id*/
+ vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPictureParameterBufferType,
+ sizeof(pic_param), 1,
+ &pic_param,
+ &priv->pic_param_id);
+
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "creating pic-param buffer failed.");
+#if !HAVE_OLD_H264_ENCODER
+ ensure_packed_pps_data(encoder, &pic_param);
+#endif
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_fill_slice_buffers(
+ GstVaapiEncoderH264 *encoder
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+ gboolean ret = TRUE;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ memset(priv->slice_param_buffers,
+ 0,
+ encoder->slice_num * sizeof(priv->slice_param_buffers[0]));
+ set_slices_parameters(encoder,
+ priv->slice_param_buffers,
+ encoder->slice_num);
+
+ if (VA_INVALID_ID != priv->slice_param_id) {
+ vaDestroyBuffer(va_dpy, priv->slice_param_id);
+ priv->slice_param_id = VA_INVALID_ID;
+ }
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncSliceParameterBufferType,
+ sizeof(priv->slice_param_buffers[0]),
+ encoder->slice_num,
+ priv->slice_param_buffers,
+ &priv->slice_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ FALSE,
+ "creating slice-parameters buffer failed.");
+
+end:
+ return ret;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_h264_rendering(
+ GstVaapiBaseEncoder *base,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key
+)
+{
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstVaapiDisplay *display = ENCODER_DISPLAY(base);
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+ VADisplay va_dpy;
+ VAContextID context_id;
+ VABufferID va_buffers[64];
+ guint32 va_buffers_count = 0;
+ gboolean is_params_ok = TRUE;
+ gboolean is_locked = FALSE;
+
+ ENCODER_ASSERT(context);
+
+ va_dpy = ENCODER_VA_DISPLAY(base);
+ context_id = ENCODER_VA_CONTEXT(base);
+
+ *is_key = (priv->cur_slice_type == SLICE_TYPE_I);
+
+ if (!priv->ref_surface1) {
+ priv->ref_surface1 = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface1,
+ ENCODER_SURFACE_ERR,
+ "reference surface, h264_pop_free_surface failed.");
+ }
+ if (!priv->ref_surface2) {
+ priv->ref_surface2 = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface2,
+ ENCODER_SURFACE_ERR,
+ "reference surface, h264_pop_free_surface failed.");
+ }
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface,
+ ENCODER_SURFACE_ERR,
+ "reconstructed surface, h264_pop_free_surface failed.");
+ }
+
+ if (SLICE_TYPE_P == priv->cur_slice_type) {
+ h264_swap_surface(&priv->ref_surface1, &priv->ref_surface2);
+ }
+
+ /* fill sequence parameters, need set every time */
+ is_params_ok = h264_fill_sequence_buffer(encoder);
+ ENCODER_CHECK_STATUS(is_params_ok,
+ ENCODER_PARAMETER_ERR,
+ "h264_recreate_seq_param failed");
+ /* set pic_parameters*/
+ is_params_ok = h264_fill_picture_buffer(encoder, coded_buf);
+ ENCODER_CHECK_STATUS(is_params_ok,
+ ENCODER_PARAMETER_ERR,
+ "h264_recreate_pic_param failed");
+ /* set slice parameters, support multiple slices */
+ is_params_ok = h264_fill_slice_buffers(encoder);
+ ENCODER_CHECK_STATUS(is_params_ok,
+ ENCODER_PARAMETER_ERR,
+ "h264_recreate_slice_param failed");
+
+ /* lock display */
+ ENCODER_ACQUIRE_DISPLAY_LOCK(display);
+
+ /*render all buffers*/
+ if (VA_INVALID_ID != priv->seq_param_id) {
+ #if HAVE_OLD_H264_ENCODER
+ if (!priv->is_seq_param_set) {
+ priv->is_seq_param_set = TRUE;
+ va_buffers[va_buffers_count++] = priv->seq_param_id;
+ }
+ #else
+ va_buffers[va_buffers_count++] = priv->seq_param_id;
+ #endif
+ }
+ if (VA_INVALID_ID != priv->pic_param_id) {
+ va_buffers[va_buffers_count++] = priv->pic_param_id;
+ }
+ if (VA_INVALID_ID != priv->slice_param_id) {
+ va_buffers[va_buffers_count++] = priv->slice_param_id;
+ }
+ if (SLICE_TYPE_I == priv->cur_slice_type) {
+ if (VA_INVALID_ID != priv->packed_seq_param_id) {
+ va_buffers[va_buffers_count++] = priv->packed_seq_param_id;
+ }
+ if (VA_INVALID_ID != priv->packed_seq_data_id) {
+ va_buffers[va_buffers_count++] = priv->packed_seq_data_id;
+ }
+ if (VA_INVALID_ID != priv->packed_pic_param_id) {
+ va_buffers[va_buffers_count++] = priv->packed_pic_param_id;
+ }
+ if (VA_INVALID_ID != priv->packed_pic_data_id) {
+ va_buffers[va_buffers_count++] = priv->packed_pic_data_id;
+ }
+ }
+
+ va_status = vaRenderPicture(va_dpy,
+ context_id,
+ va_buffers,
+ va_buffers_count);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_PICTURE_ERR,
+ "vaRenderH264Picture failed.");
+
+ /*after finished, swap recon and surface2*/
+ if (SLICE_TYPE_P == priv->cur_slice_type ||
+ SLICE_TYPE_I == priv->cur_slice_type) {
+ h264_swap_surface(&priv->recon_surface, &priv->ref_surface2);
+ }
+
+ end:
+ ENCODER_RELEASE_DISPLAY_LOCK(display);
+ return ret;
+}
+
+static const guint8 *
+h264_next_nal(const guint8 *buffer, guint32 len, guint32 *nal_size)
+{
+ const guint8 *cur = buffer;
+ const guint8 *end = buffer + len;
+ const guint8 *nal_start = NULL;
+ guint32 flag = 0xFFFFFFFF;
+ guint32 nal_start_len = 0;
+
+ ENCODER_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 == 0x00000001) {
+ *nal_size = cur - 4 - nal_start;
+ break;
+ } else if ((flag&0x00FFFFFF) == 0x00000001) {
+ *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 GstBuffer *
+gst_vaapi_encoder_h264_copy_coded_buffer(
+ GstVaapiBaseEncoder *base,
+ guint8 *frame,
+ guint32 frame_size,
+ VABufferID *coded_buf
+)
+{
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstBuffer *ret_buffer;
+ guint32 nal_size;
+ const guint8 *nal_start;
+ guint8 *frame_end;
+
+ ret_buffer = gst_buffer_new();
+ ENCODER_ASSERT(ret_buffer);
+ H264Bitstream bitstream;
+ h264_bitstream_init(&bitstream, (frame_size+32)*8);
+ h264_bitstream_align(&bitstream, 0);
+ ENCODER_ASSERT(bitstream.bit_size == 0);
+
+ if (!priv->avc_flag) { /*nal format*/
+ h264_bitstream_write_byte_array(&bitstream, frame, frame_size);
+ ENCODER_ASSERT(bitstream.bit_size == frame_size*8);
+ } else { /* elementary format */
+ frame_end = frame + frame_size;
+ nal_start = frame;
+ nal_size = 0;
+ while(NULL !=
+ (nal_start = h264_next_nal(nal_start, frame_end-nal_start, &nal_size))
+ ) {
+ ENCODER_ASSERT(nal_size);
+ if (!nal_size) {
+ nal_start += nal_size;
+ continue;
+ }
+ h264_bitstream_write_uint(&bitstream, nal_size, 32);
+ h264_bitstream_write_byte_array(&bitstream, nal_start, nal_size);
+ nal_start += nal_size;
+ }
+ }
+ h264_bitstream_align(&bitstream, 0);
+
+ GST_BUFFER_MALLOCDATA(ret_buffer) =
+ GST_BUFFER_DATA(ret_buffer) = BIT_STREAM_BUFFER(&bitstream);
+ GST_BUFFER_SIZE(ret_buffer) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
+ h264_bitstream_destroy(&bitstream, FALSE);
+
+ return ret_buffer;
+}
+
+static EncoderStatus
+read_sps_pps(GstVaapiEncoderH264Private *priv, const guint8 *buf, guint32 size)
+{
+ const guint8 *end = buf + size;
+ const guint8 *nal_start = buf;
+ guint32 nal_size = 0;
+ guint8 nal_type;
+ GstBuffer *sps = NULL, *pps = NULL;
+
+ while((!sps || !pps) &&
+ (nal_start = h264_next_nal(nal_start, end-nal_start, &nal_size)) != NULL
+ ) {
+ if (!nal_size) {
+ nal_start += nal_size;
+ continue;
+ }
+
+ nal_type = (*nal_start)&0x1F;
+ switch (nal_type) {
+ case NAL_SPS: {
+ sps = gst_buffer_new_and_alloc(nal_size);
+ memcpy(GST_BUFFER_DATA(sps), nal_start, nal_size);
+ gst_buffer_replace(&priv->sps_data, sps);
+ gst_buffer_unref(sps); /*don't set to NULL*/
+ break;
+ }
+
+ case NAL_PPS: {
+ pps = gst_buffer_new_and_alloc(nal_size);
+ memcpy(GST_BUFFER_DATA(pps), nal_start, nal_size);
+ gst_buffer_replace(&priv->pps_data, pps);
+ gst_buffer_unref(pps);
+ break;
+ }
+
+ default:
+ break;
+ }
+ nal_start += nal_size;
+ }
+
+ if (!sps || !pps) {
+ return ENCODER_DATA_NOT_READY;
+ }
+
+ return ENCODER_NO_ERROR;
+}
+
+static void
+gst_vaapi_encoder_h264_notify_frame(
+ GstVaapiBaseEncoder *base,
+ guint8 *buf,
+ guint32 size
+)
+{
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ if (!priv->sps_data || !priv->pps_data) {
+ read_sps_pps(priv, buf, size);
+ }
+ if (priv->sps_data && priv->pps_data) {
+ gst_vaapi_base_encoder_set_frame_notify(base, FALSE);
+ }
+}
+
+static gboolean
+read_sps_attributes(
+ const guint8 *sps_data,
+ guint32 sps_size,
+ guint32 *profile_idc,
+ guint32 *profile_comp,
+ guint32 *level_idc
+)
+{
+ ENCODER_ASSERT(profile_idc && profile_comp && level_idc);
+ ENCODER_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 EncoderStatus
+gst_vaapi_encoder_h264_flush(
+ GstVaapiEncoder* base,
+ GList **coded_pics
+)
+{
+ GstVaapiEncoderH264* encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ EncoderStatus ret = ENCODER_NO_ERROR;
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ //priv->frame_count = 0;
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->gop_count = g_queue_get_length(priv->queued_buffers);
+ //gst_vaapi_base_encoder_set_frame_notify((GST_VAAPI_BASE_ENCODER)encoder, TRUE);
+
+ //end:
+ return ret;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_h264_get_avcC_codec_data(
+ GstVaapiEncoderH264 *encoder,
+ GstBuffer **buffer
+)
+{
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+ GstBuffer *avc_codec;
+ const guint32 configuration_version = 0x01;
+ const guint32 length_size_minus_one = 0x03;
+ guint32 profile, profile_comp, level_idc;
+
+ ENCODER_ASSERT(buffer);
+ if (!priv->sps_data || !priv->pps_data) {
+ return ENCODER_DATA_NOT_READY;
+ }
+
+ if (FALSE == read_sps_attributes(GST_BUFFER_DATA(priv->sps_data),
+ GST_BUFFER_SIZE(priv->sps_data),
+ &profile, &profile_comp, &level_idc))
+ {
+ ENCODER_ASSERT(0);
+ return ENCODER_DATA_ERR;
+ }
+
+ H264Bitstream bitstream;
+ h264_bitstream_init(&bitstream,
+ (GST_BUFFER_SIZE(priv->sps_data) +
+ GST_BUFFER_SIZE(priv->pps_data) + 32)*8);
+
+ /*codec_data*/
+ h264_bitstream_write_uint(&bitstream, configuration_version, 8);
+ h264_bitstream_write_uint(&bitstream, profile, 8);
+ h264_bitstream_write_uint(&bitstream, profile_comp, 8);
+ h264_bitstream_write_uint(&bitstream, level_idc, 8);
+ h264_bitstream_write_uint(&bitstream, h264_bit_mask[6], 6); /*111111*/
+ h264_bitstream_write_uint(&bitstream, length_size_minus_one, 2);
+ h264_bitstream_write_uint(&bitstream, h264_bit_mask[3], 3); /*111*/
+
+ /*write sps*/
+ h264_bitstream_write_uint(&bitstream, 1, 5); /* sps count = 1*/
+ ENCODER_ASSERT( BIT_STREAM_BIT_SIZE(&bitstream)%8 == 0);
+ h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(priv->sps_data), 16);
+ h264_bitstream_write_byte_array(&bitstream,
+ GST_BUFFER_DATA(priv->sps_data),
+ GST_BUFFER_SIZE(priv->sps_data));
+
+ /*write pps*/
+ h264_bitstream_write_uint(&bitstream, 1, 8); /*pps count = 1*/
+ h264_bitstream_write_uint(&bitstream, GST_BUFFER_SIZE(priv->pps_data), 16);
+ h264_bitstream_write_byte_array(&bitstream,
+ GST_BUFFER_DATA(priv->pps_data),
+ GST_BUFFER_SIZE(priv->pps_data));
+
+ avc_codec = gst_buffer_new();
+ GST_BUFFER_MALLOCDATA(avc_codec) =
+ GST_BUFFER_DATA(avc_codec) =
+ BIT_STREAM_BUFFER(&bitstream);
+ GST_BUFFER_SIZE(avc_codec) = BIT_STREAM_BIT_SIZE(&bitstream)/8;
+ h264_bitstream_destroy(&bitstream, FALSE);
+ *buffer = avc_codec;
+
+ return ENCODER_NO_ERROR;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_h264_get_codec_data(
+ GstVaapiEncoder* base,
+ GstBuffer **buffer)
+{
+ GstVaapiEncoderH264 *encoder = GST_VAAPI_ENCODER_H264_CAST(base);
+ GstVaapiEncoderH264Private *priv = encoder->priv;
+
+ if (priv->avc_flag)
+ return gst_vaapi_encoder_h264_get_avcC_codec_data(encoder, buffer);
+ return ENCODER_NO_DATA;
+}
+
+static void
+gst_vaapi_encoder_h264_init(GstVaapiEncoderH264 *encoder)
+{
+ GstVaapiEncoderH264Private *priv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(encoder);
+ ENCODER_ASSERT(priv);
+ priv->public = encoder;
+ encoder->priv = priv;
+
+ /* init public attributes */
+ gst_vaapi_encoder_h264_init_public_values(encoder);
+ gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
+
+ /* init private values*/
+ priv->format = GST_MAKE_FOURCC('N','V','1','2');
+ priv->avc_flag = FALSE;
+
+ priv->ref_surface1 = NULL;
+ priv->ref_surface2 = NULL;
+ priv->recon_surface = NULL;
+
+ priv->seq_param_id = VA_INVALID_ID;
+ priv->pic_param_id = VA_INVALID_ID;
+ priv->slice_param_id = VA_INVALID_ID;
+ priv->packed_seq_param_id = VA_INVALID_ID;
+ priv->packed_seq_data_id = VA_INVALID_ID;
+ priv->packed_pic_param_id = VA_INVALID_ID;
+ priv->packed_pic_data_id = VA_INVALID_ID;
+ priv->is_seq_param_set = FALSE;
+ priv->slice_param_buffers = NULL;
+ priv->default_slice_height = 0;
+ priv->slice_mod_mb_num = 0;
+
+ priv->sps_data = NULL;
+ priv->pps_data = NULL;
+
+ priv->queued_buffers = g_queue_new();
+ priv->gop_count = 0;
+ priv->cur_display_num = 0;
+ priv->cur_decode_num = 0;
+ priv->cur_slice_type = SLICE_TYPE_I;
+ priv->last_decode_time = 0LL;
+ priv->default_cts_offset = 0;
+
+ priv->max_frame_num = 0;
+ priv->max_pic_order_cnt = 0;
+ priv->idr_num = 0;
+}
+
+static void
+gst_vaapi_encoder_h264_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+ GstVaapiEncoderH264Private *priv = GST_VAAPI_ENCODER_H264_GET_PRIVATE(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+
+ if (priv->sps_data) {
+ gst_buffer_unref(priv->sps_data);
+ priv->sps_data = NULL;
+ }
+ if (priv->pps_data) {
+ gst_buffer_unref(priv->pps_data);
+ priv->pps_data = NULL;
+ }
+ if (priv->slice_param_buffers) {
+ g_free(priv->slice_param_buffers);
+ priv->slice_param_buffers = NULL;
+ }
+
+ if (priv->queued_buffers) {
+ ENCODER_ASSERT(g_queue_is_empty(priv->queued_buffers));
+ g_queue_free(priv->queued_buffers);
+ priv->queued_buffers = NULL;
+ }
+
+ G_OBJECT_CLASS(gst_vaapi_encoder_h264_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_h264_class_init(GstVaapiEncoderH264Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GstVaapiEncoderH264Private));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encoder_debug,
+ "gst_va_h264_encoder",
+ 0,
+ "gst_va_h264_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_h264_finalize;
+
+ base_class->validate_attributes = gst_vaapi_encoder_h264_validate_attributes;
+ base_class->pre_alloc_resource = gst_vaapi_encoder_h264_alloc_slices;
+ base_class->release_resource = gst_vaapi_encoder_h264_release_resource;
+ base_class->prepare_next_input_buffer =
+ gst_vaapi_encoder_h264_prepare_next_buffer;
+ base_class->render_frame = gst_vaapi_encoder_h264_rendering;
+ base_class->notify_frame = gst_vaapi_encoder_h264_notify_frame;
+ base_class->copy_coded_frame = gst_vaapi_encoder_h264_copy_coded_buffer;
+ base_class->encode_frame_failed = gst_vaapi_encoder_h264_frame_failed;
+
+ encoder_class->flush = gst_vaapi_encoder_h264_flush;
+ encoder_class->get_codec_data = gst_vaapi_encoder_h264_get_codec_data;
+}
+
+static void
+h264_bitstream_init(H264Bitstream *bitstream, guint32 bit_capability)
+{
+ bitstream->bit_size = 0;
+ bitstream->buffer = NULL;
+ bitstream->max_bit_capability = 0;
+ if (bit_capability) {
+ h264_bitstream_auto_grow(bitstream, bit_capability);
+ }
+}
+
+static gboolean
+h264_bitstream_write_uint(
+ H264Bitstream *bitstream,
+ guint32 value,
+ guint32 bit_size
+)
+{
+ gboolean ret = TRUE;
+ guint32 byte_pos, bit_offset;
+ guint8 *cur_byte;
+ guint32 fill_bits;
+
+ if(!bit_size) {
+ return TRUE;
+ }
+
+ VAAPI_UNUSED_ARG(ret);
+ ENCODER_CHECK_STATUS(h264_bitstream_auto_grow(bitstream, bit_size),
+ FALSE,
+ "h264_bitstream_auto_grow failed.");
+ byte_pos = (bitstream->bit_size>>3);
+ bit_offset = (bitstream->bit_size&0x07);
+ cur_byte = bitstream->buffer + byte_pos;
+ ENCODER_ASSERT(bit_offset < 8 &&
+ bitstream->bit_size <= bitstream->max_bit_capability);
+
+ while (bit_size) {
+ fill_bits = ((8-bit_offset) < bit_size ? (8-bit_offset) : bit_size);
+ bit_size -= fill_bits;
+ bitstream->bit_size += fill_bits;
+
+ *cur_byte |=
+ ((value>>bit_size) & h264_bit_mask[fill_bits])<<(8-bit_offset-fill_bits);
+ ++cur_byte;
+ bit_offset = 0;
+ }
+ ENCODER_ASSERT(cur_byte <=
+ (bitstream->buffer + bitstream->max_bit_capability/8));
+
+ end:
+ return ret;
+}
+
+static gboolean
+h264_bitstream_align(H264Bitstream *bitstream, guint32 value)
+{
+ guint32 bit_offset, bit_left;
+
+ bit_offset = (bitstream->bit_size&0x07);
+ if (!bit_offset) {
+ return TRUE;
+ }
+ bit_left = 8 - bit_offset;
+ if (value) value = h264_bit_mask[bit_left];
+ return h264_bitstream_write_uint(bitstream, value, bit_left);
+}
+
+
+static gboolean
+h264_bitstream_write_byte_array(
+ H264Bitstream *bitstream,
+ const guint8 *buf,
+ guint32 byte_size
+)
+{
+ gboolean ret = TRUE;
+ if (!byte_size) {
+ return 0;
+ }
+
+ VAAPI_UNUSED_ARG(ret);
+ ENCODER_CHECK_STATUS(h264_bitstream_auto_grow(bitstream, byte_size<<3),
+ FALSE,
+ "h264_bitstream_auto_grow failed.");
+ if (0 == (bitstream->bit_size&0x07)) {
+ memcpy(&bitstream->buffer[bitstream->bit_size>>3], buf, byte_size);
+ bitstream->bit_size += (byte_size<<3);
+ } else {
+ ENCODER_ASSERT(0);
+ while(byte_size) {
+ h264_bitstream_write_uint(bitstream, *buf, 8);
+ --byte_size;
+ ++buf;
+ }
+ }
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_bitstream_write_ue(H264Bitstream *bitstream, guint32 value)
+{
+ gboolean ret = TRUE;
+ guint32 size_in_bits = 0;
+ guint32 tmp_value = ++value;
+ while (tmp_value) {
+ ++size_in_bits;
+ tmp_value >>= 1;
+ }
+ ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, 0, size_in_bits-1),
+ FALSE,
+ "h264_bitstream_write_ue failed.");
+ ENCODER_CHECK_STATUS(h264_bitstream_write_uint(bitstream, value, size_in_bits),
+ FALSE,
+ "h264_bitstream_write_ue failed.");
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_bitstream_write_se(H264Bitstream *bitstream, gint32 value)
+{
+ gboolean ret = TRUE;
+ guint32 new_val;
+
+ if (value <= 0) {
+ new_val = -(value<<1);
+ } else {
+ new_val = (value<<1) - 1;
+ }
+
+ ENCODER_CHECK_STATUS(h264_bitstream_write_ue(bitstream, new_val),
+ FALSE,
+ "h264_bitstream_write_se failed.");
+
+end:
+ return ret;
+}
+
+static gboolean
+h264_bitstream_write_trailing_bits(H264Bitstream *bitstream)
+{
+ h264_bitstream_write_uint(bitstream, 1, 1);
+ h264_bitstream_align(bitstream, 0);
+ return TRUE;
+}
+
+static void
+h264_bitstream_destroy(H264Bitstream *bitstream, gboolean free_flag)
+{
+ if (bitstream->buffer && free_flag) {
+ free (bitstream->buffer);
+ }
+ bitstream->buffer = NULL;
+ bitstream->bit_size = 0;
+ bitstream->max_bit_capability = 0;
+}
+
+static gboolean
+h264_bitstream_auto_grow(H264Bitstream *bitstream, guint32 extra_bit_size)
+{
+ guint32 new_bit_size = extra_bit_size + bitstream->bit_size;
+ guint32 clear_pos;
+
+ ENCODER_ASSERT(bitstream->bit_size <= bitstream->max_bit_capability);
+ if (new_bit_size <= bitstream->max_bit_capability) {
+ return TRUE;
+ }
+
+ new_bit_size = ((new_bit_size + H264_BITSTREAM_ALLOC_ALIGN_MASK)
+ &(~H264_BITSTREAM_ALLOC_ALIGN_MASK));
+ ENCODER_ASSERT(new_bit_size%(H264_BITSTREAM_ALLOC_ALIGN_MASK+1) == 0);
+ clear_pos = ((bitstream->bit_size+7)>>3);
+ bitstream->buffer = realloc(bitstream->buffer, new_bit_size>>3);
+ memset(bitstream->buffer+clear_pos, 0, (new_bit_size>>3)-clear_pos);
+ bitstream->max_bit_capability = new_bit_size;
+ return TRUE;
+}
+
+static gboolean
+h264_bitstream_write_nal_header(
+ H264Bitstream *bitstream,
+ guint nal_ref_idc,
+ guint nal_unit_type
+)
+{
+ h264_bitstream_write_uint(bitstream, 0, 1);
+ h264_bitstream_write_uint(bitstream, nal_ref_idc, 2);
+ h264_bitstream_write_uint(bitstream, nal_unit_type, 5);
+ return TRUE;
+}
+
+#if !HAVE_OLD_H264_ENCODER
+
+static gboolean
+h264_bitstream_write_sps(
+ H264Bitstream *bitstream,
+ VAEncSequenceParameterBufferH264 *seq,
+ H264_Profile profile
+)
+{
+ guint32 constraint_set0_flag, constraint_set1_flag;
+ guint32 constraint_set2_flag, constraint_set3_flag;
+ guint32 gaps_in_frame_num_value_allowed_flag = 0; // ??
+
+ 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 == H264_PROFILE_BASELINE;
+ constraint_set1_flag = profile <= H264_PROFILE_MAIN;
+ constraint_set2_flag = 0;
+ constraint_set3_flag = 0;
+
+ /* profile_idc */
+ h264_bitstream_write_uint(bitstream, profile, 8);
+ /* constraint_set0_flag */
+ h264_bitstream_write_uint(bitstream, constraint_set0_flag, 1);
+ /* constraint_set1_flag */
+ h264_bitstream_write_uint(bitstream, constraint_set1_flag, 1);
+ /* constraint_set2_flag */
+ h264_bitstream_write_uint(bitstream, constraint_set2_flag, 1);
+ /* constraint_set3_flag */
+ h264_bitstream_write_uint(bitstream, constraint_set3_flag, 1);
+ /* reserved_zero_4bits */
+ h264_bitstream_write_uint(bitstream, 0, 4);
+ /* level_idc */
+ h264_bitstream_write_uint(bitstream, seq->level_idc, 8);
+ /* seq_parameter_set_id */
+ h264_bitstream_write_ue(bitstream, seq->seq_parameter_set_id);
+
+ if (profile >= H264_PROFILE_HIGH) {
+ /* for high profile */
+ ENCODER_ASSERT(0);
+ /* chroma_format_idc = 1, 4:2:0*/
+ h264_bitstream_write_ue(bitstream, seq->seq_fields.bits.chroma_format_idc);
+ if (3 == seq->seq_fields.bits.chroma_format_idc) {
+ h264_bitstream_write_uint(bitstream, residual_color_transform_flag, 1);
+ }
+ /* bit_depth_luma_minus8 */
+ h264_bitstream_write_ue(bitstream, seq->bit_depth_luma_minus8);
+ /* bit_depth_chroma_minus8 */
+ h264_bitstream_write_ue(bitstream, seq->bit_depth_chroma_minus8);
+ /* b_qpprime_y_zero_transform_bypass */
+ h264_bitstream_write_uint(bitstream, b_qpprime_y_zero_transform_bypass, 1);
+ ENCODER_ASSERT(seq->seq_fields.bits.seq_scaling_matrix_present_flag == 0);
+ /*seq_scaling_matrix_present_flag */
+ h264_bitstream_write_uint(bitstream,
+ 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++) {
+ h264_bitstream_write_uint(bitstream, seq->seq_fields.bits.seq_scaling_list_present_flag, 1);
+ if (seq->seq_fields.bits.seq_scaling_list_present_flag) {
+ ENCODER_ASSERT(0);
+ /* FIXME, need write scaling list if seq_scaling_matrix_present_flag ==1*/
+ }
+ }
+ }
+ #endif
+ }
+
+ /* log2_max_frame_num_minus4 */
+ h264_bitstream_write_ue(bitstream,
+ seq->seq_fields.bits.log2_max_frame_num_minus4);
+ /* pic_order_cnt_type */
+ h264_bitstream_write_ue(bitstream, 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 */
+ h264_bitstream_write_ue(bitstream,
+ seq->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);
+ } else if (seq->seq_fields.bits.pic_order_cnt_type == 1) {
+ ENCODER_ASSERT(0);
+ h264_bitstream_write_uint(bitstream,
+ seq->seq_fields.bits.delta_pic_order_always_zero_flag,
+ 1);
+ h264_bitstream_write_se(bitstream, seq->offset_for_non_ref_pic);
+ h264_bitstream_write_se(bitstream,
+ seq->offset_for_top_to_bottom_field);
+ h264_bitstream_write_ue(bitstream,
+ seq->num_ref_frames_in_pic_order_cnt_cycle);
+ for ( i = 0; i < seq->num_ref_frames_in_pic_order_cnt_cycle; i++) {
+ h264_bitstream_write_se(bitstream, seq->offset_for_ref_frame[i]);
+ }
+ }
+
+ /* num_ref_frames */
+ h264_bitstream_write_ue(bitstream, seq->max_num_ref_frames);
+ /* gaps_in_frame_num_value_allowed_flag */
+ h264_bitstream_write_uint(bitstream,
+ gaps_in_frame_num_value_allowed_flag,
+ 1);
+
+ /* pic_width_in_mbs_minus1 */
+ h264_bitstream_write_ue(bitstream, seq->picture_width_in_mbs - 1);
+ /* pic_height_in_map_units_minus1 */
+ h264_bitstream_write_ue(bitstream, pic_height_in_map_units - 1);
+ /* frame_mbs_only_flag */
+ h264_bitstream_write_uint(bitstream,
+ seq->seq_fields.bits.frame_mbs_only_flag,
+ 1);
+
+ if (!seq->seq_fields.bits.frame_mbs_only_flag) { //ONLY mbs
+ ENCODER_ASSERT(0);
+ h264_bitstream_write_uint(bitstream, mb_adaptive_frame_field, 1);
+ }
+
+ /* direct_8x8_inference_flag */
+ h264_bitstream_write_uint(bitstream, 0, 1);
+ /* frame_cropping_flag */
+ h264_bitstream_write_uint(bitstream, seq->frame_cropping_flag, 1);
+
+ if (seq->frame_cropping_flag) {
+ /* frame_crop_left_offset */
+ h264_bitstream_write_ue(bitstream, seq->frame_crop_left_offset);
+ /* frame_crop_right_offset */
+ h264_bitstream_write_ue(bitstream, seq->frame_crop_right_offset);
+ /* frame_crop_top_offset */
+ h264_bitstream_write_ue(bitstream, seq->frame_crop_top_offset);
+ /* frame_crop_bottom_offset */
+ h264_bitstream_write_ue(bitstream, seq->frame_crop_bottom_offset);
+ }
+ ENCODER_ASSERT(seq->vui_parameters_present_flag == FALSE);
+
+ /* vui_parameters_present_flag */
+ h264_bitstream_write_uint(bitstream, seq->vui_parameters_present_flag, 1);
+ if (seq->vui_parameters_present_flag) {
+ /*FIXME, to write vui parameters*/
+ }
+ /* rbsp_trailing_bits */
+ h264_bitstream_write_trailing_bits(bitstream);
+ return TRUE;
+}
+
+static gboolean
+h264_bitstream_write_pps(
+ H264Bitstream *bitstream,
+ 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 */
+ h264_bitstream_write_ue(bitstream, pic->pic_parameter_set_id);
+ /* seq_parameter_set_id */
+ h264_bitstream_write_ue(bitstream, pic->seq_parameter_set_id);
+ /* entropy_coding_mode_flag */
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.entropy_coding_mode_flag,
+ 1);
+ /* pic_order_present_flag */
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.pic_order_present_flag,
+ 1);
+ /*slice_groups-1*/
+ h264_bitstream_write_ue(bitstream, num_slice_groups_minus1);
+
+ if (num_slice_groups_minus1 > 0) {
+ /*FIXME*/
+ ENCODER_ASSERT(0);
+ }
+ h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l0_active_minus1);
+ h264_bitstream_write_ue(bitstream, pic->num_ref_idx_l1_active_minus1);
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.weighted_pred_flag,
+ 1);
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.weighted_bipred_idc,
+ 2);
+ /* pic_init_qp_minus26 */
+ h264_bitstream_write_se(bitstream, pic->pic_init_qp-26);
+ /* pic_init_qs_minus26 */
+ h264_bitstream_write_se(bitstream, pic_init_qs_minus26);
+ /*chroma_qp_index_offset*/
+ h264_bitstream_write_se(bitstream, pic->chroma_qp_index_offset);
+
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.deblocking_filter_control_present_flag,
+ 1);
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.constrained_intra_pred_flag,
+ 1);
+ h264_bitstream_write_uint(bitstream, redundant_pic_cnt_present_flag, 1);
+
+ /*more_rbsp_data*/
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.transform_8x8_mode_flag,
+ 1);
+ h264_bitstream_write_uint(bitstream,
+ pic->pic_fields.bits.pic_scaling_matrix_present_flag,
+ 1);
+ if (pic->pic_fields.bits.pic_scaling_matrix_present_flag) {
+ ENCODER_ASSERT(0);
+ /* FIXME */
+ /*
+ for (i = 0; i <
+ (6+(-( (chroma_format_idc ! = 3) ? 2 : 6) * -pic->pic_fields.bits.transform_8x8_mode_flag));
+ i++) {
+ h264_bitstream_write_uint(bitstream, pic->pic_fields.bits.pic_scaling_list_present_flag, 1);
+ }
+ */
+ }
+
+ h264_bitstream_write_se(bitstream, pic->second_chroma_qp_index_offset);
+ h264_bitstream_write_trailing_bits(bitstream);
+ return TRUE;
+}
+#endif
--- /dev/null
+/*
+ * gstvaapiencoder_h264.h - H.264 encoder
+ *
+ * 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_ENCODER_H264_H
+#define GST_VAAPI_ENCODER_H264_H
+
+#include "gst/vaapi/gstvaapisurfacepool.h"
+#include "gst/vaapi/gstvaapibaseencoder.h"
+
+G_BEGIN_DECLS
+
+typedef struct _GstVaapiEncoderH264 GstVaapiEncoderH264;
+typedef struct _GstVaapiEncoderH264Private GstVaapiEncoderH264Private;
+typedef struct _GstVaapiEncoderH264Class GstVaapiEncoderH264Class;
+
+#define GST_TYPE_VAAPI_ENCODER_H264 \
+ (gst_vaapi_encoder_h264_get_type())
+
+#define GST_IS_VAAPI_ENCODER_H264(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODER_H264))
+
+#define GST_IS_VAAPI_ENCODER_H264_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODER_H264))
+
+#define GST_VAAPI_ENCODER_H264_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODER_H264, \
+ GstVaapiEncoderH264Class))
+
+#define GST_VAAPI_ENCODER_H264(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODER_H264, \
+ GstVaapiEncoderH264))
+
+#define GST_VAAPI_ENCODER_H264_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODER_H264, \
+ GstVaapiEncoderH264Class))
+
+#define GST_VAAPI_ENCODER_H264_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_TYPE_VAAPI_ENCODER_H264, \
+ GstVaapiEncoderH264Private))
+
+typedef enum {
+ H264_PROFILE_BASELINE = 66,
+ H264_PROFILE_MAIN = 77,
+ H264_PROFILE_EXTENDED = 88,
+ H264_PROFILE_HIGH = 100,
+ H264_PROFILE_HIGH10 = 110,
+ H264_PROFILE_HIGH422 = 122,
+ H264_PROFILE_HIGH444 = 144,
+ H264_PROFILE_HIGH444_PREDICTIVE = 244,
+} H264_Profile;
+
+typedef enum {
+ H264_LEVEL_10 = 10, /* QCIF format, < 380160 samples/sec */
+ H264_LEVEL_11 = 11, /* CIF format, < 768000 samples/sec */
+ H264_LEVEL_12 = 12, /* CIF format, < 1536000 samples/sec */
+ H264_LEVEL_13 = 13, /* CIF format, < 3041280 samples/sec */
+ H264_LEVEL_20 = 20, /* CIF format, < 3041280 samples/sec */
+ H264_LEVEL_21 = 21, /* HHR format, < 5068800 samples/sec */
+ H264_LEVEL_22 = 22, /* SD/4CIF format, < 5184000 samples/sec */
+ H264_LEVEL_30 = 30, /* SD/4CIF format, < 10368000 samples/sec */
+ H264_LEVEL_31 = 31, /* 720pHD format, < 27648000 samples/sec */
+ H264_LEVEL_32 = 32, /* SXGA format, < 55296000 samples/sec */
+ H264_LEVEL_40 = 40, /* 2Kx1K format, < 62914560 samples/sec */
+ H264_LEVEL_41 = 41, /* 2Kx1K format, < 62914560 samples/sec */
+ H264_LEVEL_42 = 42, /* 2Kx1K format, < 125829120 samples/sec */
+ H264_LEVEL_50 = 50, /* 3672x1536 format, < 150994944 samples/sec */
+ H264_LEVEL_51 = 51, /* 4096x2304 format, < 251658240 samples/sec */
+} H264_Level;
+
+#define H264_DEFAULT_PROFILE H264_PROFILE_BASELINE
+#define H264_DEFAULT_LEVEL H264_LEVEL_30
+#define H264_DEFAULT_INIT_QP 24
+#define H264_DEFAULT_MIN_QP 1
+#define H264_DEFAULT_INTRA_PERIOD 30
+#define H264_DEFAULT_FPS 30
+#define H264_DEFAULT_SLICE_NUM 1
+
+struct _GstVaapiEncoderH264 {
+ GstVaapiBaseEncoder parent; /*based on gobject*/
+
+ GstVaapiEncoderH264Private *priv;
+
+ guint32 profile;
+ guint32 level;
+ guint32 bitrate;
+ guint32 intra_period;
+ guint32 init_qp; /*default 24*/
+ guint32 min_qp; /*default 1*/
+ guint32 slice_num;
+ guint32 b_frame_num;
+};
+
+struct _GstVaapiEncoderH264Class {
+ GstVaapiBaseEncoderClass parent_class;
+};
+
+
+GType
+gst_vaapi_encoder_h264_get_type(void);
+
+GstVaapiEncoderH264 *
+gst_vaapi_encoder_h264_new(void);
+
+static inline void
+gst_vaapi_encoder_h264_unref (GstVaapiEncoderH264 * encoder)
+{
+ g_object_unref (encoder);
+}
+
+void
+gst_vaapi_encoder_h264_set_avc_flag(
+ GstVaapiEncoderH264* encoder,
+ gboolean avc
+);
+
+gboolean
+gst_vaapi_encoder_h264_get_avc_flag(GstVaapiEncoderH264* encoder);
+
+G_END_DECLS
+
+#endif /*GST_VAAPI_ENCODER_H264_H */
--- /dev/null
+/*
+ * gstvaapiencoder_mpeg4.c - MPEG-4 encoder
+ *
+ * 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 "gstvaapiencoder_mpeg4.h"
+
+#include <string.h>
+#include "gst/gstclock.h"
+
+#include "gstvaapiobject.h"
+#include "gstvaapiobject_priv.h"
+#include "gstvaapicontext.h"
+#include "gstvaapisurface.h"
+#include "gstvaapivideobuffer.h"
+#include "gstvaapidisplay_priv.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_mpeg4_encoder_debug);
+#define GST_CAT_DEFAULT gst_vaapi_mpeg4_encoder_debug
+
+#define GST_VAAPI_ENCODER_MPEG4_CAST(encoder) ((GstVaapiEncoderMpeg4 *)(encoder))
+
+#define VISUAL_OBJECT_SEQUENCE_START_CODE 0x000001B0
+#define VISUAL_OBJECT_SEQUENCE_END_CODE 0x000001B1
+#define VISUAL_OBJECT_START_CODE 0x000001B5
+#define VIDEO_OBJECT_PLANE_START_CODE 0x000001B6
+/* Video Object Start Code range */
+#define VIDEO_OBJECT_START_CODE_MIN 0x00000100
+#define VIDEO_OBJECT_START_CODE_MAX 0x0000011F
+/* Video Object Layer Start Code range 0x00000120 ~ 0x0000012F*/
+#define VIDEO_OBJECT_LAYER_START_CODE 0x00000120
+#define VIDEO_OBJECT_LAYER_START_CODE_MASK 0xFFFFFFF0
+
+
+struct _GstVaapiEncoderMpeg4Private {
+ GstVaapiSurface *ref_surface; /* reference buffer*/
+ GstVaapiSurface *recon_surface; /* reconstruct buffer*/
+
+ VABufferID seq_param_id;
+ VABufferID pic_param_id;
+ VABufferID slice_param_id;
+
+ GstBuffer *codec_data;
+};
+
+G_DEFINE_TYPE(GstVaapiEncoderMpeg4, gst_vaapi_encoder_mpeg4, GST_TYPE_VAAPI_BASE_ENCODER)
+
+GstVaapiEncoderMpeg4 *
+gst_vaapi_encoder_mpeg4_new(void)
+{
+ return GST_VAAPI_ENCODER_MPEG4_CAST(
+ g_object_new(GST_TYPE_VAAPI_ENCODER_MPEG4, NULL));
+}
+
+gboolean
+gst_vaapi_encoder_mpeg4_validate_attributes(
+ GstVaapiBaseEncoder *base
+)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+
+ if (!ENCODER_WIDTH(encoder) ||
+ !ENCODER_HEIGHT(encoder) ||
+ !ENCODER_FPS(encoder)) {
+ return FALSE;
+ }
+ if (VAProfileMPEG4Simple != encoder->profile &&
+ VAProfileMPEG4AdvancedSimple != encoder->profile) {
+ return FALSE;
+ }
+ gst_vaapi_base_encoder_set_va_profile(base, encoder->profile);
+
+ if (!encoder->intra_period) {
+ encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
+ }
+ if (-1 == encoder->init_qp) {
+ encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
+ }
+ if (-1 == encoder->min_qp) {
+ encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
+ }
+
+ /* default compress ratio 1: (4*8*1.5) */
+ if (!encoder->bitrate) {
+ encoder->bitrate =
+ ENCODER_WIDTH(encoder)*ENCODER_HEIGHT(encoder)*ENCODER_FPS(encoder)/4;
+ }
+ return TRUE;
+
+}
+
+static void
+mpeg4_release_parameters(
+ GstVaapiEncoderMpeg4 *encoder
+)
+{
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ VADisplay va_dpy = ENCODER_DISPLAY(encoder);
+ VAStatus va_status = VA_STATUS_SUCCESS;
+
+ VAAPI_UNUSED_ARG(va_status);
+
+ if (VA_INVALID_ID != priv->seq_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->seq_param_id);
+ priv->seq_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->pic_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+ if (VA_INVALID_ID != priv->slice_param_id) {
+ va_status = vaDestroyBuffer(va_dpy, priv->slice_param_id);
+ priv->slice_param_id = VA_INVALID_ID;
+ }
+}
+
+static gboolean
+gst_vaapi_encoder_mpeg4_release_resource(
+ GstVaapiBaseEncoder* base
+)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+
+ mpeg4_release_parameters(encoder);
+
+ /*remove ref_surface*/
+ if (priv->ref_surface) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->ref_surface);
+ } else {
+ g_object_unref(priv->ref_surface);
+ }
+ priv->ref_surface = NULL;
+ }
+
+ /*remove recon_surface*/
+ if (priv->recon_surface) {
+ if (context) {
+ gst_vaapi_context_put_surface(context, priv->recon_surface);
+ } else {
+ g_object_unref(priv->recon_surface);
+ }
+ priv->recon_surface = NULL;
+ }
+
+ if (priv->codec_data) {
+ gst_buffer_unref(priv->codec_data);
+ priv->codec_data = NULL;
+ }
+
+ return TRUE;
+}
+
+static guint32
+mpeg4_get_profile_level_indication(guint32 profile)
+{
+ switch(profile) {
+ case VAProfileMPEG4Simple:
+ return MPEG4_DEFAULT_SIMPLE_PROFILE_AND_LEVEL;
+ case VAProfileMPEG4AdvancedSimple:
+ return MPEG4_DEFAULT_ADVANCED_SIMPLE_PROFILE_AND_LEVEL;
+ default:
+ return 0;
+ }
+ return 0;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_rendering(
+ GstVaapiBaseEncoder *base,
+ GstVaapiSurface *surface,
+ guint frame_index,
+ VABufferID coded_buf,
+ gboolean *is_key
+)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ GstVaapiContext *context = ENCODER_CONTEXT(base);
+ VADisplay va_dpy = ENCODER_VA_DISPLAY(encoder);
+ VAContextID context_id = ENCODER_VA_CONTEXT(encoder);
+
+ VAStatus va_status = VA_STATUS_SUCCESS;
+ EncoderStatus ret = ENCODER_NO_ERROR;
+
+ *is_key = (frame_index % encoder->intra_period == 0);
+
+ /* initialize sequence parameter set, only first time */
+ if (VA_INVALID_ID == priv->seq_param_id) { /*only the first time*/
+ VAEncSequenceParameterBufferMPEG4 seq_param = {0};
+
+ seq_param.profile_and_level_indication =
+ mpeg4_get_profile_level_indication(encoder->profile);
+ seq_param.intra_period = encoder->intra_period;
+ seq_param.video_object_layer_width = ENCODER_WIDTH(encoder);
+ seq_param.video_object_layer_height = ENCODER_HEIGHT(encoder);
+ seq_param.vop_time_increment_resolution = ENCODER_FPS(encoder);
+ seq_param.fixed_vop_rate = MPEG4_DEFAULT_FIXED_VOP_RATE;
+ if (seq_param.fixed_vop_rate) {
+ seq_param.fixed_vop_time_increment = 1;
+ }
+ seq_param.bits_per_second = encoder->bitrate;
+ seq_param.frame_rate = ENCODER_FPS(encoder);
+ seq_param.initial_qp = encoder->init_qp;
+ seq_param.min_qp = encoder->min_qp; //mpeg4_encoder->min_qp;
+
+ va_status = vaCreateBuffer(va_dpy, context_id,
+ VAEncSequenceParameterBufferType,
+ sizeof(seq_param), 1,
+ &seq_param,
+ &priv->seq_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_ENC_RES_ERR,
+ "mpeg4 alloc seq-buffer failed.");
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->seq_param_id, 1);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_PICTURE_ERR,
+ "mpeg4 vaRenderPicture seq-parameters failed.");
+ }
+
+ /* set reference and reconstructed surfaces */
+ if (!priv->ref_surface) {
+ priv->ref_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->ref_surface,
+ ENCODER_SURFACE_ERR,
+ "mpeg4 reference surface, mpeg4_pop_free_surface failed.");
+ }
+ if (!priv->recon_surface) {
+ priv->recon_surface = gst_vaapi_context_get_surface(context);
+ ENCODER_CHECK_STATUS(priv->recon_surface,
+ ENCODER_SURFACE_ERR,
+ "mpeg4 reconstructed surface, mpeg4_pop_free_surface failed.");
+ }
+
+ /* initialize picture, every time, every frame */
+ VAEncPictureParameterBufferMPEG4 pic_param = {0};
+ pic_param.reference_picture = GST_VAAPI_OBJECT_ID(priv->ref_surface);
+ pic_param.reconstructed_picture = GST_VAAPI_OBJECT_ID(priv->recon_surface);
+ pic_param.coded_buf = coded_buf;
+ pic_param.picture_width = ENCODER_WIDTH(encoder);
+ pic_param.picture_height = ENCODER_HEIGHT(encoder);
+ if (0 == frame_index) {
+ pic_param.modulo_time_base = 0;
+ } else {
+ pic_param.modulo_time_base =
+ ((frame_index%ENCODER_FPS(encoder)) == 0 ? 1 : 0);
+ }
+ pic_param.vop_time_increment = 301%ENCODER_FPS(encoder);
+ pic_param.picture_type =
+ (*is_key ? VAEncPictureTypeIntra : VAEncPictureTypePredictive);
+
+ if (VA_INVALID_ID != priv->pic_param_id) { /* destroy first*/
+ va_status = vaDestroyBuffer(va_dpy, priv->pic_param_id);
+ priv->pic_param_id = VA_INVALID_ID;
+ }
+
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncPictureParameterBufferType,
+ sizeof(pic_param), 1,
+ &pic_param,
+ &priv->pic_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_ENC_RES_ERR,
+ "mpeg4 creating pic-param buffer failed.");
+
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->pic_param_id, 1);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS ==va_status,
+ ENCODER_PICTURE_ERR,
+ "mpeg4 rendering pic-param buffer failed.");
+
+ /*initialize slice parameters, only ONE slice for mpeg4*/
+ VAEncSliceParameterBuffer slice_param = { 0 };
+ slice_param.start_row_number = 0;
+ slice_param.slice_height = (ENCODER_HEIGHT(encoder)+15)/16; /*MB?*/
+ slice_param.slice_flags.bits.is_intra = *is_key;
+ slice_param.slice_flags.bits.disable_deblocking_filter_idc = 0;
+ if (VA_INVALID_ID != priv->slice_param_id) {
+ vaDestroyBuffer(va_dpy, priv->slice_param_id);
+ priv->slice_param_id = VA_INVALID_ID;
+ }
+
+ va_status = vaCreateBuffer(va_dpy,
+ context_id,
+ VAEncSliceParameterBufferType,
+ sizeof(slice_param),
+ 1,
+ &slice_param,
+ &priv->slice_param_id);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_ENC_RES_ERR,
+ "mpeg4 creating slice-parameters buffer failed.");
+
+ va_status = vaRenderPicture(va_dpy, context_id, &priv->slice_param_id, 1);
+ ENCODER_CHECK_STATUS(VA_STATUS_SUCCESS == va_status,
+ ENCODER_PICTURE_ERR,
+ "mpeg4 rendering slice-parameters buffer failed.");
+
+ /*swap ref_surface and recon_surface */
+ GstVaapiSurface *swap = priv->ref_surface;
+ priv->ref_surface = priv->recon_surface;
+ priv->recon_surface = swap;
+
+end:
+ return ret;
+}
+
+#if 0
+static GstBuffer *
+gst_vaapi_encoder_mpeg4_copy_coded_buffer(GstVaapiBaseEncoder *encoder,
+ guint8 *frame, guint32 frame_size, VABufferID *coded_buf)
+
+{
+ /*process data*/
+ GstBuffer* buffer = gst_buffer_new_and_alloc(frame_size);
+ memcpy(GST_BUFFER_DATA(buffer), frame, frame_size);
+
+ #if 0
+ GstVaapiEncoderMpeg4 *mpeg4_encoder = GST_VAAPI_ENCODER_MPEG4_CAST(encoder);
+ if (mpeg4_encoder->profile == VAProfileMPEG4AdvancedSimple) {
+ guint8 *start_code = GST_BUFFER_DATA(buffer)+16; /*fix old issue of ASP in mrst platform*/
+ if (start_code[0] == 0x01 && start_code[1] == 0x20
+ && start_code[-1] == 0x00 && start_code[-2] == 0x00)
+ {
+ start_code[2] = 0x08;
+ }
+ }
+ #endif
+
+ return buffer;
+}
+#endif
+
+static gboolean
+find_video_object_configuration_info(
+ const guint8 *in_buffer,
+ guint32 in_size,
+ const guint8 **out_buffer,
+ guint32 *out_size
+)
+{
+ guint32 value = 0x00;
+ const guint8 *end = in_buffer + in_size;
+
+ while(in_buffer < end) {
+ value = ((value<<8)|(*in_buffer));
+ if (VISUAL_OBJECT_SEQUENCE_START_CODE == value) {
+ *out_buffer = in_buffer - 3;
+ ++in_buffer;
+ break;
+ }
+ ++in_buffer;
+ }
+ if (in_buffer >= end)
+ return FALSE;
+
+ while(in_buffer < end) {
+ value = ((value<<8)|(*in_buffer));
+ if (VIDEO_OBJECT_PLANE_START_CODE == value) {
+ *out_size = (in_buffer - 3 - *out_buffer);
+ return TRUE;
+ }
+ ++in_buffer;
+ }
+ return FALSE;
+}
+
+static gboolean
+mpeg4_encoder_generate_codec_data(
+ const guint8 *in_buffer,
+ guint32 in_size,
+ GstBuffer **out_buffer
+)
+{
+ const guint8 *codec_buffer = NULL;
+ guint32 codec_size = 0;
+ guint8 *visual_obj_seq_end = NULL;
+
+ if (!find_video_object_configuration_info(in_buffer,
+ in_size,
+ &codec_buffer,
+ &codec_size)
+ ) {
+ return FALSE;
+ }
+ ENCODER_ASSERT(codec_size);
+ *out_buffer = gst_buffer_new_and_alloc(codec_size+4);
+ memcpy(GST_BUFFER_DATA(*out_buffer), codec_buffer, codec_size);
+ visual_obj_seq_end = GST_BUFFER_DATA(*out_buffer) + codec_size;
+ visual_obj_seq_end[0] = (VISUAL_OBJECT_SEQUENCE_END_CODE>>24);
+ visual_obj_seq_end[1] = (VISUAL_OBJECT_SEQUENCE_END_CODE>>16);
+ visual_obj_seq_end[2] = (VISUAL_OBJECT_SEQUENCE_END_CODE>>8);
+ visual_obj_seq_end[3] = (guint8)VISUAL_OBJECT_SEQUENCE_END_CODE;
+ return TRUE;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_notify_frame(
+ GstVaapiBaseEncoder *base,
+ guint8 *buf,
+ guint32 size
+)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+ if (!priv->codec_data) {
+ if (!mpeg4_encoder_generate_codec_data(buf, size, &priv->codec_data)) {
+ ENCODER_LOG_ERROR("mpeg4 encoder coded data error,"
+ "please check <mpeg4_encoder_generate_codec_data>.");
+ }
+ }
+ if (priv->codec_data) {
+ gst_vaapi_base_encoder_set_frame_notify(base, FALSE);
+ }
+}
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_flush(
+ GstVaapiEncoder* base,
+ GList **coded_pics
+)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+
+ mpeg4_release_parameters(encoder);
+ return ENCODER_NO_ERROR;
+}
+
+static EncoderStatus
+gst_vaapi_encoder_mpeg4_get_codec_data(
+ GstVaapiEncoder *base,
+ GstBuffer **buffer
+)
+{
+ GstVaapiEncoderMpeg4 *encoder = GST_VAAPI_ENCODER_MPEG4_CAST(base);
+ GstVaapiEncoderMpeg4Private *priv = encoder->priv;
+
+ if (!priv->codec_data)
+ return ENCODER_DATA_NOT_READY;
+ *buffer = gst_buffer_ref(priv->codec_data);
+ return ENCODER_NO_ERROR;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_init(GstVaapiEncoderMpeg4 *encoder)
+{
+ GstVaapiEncoderMpeg4Private *priv = GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(encoder);
+ ENCODER_ASSERT(priv);
+ encoder->priv = priv;
+
+ /* init public */
+ encoder->profile = VAProfileMPEG4Simple;
+ encoder->bitrate = 0;
+ encoder->intra_period = MPEG4_DEFAULT_INTRA_PERIOD;
+ encoder->init_qp = MPEG4_DEFAULT_INIT_QP;
+ encoder->min_qp = MPEG4_DEFAULT_MIN_QP;
+
+ gst_vaapi_base_encoder_set_frame_notify(GST_VAAPI_BASE_ENCODER(encoder), TRUE);
+ /* init private */
+ priv->ref_surface = NULL;
+ priv->recon_surface = NULL;
+
+ priv->seq_param_id = VA_INVALID_ID;
+ priv->pic_param_id = VA_INVALID_ID;
+ priv->slice_param_id = VA_INVALID_ID;
+
+ priv->codec_data = NULL;
+}
+
+static void
+gst_vaapi_encoder_mpeg4_finalize(GObject *object)
+{
+ /*free private buffers*/
+ GstVaapiEncoder *encoder = GST_VAAPI_ENCODER(object);
+
+ if (gst_vaapi_encoder_get_state(encoder) != VAAPI_ENC_NULL) {
+ gst_vaapi_encoder_uninitialize(encoder);
+ }
+ G_OBJECT_CLASS(gst_vaapi_encoder_mpeg4_parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encoder_mpeg4_class_init(GstVaapiEncoderMpeg4Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncoderClass * const encoder_class = GST_VAAPI_ENCODER_CLASS(klass);
+ GstVaapiBaseEncoderClass * const base_class = GST_VAAPI_BASE_ENCODER_CLASS(klass);
+
+ g_type_class_add_private(klass, sizeof(GstVaapiEncoderMpeg4Private));
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_mpeg4_encoder_debug, "gst_va_mpeg4_encoder", 0,
+ "gst_va_mpeg4_encoder element");
+
+ object_class->finalize = gst_vaapi_encoder_mpeg4_finalize;
+
+ base_class->validate_attributes = gst_vaapi_encoder_mpeg4_validate_attributes;
+ base_class->pre_alloc_resource = NULL;
+ base_class->release_resource = gst_vaapi_encoder_mpeg4_release_resource;
+ base_class->render_frame = gst_vaapi_encoder_mpeg4_rendering;
+ base_class->notify_frame = gst_vaapi_encoder_mpeg4_notify_frame;
+ base_class->copy_coded_frame = NULL;
+
+ encoder_class->flush = gst_vaapi_encoder_mpeg4_flush;
+ encoder_class->get_codec_data = gst_vaapi_encoder_mpeg4_get_codec_data;
+}
--- /dev/null
+/*
+ * gstvaapiencoder_mpeg4.h - MPEG-4 encoder
+ *
+ * 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_ENCODER_MPEG4_H
+#define GST_VAAPI_ENCODER_MPEG4_H
+
+#include "gst/vaapi/gstvaapisurfacepool.h"
+#include "gst/vaapi/gstvaapibaseencoder.h"
+
+G_BEGIN_DECLS
+
+#define MPEG4_DEFAULT_INTRA_PERIOD 30
+#define MPEG4_DEFAULT_INIT_QP 15
+#define MPEG4_DEFAULT_MIN_QP 1
+#define MPEG4_DEFAULT_SIMPLE_PROFILE_AND_LEVEL 0x03
+#define MPEG4_DEFAULT_ADVANCED_SIMPLE_PROFILE_AND_LEVEL 0xF3
+
+#define MPEG4_DEFAULT_FIXED_VOP_RATE FALSE
+
+
+typedef struct _GstVaapiEncoderMpeg4 GstVaapiEncoderMpeg4;
+typedef struct _GstVaapiEncoderMpeg4Private GstVaapiEncoderMpeg4Private;
+typedef struct _GstVaapiEncoderMpeg4Class GstVaapiEncoderMpeg4Class;
+
+
+#define GST_TYPE_VAAPI_ENCODER_MPEG4 \
+ (gst_vaapi_encoder_mpeg4_get_type())
+
+#define GST_IS_VAAPI_ENCODER_MPEG4(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODER_MPEG4))
+
+#define GST_IS_VAAPI_ENCODER_MPEG4_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODER_MPEG4))
+
+#define GST_VAAPI_ENCODER_MPEG4_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODER_MPEG4, \
+ GstVaapiEncoderMpeg4Class))
+
+#define GST_VAAPI_ENCODER_MPEG4(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODER_MPEG4, \
+ GstVaapiEncoderMpeg4))
+
+#define GST_VAAPI_ENCODER_MPEG4_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODER_MPEG4, \
+ GstVaapiEncoderMpeg4Class))
+
+#define GST_VAAPI_ENCODER_MPEG4_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_TYPE_VAAPI_ENCODER_MPEG4, \
+ GstVaapiEncoderMpeg4Private))
+
+struct _GstVaapiEncoderMpeg4 {
+ GstVaapiBaseEncoder parent; /*based on gobject*/
+ VAProfile profile; /* VAProfileMPEG4Simple, VAProfileMPEG4AdvancedSimple */
+ guint32 bitrate;
+ guint32 intra_period;
+ guint32 init_qp; /*default 15, 1~31*/
+ guint32 min_qp; /*default 1, 1~31*/
+
+ GstVaapiEncoderMpeg4Private *priv;
+};
+
+struct _GstVaapiEncoderMpeg4Class {
+ GstVaapiBaseEncoderClass parent_class;
+};
+
+GType
+gst_vaapi_encoder_mpeg4_get_type(void);
+
+GstVaapiEncoderMpeg4 *
+gst_vaapi_encoder_mpeg4_new(void);
+
+static inline void
+gst_vaapi_encoder_mpeg4_unref (GstVaapiEncoderMpeg4 * encoder)
+{
+ g_object_unref (encoder);
+}
+
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODER_MPEG4_H */
--- /dev/null
+/*
+ * gstvaapiimage.c - VA image 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:gstvaapiimage
+ * @short_description: VA image abstraction
+ */
+
+#include "sysdeps.h"
+#include <string.h>
+#include "gst/gstutils.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapiimage.h"
+#include "gstvaapi_priv.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+G_DEFINE_TYPE(GstVaapiImage, gst_vaapi_image, GST_VAAPI_TYPE_OBJECT);
+
+#define GST_VAAPI_IMAGE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_VAAPI_TYPE_IMAGE, \
+ GstVaapiImagePrivate))
+
+struct _GstVaapiImagePrivate {
+ VAImage internal_image;
+ VAImage image;
+ guchar *image_data;
+ GstVaapiImageFormat internal_format;
+ 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
+};
+
+#define SWAP_UINT(a, b) do { \
+ guint v = a; \
+ a = b; \
+ b = v; \
+ } while (0)
+
+static gboolean
+_gst_vaapi_image_map(GstVaapiImage *image, GstVaapiImageRaw *raw_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','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'):
+ 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)
+{
+ GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
+ VAImageID image_id;
+ VAStatus status;
+
+ _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));
+
+ 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, GstVaapiImageFormat format)
+{
+ GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(image);
+ GstVaapiImagePrivate * const priv = image->priv;
+ const VAImageFormat *va_format;
+ VAStatus status;
+
+ 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(display);
+ status = vaCreateImage(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ (VAImageFormat *)va_format,
+ priv->width,
+ priv->height,
+ &priv->internal_image
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ 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_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 &&
+ priv->image.buf != VA_INVALID_ID);
+
+ 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;
+ image_id = priv->image.image_id;
+
+ 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;
+ }
+ }
+ 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;
+}
+
+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_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);
+}
+
+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->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));
+}
+
+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;
+}
+
+/**
+ * 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,
+ GstVaapiImageFormat format,
+ guint width,
+ 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);
+
+ 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
+ );
+ if (!image)
+ return NULL;
+
+ if (!image->priv->is_constructed) {
+ g_object_unref(image);
+ return NULL;
+ }
+ 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)
+{
+ 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,
+ "id", GST_VAAPI_ID(va_image->image_id),
+ "image", va_image,
+ NULL
+ );
+ if (!image)
+ return NULL;
+
+ if (!image->priv->is_constructed) {
+ g_object_unref(image);
+ return NULL;
+ }
+ return image;
+}
+
+/**
+ * gst_vaapi_image_get_id:
+ * @image: a #GstVaapiImage
+ *
+ * Returns the underlying VAImageID of the @image.
+ *
+ * Return value: the underlying VA image id
+ */
+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);
+}
+
+/**
+ * gst_vaapi_image_get_image:
+ * @image: a #GstVaapiImage
+ * @va_image: 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)
+{
+ 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;
+
+ 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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * gst_vaapi_image_get_size:
+ * @image: a #GstVaapiImage
+ * @pwidth: return location for the width, or %NULL
+ * @pheight: 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)
+{
+ g_return_if_fail(GST_VAAPI_IS_IMAGE(image));
+ g_return_if_fail(image->priv->is_constructed);
+
+ if (pwidth)
+ *pwidth = image->priv->width;
+
+ if (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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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);
+ g_return_val_if_fail(image->priv->is_constructed, FALSE);
+
+ 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)
+{
+ 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);
+}
+
+gboolean
+_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;
+
+ display = GST_VAAPI_OBJECT_DISPLAY(image);
+ if (!display)
+ return FALSE;
+
+ GST_VAAPI_DISPLAY_LOCK(display);
+ status = vaMapBuffer(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ image->priv->image.buf,
+ &image_data
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaMapBuffer()"))
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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)
+{
+ GstVaapiDisplay *display;
+ VAStatus status;
+
+ if (!_gst_vaapi_image_is_mapped(image))
+ return FALSE;
+
+ display = GST_VAAPI_OBJECT_DISPLAY(image);
+ if (!display)
+ return FALSE;
+
+ GST_VAAPI_DISPLAY_LOCK(display);
+ status = vaUnmapBuffer(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ image->priv->image.buf
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaUnmapBuffer()"))
+ return FALSE;
+
+ image->priv->image_data = NULL;
+ 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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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);
+
+ 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)
+{
+ 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];
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+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(
+ 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 += src_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_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
+ * @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
+ * @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.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_image_update_from_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(&src_image, buffer))
+ return FALSE;
+ if (src_image.format != priv->format)
+ return FALSE;
+ if (src_image.width != priv->width || src_image.height != priv->height)
+ return 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;
+}
+
+/**
+ * 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;
+}
+
+static void
+_yuv411_to_nv12(
+ const guint8 *y_src,
+ guint32 y_src_stride,
+ const guint8 *u_src,
+ guint32 u_src_stride,
+ const guint8 *v_src,
+ guint32 v_src_stride,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *uv_dest,
+ guint32 uv_dest_stride,
+ guint32 width,
+ guint32 height
+)
+{
+ guint32 row, column;
+ guint32 uv_height;
+
+ memcpy_pic(y_dest, y_dest_stride, y_src, y_src_stride, width, height);
+ uv_height = GST_ROUND_UP_2(height)/2;
+ for (row = 0; row < uv_height; row++) {
+ for (column = 0; column < width/2; column++) {
+ uv_dest[column*2] = u_src[column];
+ uv_dest[column*2+1] = v_src[column];
+ }
+ u_src += u_src_stride;
+ v_src += v_src_stride;
+ uv_dest += uv_dest_stride;
+ }
+}
+
+static void
+_nv12_to_yuv411(
+ const guint8 *y_src,
+ guint32 y_src_stride,
+ const guint8 *uv_src,
+ guint32 uv_src_stride,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *u_dest,
+ guint32 u_dest_stride,
+ guint8 *v_dest,
+ guint32 v_dest_stride,
+ guint32 width,
+ guint32 height
+)
+{
+ guint32 row, column;
+ guint32 uv_height;
+
+ memcpy_pic(y_dest, y_dest_stride, y_src, y_src_stride, width, height);
+ uv_height = GST_ROUND_UP_2(height)/2;
+ for (row = 0; row < uv_height; row++) {
+ for (column = 0; column < width/2; column++) {
+ u_dest[column] = uv_src[column*2];
+ v_dest[column] = uv_src[column*2+1];
+ }
+ uv_src += uv_src_stride;
+ u_dest += u_dest_stride;
+ v_dest += v_dest_stride;
+ }
+}
+
+static void
+_yuy2_to_yuv411(
+ const guint8 *yuv_src,
+ guint32 yuv_src_stride,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *u_dest,
+ guint32 u_dest_stride,
+ guint8 *v_dest,
+ guint32 v_dest_stride,
+ gboolean uv_interlaced,
+ guint32 width,
+ guint32 height
+)
+{
+ guint32 row, column;
+ const guint8 *yuv_next_src;
+ guint8 *y_next_dest;
+ guint32 interval;
+
+ interval = uv_interlaced ? 2 : 1;
+ for (row = 0; row < height/2; row++) {
+ yuv_next_src = yuv_src + yuv_src_stride;
+ y_next_dest = y_dest + y_dest_stride;
+ for (column = 0; column < width/2; column++) {
+ y_dest[column*2] = yuv_src[column*4];
+ y_dest[column*2+1] = yuv_src[column*4+2];
+ y_next_dest[column*2] = yuv_next_src[column*4];
+ y_next_dest[column*2+1] = yuv_next_src[column*4+2];
+ u_dest[column*interval] = ((yuv_src[column*4+1] + yuv_next_src[column*4+1])>>1);
+ v_dest[column*interval] = ((yuv_src[column*4+3] + yuv_next_src[column*4+3])>>1);
+ }
+ yuv_src = yuv_next_src + yuv_src_stride;
+ y_dest = y_next_dest + y_dest_stride;
+ u_dest += u_dest_stride;
+ v_dest += v_dest_stride;
+ }
+
+ /* odd line */
+ if (height%2) {
+ for (column = 0; column < width/2; column++) {
+ y_dest[column*2] = yuv_src[column*4];
+ y_dest[column*2+1] = yuv_src[column*4+2];
+ u_dest[column*interval] = yuv_src[column*4+1];
+ v_dest[column*interval] = yuv_src[column*4+3];
+ }
+ }
+
+}
+
+static gboolean
+_image_convert_to_nv12(
+ const guint8 *src,
+ guint32 width,
+ guint32 height,
+ guint32 src_format,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *uv_dest,
+ guint32 uv_dest_stride
+)
+{
+ const guint8 *y_src, *u_src, *v_src, *uv_src;
+ guint32 ystride, ustride, vstride, uv_stride;
+
+ switch (src_format) {
+ case GST_MAKE_FOURCC('N','V','1','2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ uv_src = src + ystride*GST_ROUND_UP_2(height);
+ uv_stride = ystride;
+ memcpy_pic(y_dest, y_dest_stride, y_src, ystride, width, height);
+ memcpy_pic(uv_dest, uv_dest_stride, uv_src, uv_stride,
+ width, GST_ROUND_UP_2(height)/2);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('I','4','2','0'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ u_src = src + ystride*GST_ROUND_UP_2(height);
+ ustride = GST_ROUND_UP_8(ystride)/2;
+ v_src = u_src + ustride*GST_ROUND_UP_2(height)/2;
+ vstride = GST_ROUND_UP_8(ystride)/2;
+
+ _yuv411_to_nv12(y_src, ystride, u_src, ustride, v_src, vstride,
+ y_dest, y_dest_stride,
+ uv_dest, uv_dest_stride,
+ width, height);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('Y','V','1','2'):{
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ v_src = src + ystride*GST_ROUND_UP_2(height);
+ vstride = GST_ROUND_UP_8(ystride)/2;
+ u_src = v_src + vstride*GST_ROUND_UP_2(height)/2;
+ ustride = GST_ROUND_UP_8(ystride)/2;
+
+ _yuv411_to_nv12(y_src, ystride, u_src, ustride, v_src, vstride,
+ y_dest, y_dest_stride, uv_dest, uv_dest_stride,
+ width, height);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_2(width)*2;
+ _yuy2_to_yuv411(y_src, ystride,
+ y_dest, y_dest_stride,
+ uv_dest, uv_dest_stride,
+ uv_dest+1, uv_dest_stride,
+ TRUE,
+ width, height);
+ break;
+ }
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static gboolean
+_image_convert_to_yuv411(
+ const guint8 *src,
+ guint32 width,
+ guint32 height,
+ guint32 src_format,
+ guint8 *y_dest,
+ guint32 y_dest_stride,
+ guint8 *u_dest,
+ guint32 u_dest_stride,
+ guint8 *v_dest,
+ guint32 v_dest_stride
+)
+{
+ const guint8 *y_src, *u_src, *v_src, *uv_src;
+ guint32 ystride, ustride, vstride, uv_stride;
+
+ switch (src_format) {
+ case GST_MAKE_FOURCC('N','V','1','2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ uv_src = src + ystride*GST_ROUND_UP_2(height);
+ uv_stride = ystride;
+ _nv12_to_yuv411(y_src, ystride, uv_src, uv_stride,
+ y_dest, y_dest_stride,
+ u_dest, u_dest_stride,
+ v_dest, v_dest_stride,
+ width, height);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('I','4','2','0'):
+ case GST_MAKE_FOURCC('Y','V','1','2'):{
+ y_src = src;
+ ystride = GST_ROUND_UP_4(width);
+ if (GST_MAKE_FOURCC('I','4','2','0') == src_format) {
+ u_src = src + ystride*GST_ROUND_UP_2(height);
+ ustride = GST_ROUND_UP_8(ystride)/2;
+ v_src = u_src + ustride*GST_ROUND_UP_2(height)/2;
+ vstride = GST_ROUND_UP_8(ystride)/2;
+ } else {
+ v_src = src + ystride*GST_ROUND_UP_2(height);
+ vstride = GST_ROUND_UP_8(ystride)/2;
+ u_src = v_src + vstride*GST_ROUND_UP_2(height)/2;
+ ustride = GST_ROUND_UP_8(ystride)/2;
+ }
+
+ memcpy_pic(y_dest, y_dest_stride, y_src, ystride, width, height);
+ memcpy_pic(u_dest, u_dest_stride, u_src, ustride, width/2, GST_ROUND_UP_2(height)/2);
+ memcpy_pic(v_dest, v_dest_stride, v_src, vstride, width/2, GST_ROUND_UP_2(height)/2);
+ break;
+ }
+
+ case GST_MAKE_FOURCC('Y', 'U', 'Y', '2'): {
+ y_src = src;
+ ystride = GST_ROUND_UP_2(width)*2;
+ _yuy2_to_yuv411(y_src, ystride,
+ y_dest, y_dest_stride,
+ u_dest, u_dest_stride,
+ v_dest, v_dest_stride,
+ FALSE,
+ width, height);
+ break;
+ }
+
+ default:
+ return FALSE;
+ }
+ return TRUE;
+}
+
+
+gboolean
+gst_vaapi_convert_buffer_to_image(
+ GstVaapiImage *image,
+ GstBuffer *inbuf
+ )
+{
+ GstVaapiImagePrivate *priv;
+ guint width, height;
+ GstVaapiImageFormat image_format;
+ gboolean success = TRUE;
+ GstCaps *buffer_caps;
+ GstStructure *structure;
+ guint32 in_format = 0;
+
+ priv = image->priv;
+ gst_vaapi_image_get_size(image, &width, &height);
+ image_format = gst_vaapi_image_get_format(image);
+
+ /* get buffer format */
+ buffer_caps = GST_BUFFER_CAPS(inbuf);
+ if (!buffer_caps)
+ return FALSE;
+ structure = gst_caps_get_structure(buffer_caps, 0);
+ if (!structure)
+ return FALSE;
+ if (!gst_structure_get_fourcc(structure, "format", &in_format))
+ return FALSE;
+
+ /* currently only support YUV convert */
+ if ( (in_format != GST_MAKE_FOURCC('N','V','1','2')
+ && in_format != GST_MAKE_FOURCC('Y','V','1','2')
+ && in_format != GST_MAKE_FOURCC('I','4','2','0')
+ && in_format != GST_MAKE_FOURCC('Y', 'U', 'Y', '2'))
+ || (image_format != GST_VAAPI_IMAGE_NV12
+ && image_format != GST_VAAPI_IMAGE_YV12
+ && image_format != GST_VAAPI_IMAGE_I420)
+ )
+ {
+ return FALSE;
+ }
+
+
+ gst_vaapi_image_map(image);
+ switch (image_format) {
+ case GST_VAAPI_IMAGE_NV12: {
+ g_assert(priv->image.num_planes == 2);
+ success = _image_convert_to_nv12(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data+priv->image.offsets[0],
+ priv->image.pitches[0],
+ priv->image_data+priv->image.offsets[1],
+ priv->image.pitches[1]);
+ break;
+ }
+
+ case GST_VAAPI_IMAGE_I420: {
+ g_assert(priv->image.num_planes == 3);
+ success = _image_convert_to_yuv411(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data+priv->image.offsets[0],
+ priv->image.pitches[0],
+ priv->image_data+priv->image.offsets[1],
+ priv->image.pitches[1],
+ priv->image_data+priv->image.offsets[2],
+ priv->image.pitches[2]);
+ break;
+ }
+ case GST_VAAPI_IMAGE_YV12:{
+ g_assert(priv->image.num_planes == 3);
+ success = _image_convert_to_yuv411(GST_BUFFER_DATA(inbuf),
+ width, height, in_format,
+ priv->image_data+priv->image.offsets[0],
+ priv->image.pitches[0],
+ priv->image_data+priv->image.offsets[2],
+ priv->image.pitches[2],
+ priv->image_data+priv->image.offsets[1],
+ priv->image.pitches[1]);
+ break;
+ }
+
+ default:
+ success = FALSE;
+ break;
+ }
+ gst_vaapi_image_unmap(image);
+
+ return success;
+}
+
--- /dev/null
+/*
+ * gstvaapiimage.h - VA image 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_H
+#define GST_VAAPI_IMAGE_H
+
+#include <gst/gstbuffer.h>
+#include <gst/vaapi/gstvaapiobject.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiimageformat.h>
+
+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, \
+ GstVaapiImageClass))
+
+/**
+ * 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;
+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:
+ *
+ * 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) G_GNUC_CONST;
+
+GstVaapiImage *
+gst_vaapi_image_new(
+ GstVaapiDisplay *display,
+ GstVaapiImageFormat format,
+ guint width,
+ guint height
+);
+
+GstVaapiImage *
+gst_vaapi_image_new_with_image(GstVaapiDisplay *display, VAImage *va_image);
+
+GstVaapiID
+gst_vaapi_image_get_id(GstVaapiImage *image);
+
+gboolean
+gst_vaapi_image_get_image(GstVaapiImage *image, VAImage *va_image);
+
+GstVaapiImageFormat
+gst_vaapi_image_get_format(GstVaapiImage *image);
+
+guint
+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);
+
+gboolean
+gst_vaapi_image_is_linear(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);
+
+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,
+ GstBuffer *buffer,
+ GstVaapiRectangle *rect
+);
+
+gboolean
+gst_vaapi_image_update_from_raw(
+ GstVaapiImage *image,
+ GstVaapiImageRaw *src_image,
+ GstVaapiRectangle *rect
+);
+
+gboolean
+gst_vaapi_convert_buffer_to_image(
+ GstVaapiImage *image,
+ GstBuffer *buffer);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_IMAGE_H */
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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 <gst/video/video.h>
+#include "gstvaapicompat.h"
+#include "gstvaapiimageformat.h"
+
+typedef enum _GstVaapiImageFormatType GstVaapiImageFormatType;
+typedef struct _GstVaapiImageFormatMap GstVaapiImageFormatMap;
+
+enum _GstVaapiImageFormatType {
+ GST_VAAPI_IMAGE_FORMAT_TYPE_YCBCR = 1, /* YUV */
+ GST_VAAPI_IMAGE_FORMAT_TYPE_RGB, /* RGB */
+ GST_VAAPI_IMAGE_FORMAT_TYPE_INDEXED /* paletted */
+};
+
+struct _GstVaapiImageFormatMap {
+ GstVaapiImageFormatType type;
+ GstVaapiImageFormat format;
+ const char *caps_str;
+ VAImageFormat va_format;
+};
+
+#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_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_##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)
+{
+ 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;
+}
+
+/**
+ * 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;
+}
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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 <gst/gstvalue.h>
+#include <gst/video/video.h>
+
+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_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.
+ */
+enum _GstVaapiImageFormat {
+ 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
+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_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 */
--- /dev/null
+/*
+ * gstvaapiimagepool.c - Gst VA image pool
+ *
+ * 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:gstvaapiimagepool
+ * @short_description: VA image pool
+ */
+
+#include "sysdeps.h"
+#include "gstvaapiimagepool.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.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;
+}
+
+/**
+ * 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)
+{
+ return g_object_new(GST_VAAPI_TYPE_IMAGE_POOL,
+ "display", display,
+ "caps", caps,
+ NULL);
+}
--- /dev/null
+/*
+ * gstvaapiimagepool.h - Gst VA image pool
+ *
+ * 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_IMAGE_POOL_H
+#define GST_VAAPI_IMAGE_POOL_H
+
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/vaapi/gstvaapivideopool.h>
+
+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;
+
+/**
+ * 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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_IMAGE_POOL_H */
--- /dev/null
+/*
+ * gstvaapiobject.c - Base VA object
+ *
+ * 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:gstvaapiobject
+ * @short_description: Base VA object
+ */
+
+#include "sysdeps.h"
+#include "gstvaapiobject.h"
+#include "gstvaapi_priv.h"
+#include "gstvaapiparamspecs.h"
+#include "gstvaapivalue.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, };
+
+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)
+{
+ GstVaapiObjectPrivate * const priv = GST_VAAPI_OBJECT(object)->priv;
+
+ priv->id = GST_VAAPI_ID_NONE;
+
+ g_clear_object(&priv->display);
+
+ 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;
+ 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;
+ }
+}
+
+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;
+ 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;
+ }
+}
+
+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->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
+ );
+}
+
+static void
+gst_vaapi_object_init(GstVaapiObject *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_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;
+}
+
+/**
+ * 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
+ *
+ * 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), GST_VAAPI_ID_NONE);
+
+ return object->priv->id;
+}
--- /dev/null
+/*
+ * gstvaapiobject.h - Base VA object
+ *
+ * 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_OBJECT_H
+#define GST_VAAPI_OBJECT_H
+
+#include <gst/vaapi/gstvaapitypes.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+
+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))
+
+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:
+ * @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;
+
+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 */
--- /dev/null
+/*
+ * gstvaapiobject_priv.h - Base VA object (private definitions)
+ *
+ * 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_OBJECT_PRIV_H
+#define GST_VAAPI_OBJECT_PRIV_H
+
+#include <gst/vaapi/gstvaapiobject.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_CAST(object) ((GstVaapiObject *)(object))
+
+/**
+ * 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_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_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_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
+ * 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_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
+ *
+ * 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))
+
+/**
+ * GstVaapiObjectPrivate:
+ *
+ * VA object base.
+ */
+struct _GstVaapiObjectPrivate {
+ GstVaapiDisplay *display;
+ GstVaapiID id;
+ guint is_destroying : 1;
+};
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_OBJECT_PRIV_H */
--- /dev/null
+/*
+ * gstvaapiparamspecs.c - GParamSpecs for some of our types
+ *
+ * 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: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;
+}
--- /dev/null
+/*
+ * gstvaapiparamspecs.h - GParamSpecs for some of our types
+ *
+ * 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_PARAM_SPECS_H
+#define GST_VAAPI_PARAM_SPECS_H
+
+#include <gst/vaapi/gstvaapitypes.h>
+#include <glib-object.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapiprofile.c - VA profile abstraction
+ *
+ * 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:gstvaapiprofile
+ * @short_description: VA profile abstraction
+ */
+
+#include "sysdeps.h"
+#include <string.h>
+#include <gst/gstbuffer.h>
+#include "gstvaapicompat.h"
+#include "gstvaapiprofile.h"
+#include "gstvaapiworkarounds.h"
+
+typedef struct _GstVaapiProfileMap GstVaapiProfileMap;
+typedef struct _GstVaapiEntrypointMap GstVaapiEntrypointMap;
+
+struct _GstVaapiProfileMap {
+ GstVaapiProfile profile;
+ VAProfile va_profile;
+ const char *caps_str;
+ const gchar *profile_str;
+};
+
+struct _GstVaapiEntrypointMap {
+ GstVaapiEntrypoint entrypoint;
+ VAEntrypoint va_entrypoint;
+};
+
+/* 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"
+ },
+#if VA_CHECK_VERSION(0,30,0)
+ { 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_MAIN, VAProfileH264Main,
+ "video/x-h264", "main"
+ },
+ { GST_VAAPI_PROFILE_H264_HIGH, VAProfileH264High,
+ "video/x-h264", "high"
+ },
+ { 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=(fourcc)WVC1", "advanced"
+ },
+#if VA_CHECK_VERSION(0,32,0)
+ { GST_VAAPI_PROFILE_JPEG_BASELINE, VAProfileJPEGBaseline,
+ "image/jpeg", "baseline"
+ },
+#endif
+ { 0, }
+};
+
+/* Entry-points */
+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 },
+#endif
+ { 0, }
+};
+
+static const GstVaapiProfileMap *
+get_profiles_map(GstVaapiProfile profile)
+{
+ const GstVaapiProfileMap *m;
+
+ for (m = gst_vaapi_profiles; m->profile; m++)
+ if (m->profile == profile)
+ return m;
+ 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:
+ * @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 @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_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 */
+ guchar * 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
+ *
+ * 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 *profile_str;
+ GstVaapiProfile profile, best_profile;
+ GstBuffer *codec_data = NULL;
+ const gchar *name;
+ gsize namelen;
+
+ 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_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->caps_str, namelen) != 0)
+ continue;
+ 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;
+ }
+ 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;
+}
+
+/**
+ * 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_profiles_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 *m;
+ GstCaps *out_caps, *caps;
+
+ 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->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;
+}
+
+/**
+ * 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)
+{
+ 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;
+ case GST_VAAPI_PROFILE_JPEG_BASELINE:
+ codec = GST_VAAPI_CODEC_JPEG;
+ break;
+ default:
+ codec = (guint32)profile & GST_MAKE_FOURCC(0xff,0xff,0xff,0);
+ break;
+ }
+ return codec;
+}
+
+/**
+ * gst_vaapi_entrypoint:
+ * @entrypoint: 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;
+}
--- /dev/null
+/*
+ * gstvaapiprofile.h - VA profile abstraction
+ *
+ * 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_PROFILE_H
+#define GST_VAAPI_PROFILE_H
+
+#include <gst/gstvalue.h>
+
+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)
+ * @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_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.
+ */
+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_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_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_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:
+ * 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
+ * @GST_VAAPI_PROFILE_VC1_ADVANCED:
+ * VC-1 advanced profile
+ *
+ * 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),
+ 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),
+ GST_VAAPI_PROFILE_JPEG_BASELINE = GST_VAAPI_MAKE_PROFILE(JPEG,1),
+};
+
+/**
+ * GstVaapiEntrypoint:
+ * @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_SLICE_ENCODE
+};
+
+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);
+
+GstVaapiEntrypoint
+gst_vaapi_entrypoint(VAEntrypoint entrypoint);
+
+VAEntrypoint
+gst_vaapi_entrypoint_get_va_entrypoint(GstVaapiEntrypoint entrypoint);
+
+G_END_DECLS
+
+#endif /* GST_GST_VAAPI_IMAGE_H */
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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:gstvaapisubpicture
+ * @short_description: VA subpicture abstraction
+ */
+
+#include "sysdeps.h"
+#include <string.h>
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapisubpicture.h"
+#include "gstvaapi_priv.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+G_DEFINE_TYPE(GstVaapiSubpicture, gst_vaapi_subpicture, GST_VAAPI_TYPE_OBJECT);
+
+#define GST_VAAPI_SUBPICTURE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_VAAPI_TYPE_SUBPICTURE, \
+ GstVaapiSubpicturePrivate))
+
+struct _GstVaapiSubpicturePrivate {
+ GstVaapiImage *image;
+};
+
+enum {
+ PROP_0,
+
+ PROP_IMAGE
+};
+
+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;
+
+ 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;
+ }
+
+ g_clear_object(&priv->image);
+}
+
+static gboolean
+gst_vaapi_subpicture_create(GstVaapiSubpicture *subpicture)
+{
+ 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),
+ &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;
+ 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:
+ 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_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: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;
+}
+
+/**
+ * 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)
+{
+ 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)));
+
+ return g_object_new(GST_VAAPI_TYPE_SUBPICTURE,
+ "display", GST_VAAPI_OBJECT_DISPLAY(image),
+ "id", GST_VAAPI_ID(VA_INVALID_ID),
+ "image", 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
+ *
+ * Returns the underlying VASubpictureID of the @subpicture.
+ *
+ * Return value: the underlying VA subpicture id
+ */
+GstVaapiID
+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
+ *
+ * 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)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_SUBPICTURE(subpicture), NULL);
+
+ 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 and a new one is acquired on @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);
+}
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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
+#define GST_VAAPI_SUBPICTURE_H
+
+#include <gst/vaapi/gstvaapiobject.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/video/video-overlay-composition.h>
+
+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, \
+ GstVaapiSubpictureClass))
+
+typedef struct _GstVaapiSubpicture GstVaapiSubpicture;
+typedef struct _GstVaapiSubpicturePrivate GstVaapiSubpicturePrivate;
+typedef struct _GstVaapiSubpictureClass GstVaapiSubpictureClass;
+
+/**
+ * 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);
+
+GstVaapiSubpicture *
+gst_vaapi_subpicture_new_from_overlay_rectangle(
+ GstVaapiDisplay *display,
+ GstVideoOverlayRectangle *rect
+);
+
+GstVaapiID
+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 */
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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:gstvaapisurface
+ * @short_description: VA surface abstraction
+ */
+
+#include "sysdeps.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapisurface.h"
+#include "gstvaapisurface_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);
+
+#define GST_VAAPI_SURFACE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_VAAPI_TYPE_SURFACE, \
+ GstVaapiSurfacePrivate))
+
+struct _GstVaapiSurfacePrivate {
+ guint width;
+ guint height;
+ GstVaapiChromaType chroma_type;
+ GPtrArray *subpictures;
+ GstVaapiContext *parent_context;
+};
+
+enum {
+ PROP_0,
+
+ PROP_WIDTH,
+ PROP_HEIGHT,
+ PROP_CHROMA_TYPE,
+ PROP_PARENT_CONTEXT
+};
+
+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 surface)
+{
+ _gst_vaapi_surface_deassociate_subpicture(surface, subpicture);
+ g_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;
+ }
+}
+
+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);
+ 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)
+{
+ GstVaapiDisplay * const display = GST_VAAPI_OBJECT_DISPLAY(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;
+ }
+
+ GST_VAAPI_DISPLAY_LOCK(display);
+ status = vaCreateSurfaces(
+ GST_VAAPI_DISPLAY_VADISPLAY(display),
+ priv->width,
+ priv->height,
+ format,
+ 1, &surface_id
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaCreateSurfaces()"))
+ return FALSE;
+
+ 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;
+}
+
+/**
+ * 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,
+ GstVaapiChromaType chroma_type,
+ guint width,
+ guint height
+)
+{
+ 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);
+}
+
+/**
+ * gst_vaapi_surface_get_id:
+ * @surface: a #GstVaapiSurface
+ *
+ * Returns the underlying VASurfaceID of the @surface.
+ *
+ * Return value: the underlying VA surface id
+ */
+GstVaapiID
+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
+ *
+ * Returns the #GstVaapiChromaType the @surface was created with.
+ *
+ * Return value: the #GstVaapiChromaType
+ */
+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;
+}
+
+/**
+ * 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)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
+
+ 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)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 0);
+
+ return surface->priv->height;
+}
+
+/**
+ * gst_vaapi_surface_get_size:
+ * @surface: a #GstVaapiSurface
+ * @pwidth: return location for the width, or %NULL
+ * @pheight: 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
+)
+{
+ 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);
+}
+
+/**
+ * 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;
+
+ g_clear_object(&priv->parent_context);
+
+ 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
+ *
+ * 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)
+{
+ GstVaapiDisplay *display;
+ VAImage va_image;
+ VAStatus status;
+
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), NULL);
+
+ 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;
+
+ return gst_vaapi_image_new_with_image(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)
+{
+ GstVaapiDisplay *display;
+ 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);
+
+ display = GST_VAAPI_OBJECT_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;
+
+ 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;
+
+ 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)
+{
+ GstVaapiDisplay *display;
+ 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);
+
+ display = GST_VAAPI_OBJECT_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;
+
+ 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;
+
+ return TRUE;
+}
+
+/**
+ * gst_vaapi_surface_associate_subpicture:
+ * @surface: a #GstVaapiSurface
+ * @subpicture: a #GstVaapiSubpicture
+ * @src_rect: the sub-rectangle of the source subpicture
+ * image to extract and process. If %NULL, the entire image will be used.
+ * @dst_rect: 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. Note that the @surface holds an additional
+ * reference to the @subpicture.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_surface_associate_subpicture(
+ GstVaapiSurface *surface,
+ GstVaapiSubpicture *subpicture,
+ const GstVaapiRectangle *src_rect,
+ const GstVaapiRectangle *dst_rect
+)
+{
+ gboolean success;
+
+ 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)
+ 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,
+ 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_DISPLAY(surface);
+ if (!display)
+ 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;
+ 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(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,
+ 0
+ );
+ GST_VAAPI_DISPLAY_UNLOCK(display);
+ if (!vaapi_check_status(status, "vaAssociateSubpicture()"))
+ return FALSE;
+
+ 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
+)
+{
+ gboolean success;
+
+ 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 %" 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);
+ 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_DISPLAY(surface);
+ if (!display)
+ 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;
+
+ 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)
+{
+ GstVaapiDisplay *display;
+ VAStatus status;
+
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE(surface), 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;
+
+ 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;
+}
+
+/**
+ * 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
+ * method will clear existing subpictures.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+gst_vaapi_surface_set_subpictures_from_composition(
+ GstVaapiSurface *surface,
+ GstVideoOverlayComposition *composition,
+ gboolean propagate_context
+)
+{
+ GstVaapiDisplay *display;
+ guint n, nb_rectangles;
+
+ 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;
+
+ /* 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);
+ g_object_unref (subpicture);
+ return FALSE;
+ }
+ g_object_unref (subpicture);
+ }
+ return TRUE;
+}
--- /dev/null
+/*
+ * gstvaapisurface.h - 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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
+#define GST_VAAPI_SURFACE_H
+
+#include <gst/vaapi/gstvaapiobject.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/vaapi/gstvaapisubpicture.h>
+#include <gst/video/gstsurfacebuffer.h>
+#include <gst/video/video-overlay-composition.h>
+
+G_BEGIN_DECLS
+
+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 GST_VIDEO_CAPS_SURFACE
+
+/**
+ * GST_VAAPI_SURFACE_CAPS:
+ *
+ * Generic caps for VA surfaces.
+ */
+#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 ]"
+
+/**
+ * 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,
+ 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:
+ * 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())
+
+#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, \
+ GstVaapiSurfaceClass))
+
+typedef struct _GstVaapiSurface GstVaapiSurface;
+typedef struct _GstVaapiSurfacePrivate GstVaapiSurfacePrivate;
+typedef struct _GstVaapiSurfaceClass GstVaapiSurfaceClass;
+
+/**
+ * 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,
+ GstVaapiChromaType chroma_type,
+ guint width,
+ guint height
+);
+
+GstVaapiID
+gst_vaapi_surface_get_id(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);
+
+void
+gst_vaapi_surface_get_size(
+ GstVaapiSurface *surface,
+ guint *pwidth,
+ guint *pheight
+);
+
+GstVaapiImage *
+gst_vaapi_surface_derive_image(GstVaapiSurface *surface);
+
+gboolean
+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);
+
+gboolean
+gst_vaapi_surface_query_status(
+ GstVaapiSurface *surface,
+ GstVaapiSurfaceStatus *pstatus
+);
+
+gboolean
+gst_vaapi_surface_set_subpictures_from_composition(
+ GstVaapiSurface *surface,
+ GstVideoOverlayComposition *composition,
+ gboolean propagate_context
+);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_SURFACE_H */
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapicontext.h>
+#include <gst/vaapi/gstvaapisurface.h>
+
+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);
+
+#endif /* GST_VAAPI_SURFACE_PRIV_H */
--- /dev/null
+/*
+ * gstvaapisurfacepool.c - Gst VA surface pool
+ *
+ * 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:gstvaapisurfacepool
+ * @short_description: VA surface pool
+ */
+
+#include "sysdeps.h"
+#include "gstvaapisurfacepool.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+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), \
+ 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)
+{
+ GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_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->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
+ priv->width = width;
+ priv->height = height;
+}
+
+gpointer
+gst_vaapi_surface_pool_alloc_object(
+ GstVaapiVideoPool *pool,
+ GstVaapiDisplay *display
+)
+{
+ GstVaapiSurfacePoolPrivate *priv = GST_VAAPI_SURFACE_POOL(pool)->priv;
+
+ return gst_vaapi_surface_new(display,
+ priv->chroma_type,
+ priv->width,
+ priv->height);
+}
+
+static void
+gst_vaapi_surface_pool_finalize(GObject *object)
+{
+ G_OBJECT_CLASS(gst_vaapi_surface_pool_parent_class)->finalize(object);
+}
+
+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;
+}
+
+/**
+ * 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)
+{
+ return g_object_new(GST_VAAPI_TYPE_SURFACE_POOL,
+ "display", display,
+ "caps", caps,
+ NULL);
+}
--- /dev/null
+/*
+ * gstvaapisurfacepool.h - Gst VA surface pool
+ *
+ * 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_SURFACE_POOL_H
+#define GST_VAAPI_SURFACE_POOL_H
+
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapivideopool.h>
+
+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;
+
+/**
+ * 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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_SURFACE_POOL_H */
--- /dev/null
+/*
+ * gstvaapisurfaceproxy.c - VA surface proxy
+ *
+ * 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:gstvaapisurfaceproxy
+ * @short_description: VA surface proxy
+ */
+
+#include "sysdeps.h"
+#include "gstvaapisurfaceproxy.h"
+#include "gstvaapiobject_priv.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.h"
+
+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;
+ guint is_interlaced : 1;
+ guint tff : 1;
+};
+
+enum {
+ PROP_0,
+
+ PROP_CONTEXT,
+ PROP_SURFACE,
+ PROP_TIMESTAMP,
+ PROP_INTERLACED,
+ PROP_TFF
+};
+
+static void
+gst_vaapi_surface_proxy_finalize(GObject *object)
+{
+ 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_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_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_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;
+
+ priv = GST_VAAPI_SURFACE_PROXY_GET_PRIVATE(proxy);
+ proxy->priv = priv;
+ priv->context = NULL;
+ priv->surface = NULL;
+ priv->timestamp = GST_CLOCK_TIME_NONE;
+ priv->is_interlaced = FALSE;
+ priv->tff = FALSE;
+}
+
+/**
+ * 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->priv->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
+)
+{
+ GstVaapiSurfaceProxyPrivate *priv;
+
+ g_return_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy));
+
+ priv = proxy->priv;
+
+ g_clear_object(&priv->context);
+
+ if (context)
+ priv->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->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
+ * @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
+)
+{
+ 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 (surface)
+ 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;
+}
+
+/**
+ * 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
+ *
+ * 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->is_interlaced && 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;
+}
--- /dev/null
+/*
+ * gstvaapisurfaceproxy.h - VA surface proxy
+ *
+ * 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_H
+#define GST_VAAPI_SURFACE_PROXY_H
+
+#include <glib-object.h>
+#include <gst/vaapi/gstvaapicontext.h>
+#include <gst/vaapi/gstvaapisurface.h>
+
+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))
+
+/**
+ * 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)
+
+/**
+ * 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)
+
+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);
+
+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
+);
+
+GstClockTime
+gst_vaapi_surface_proxy_get_timestamp(GstVaapiSurfaceProxy *proxy);
+
+void
+gst_vaapi_surface_proxy_set_timestamp(
+ GstVaapiSurfaceProxy *proxy,
+ 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);
+
+void
+gst_vaapi_surface_proxy_set_tff(GstVaapiSurfaceProxy *proxy, gboolean tff);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_SURFACE_PROXY_H */
--- /dev/null
+/*
+ * gstvaapitexture.c - VA texture abstraction
+ *
+ * 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:gstvaapitexture
+ * @short_description: VA/GLX texture abstraction
+ */
+
+#include "sysdeps.h"
+#include "gstvaapitexture.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapiutils_glx.h"
+#include "gstvaapidisplay_glx.h"
+#include "gstvaapi_priv.h"
+#include "gstvaapidisplay_x11_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;
+ GLContextState *gl_context;
+ void *gl_surface;
+ GLPixmapObject *pixo;
+ GLFramebufferObject *fbo;
+ 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_objects(GstVaapiTexture *texture)
+{
+ GstVaapiTexturePrivate * const priv = texture->priv;
+
+#if USE_VAAPI_GLX
+ GST_VAAPI_OBJECT_LOCK_DISPLAY(texture);
+ if (priv->gl_surface) {
+ vaDestroySurfaceGLX(
+ GST_VAAPI_OBJECT_VADISPLAY(texture),
+ priv->gl_surface
+ );
+ priv->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 (priv->fbo) {
+ gl_destroy_framebuffer_object(priv->fbo);
+ priv->fbo = NULL;
+ }
+
+ if (priv->pixo) {
+ 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
+}
+
+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;
+ gboolean success = FALSE;
+
+#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);
+ success = vaapi_check_status(status, "vaCreateSurfaceGLX()");
+#else
+ 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),
+ 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);
+#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);
+ 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;
+ }
+
+ return _gst_vaapi_texture_create_objects(texture, texture_id);
+}
+
+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_context = NULL;
+ priv->gl_surface = NULL;
+ priv->pixo = NULL;
+ priv->fbo = NULL;
+ priv->foreign_texture = FALSE;
+ 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,
+ 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);
+}
+
+/**
+ * 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,
+ GLuint texture,
+ GLenum target,
+ GLenum format
+)
+{
+ guint width, height, border_width;
+ GLTextureState ts;
+ gboolean success;
+
+ g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
+
+ /* Check texture dimensions */
+ 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;
+ 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_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_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;
+ GLContextState old_cs;
+ 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;
+
+ GST_VAAPI_OBJECT_LOCK_DISPLAY(texture);
+ 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_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(priv->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, priv->height);
+ glTexCoord2f(1.0f, 1.0f); glVertex2i(priv->width, priv->height);
+ glTexCoord2f(1.0f, 0.0f); glVertex2i(priv->width, 0 );
+ }
+ glEnd();
+
+ success = gl_unbind_pixmap_object(priv->pixo);
+ if (!success) {
+ GST_DEBUG("could not release GLX pixmap");
+ goto out_unbind_fbo;
+ }
+
+out_unbind_fbo:
+ if (!gl_unbind_framebuffer_object(priv->fbo))
+ success = FALSE;
+out_reset_context:
+ if (priv->gl_context && !gl_set_current_context(&old_cs, NULL))
+ success = FALSE;
+end:
+ GST_VAAPI_OBJECT_UNLOCK_DISPLAY(texture);
+ return success;
+#endif
+ return TRUE;
+}
+
+gboolean
+gst_vaapi_texture_put_surface(
+ GstVaapiTexture *texture,
+ GstVaapiSurface *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(GST_VAAPI_IS_SURFACE(surface), FALSE);
+
+ return _gst_vaapi_texture_put_surface(texture, surface, flags);
+}
--- /dev/null
+/*
+ * gstvaapitexture.h - VA texture abstraction
+ *
+ * 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_TEXTURE_H
+#define GST_VAAPI_TEXTURE_H
+
+#include <GL/gl.h>
+#include <gst/vaapi/gstvaapitypes.h>
+#include <gst/vaapi/gstvaapiobject.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapisurface.h>
+
+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(
+ 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 */
--- /dev/null
+/*
+ * gstvaapitypes.h - Basic types
+ *
+ * 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_TYPES_H
+#define GST_VAAPI_TYPES_H
+
+#include <glib.h>
+
+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_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:
+ *
+ * Can be used together with #GST_VAAPI_ID_ARGS to properly output an
+ * integer value in a printf()-style text message.
+ * <informalexample>
+ * <programlisting>
+ * printf("id: %" GST_VAAPI_ID_FORMAT "\n", GST_VAAPI_ID_ARGS(id));
+ * </programlisting>
+ * </informalexample>
+ */
+#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)
+
+/**
+ * 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;
+};
+
+/**
+ * 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
+};
+
+/**
+ * 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 */
--- /dev/null
+/*
+ * gstvaapiutils.c - VA-API utilities
+ *
+ * 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 "sysdeps.h"
+#include "gstvaapicompat.h"
+#include "gstvaapiutils.h"
+#include "gstvaapisurface.h"
+#include <stdio.h>
+#include <stdarg.h>
+
+#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)
+{
+ 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)
+{
+ 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 */
+gboolean
+vaapi_create_buffer(
+ VADisplay dpy,
+ VAContextID ctx,
+ int type,
+ unsigned int size,
+ gconstpointer buf,
+ VABufferID *buf_id_ptr,
+ gpointer *mapped_data
+)
+{
+ 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;
+
+ if (mapped_data) {
+ data = vaapi_map_buffer(dpy, buf_id);
+ if (!data)
+ goto error;
+ *mapped_data = data;
+ }
+
+ *buf_id_ptr = buf_id;
+ return TRUE;
+
+error:
+ vaapi_destroy_buffer(dpy, &buf_id);
+ return FALSE;
+}
+
+/* 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)
+{
+ switch (profile) {
+#define MAP(profile) \
+ STRCASEP(VAProfile, profile)
+ MAP(MPEG2Simple);
+ MAP(MPEG2Main);
+ MAP(MPEG4Simple);
+ MAP(MPEG4AdvancedSimple);
+ MAP(MPEG4Main);
+#if VA_CHECK_VERSION(0,32,0)
+ MAP(JPEGBaseline);
+ MAP(H263Baseline);
+ MAP(H264ConstrainedBaseline);
+#endif
+ MAP(H264Baseline);
+ MAP(H264Main);
+ MAP(H264High);
+ MAP(VC1Simple);
+ MAP(VC1Main);
+ MAP(VC1Advanced);
+#undef MAP
+ default: break;
+ }
+ return "<unknown>";
+}
+
+/* Return a string representation of a VAEntrypoint */
+const char *string_of_VAEntrypoint(VAEntrypoint entrypoint)
+{
+ switch (entrypoint) {
+#define MAP(entrypoint) \
+ STRCASEP(VAEntrypoint, entrypoint)
+ MAP(VLD);
+ MAP(IZZ);
+ MAP(IDCT);
+ MAP(MoComp);
+ MAP(Deblocking);
+#undef MAP
+ default: break;
+ }
+ return "<unknown>";
+}
+
+/* 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 "<unknown>";
+}
+
+/**
+ * from_GstVaapiSurfaceRenderFlags:
+ * @flags: the #GstVaapiSurfaceRenderFlags
+ *
+ * Converts #GstVaapiSurfaceRenderFlags to flags suitable for
+ * vaPutSurface().
+ */
+guint
+from_GstVaapiSurfaceRenderFlags(guint flags)
+{
+ guint va_fields = 0, va_csc = 0;
+
+ 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;
+
+#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_csc = VA_SRC_BT709;
+#endif
+
+ 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_CHECK_VERSION(0,30,0)
+ if (va_flags & VASurfaceSkipped)
+ flags |= GST_VAAPI_SURFACE_STATUS_SKIPPED;
+#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;
+}
--- /dev/null
+/*
+ * gstvaapiutils.h - VA-API utilities
+ *
+ * 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_UTILS_H
+#define GST_VAAPI_UTILS_H
+
+#include "config.h"
+#include <glib.h>
+#include <va/va.h>
+
+/** Check VA status for success or print out an error */
+G_GNUC_INTERNAL
+gboolean
+vaapi_check_status(VAStatus status, const char *msg);
+
+/** Maps VA buffer */
+G_GNUC_INTERNAL
+void *
+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);
+
+/** 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
+);
+
+/** Destroy VA buffer */
+G_GNUC_INTERNAL
+void
+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);
+
+/** Return a string representation of a VAEntrypoint */
+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);
+
+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 */
--- /dev/null
+/*
+ * gstvaapiutils_glx.c - GLX utilties
+ *
+ * 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
+ */
+
+#define _GNU_SOURCE 1 /* RTLD_DEFAULT */
+#include "sysdeps.h"
+#include <string.h>
+#include <math.h>
+#include <dlfcn.h>
+#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
+ *
+ * Retrieves the string representation the OpenGL @error.
+ *
+ * Return error: the static string representing the OpenGL @error
+ */
+const char *
+gl_get_error_string(GLenum 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");
+#ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
+ MAP(GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "invalid framebuffer operation");
+#endif
+#undef MAP
+ default: break;
+ };
+ 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_texture_param:
+ * @target: the target to which the texture is bound
+ * @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 target, GLenum param, guint *pval)
+{
+ GLint val;
+
+ gl_purge_errors();
+ glGetTexLevelParameteriv(target, 0, param, &val);
+ if (gl_check_error())
+ return FALSE;
+
+ if (pval)
+ *pval = val;
+ 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
+ *
+ * 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_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
+gl_perspective(GLdouble fovy, GLdouble aspect, GLdouble near_val, GLdouble far_val)
+{
+ GLdouble left, right, top, bottom;
+
+ /* Source (Q 9.085):
+ <http://www.opengl.org/resources/faq/technical/transformations.htm> */
+ 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);
+}
+
+/**
+ * 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)
+{
+#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();
+ 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);
+}
+
+/**
+ * gl_create_context:
+ * @dpy: an X11 #Display
+ * @screen: the associated screen of @dpy
+ * @parent: the parent #GLContextState, or %NULL if none is to be used
+ *
+ * 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 *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
+ };
+
+ cs = malloc(sizeof(*cs));
+ if (!cs)
+ goto error;
+
+ 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;
+ }
+ 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;
+
+error:
+ gl_destroy_context(cs);
+ cs = NULL;
+end:
+ if (fbconfigs)
+ XFree(fbconfigs);
+ 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 @old_cs is non %NULL, the previously current GLX context and
+ * window are recorded.
+ *
+ * Return value: %TRUE on success
+ */
+gboolean
+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 (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);
+}
+
+/**
+ * gl_swap_buffers:
+ * @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(GLContextState *cs)
+{
+ glXSwapBuffers(cs->display, cs->window);
+ cs->swapped_buffers = TRUE;
+}
+
+/**
+ * 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)
+{
+ GLenum binding;
+
+ 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())
+ 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)
+{
+ GLenum internal_format;
+ GLuint texture;
+ GLTextureState ts;
+ guint 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:
+ internal_format = GL_RGBA;
+ 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,
+ internal_format,
+ width, height,
+ 0,
+ format,
+ GL_UNSIGNED_BYTE,
+ NULL
+ );
+ 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_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;
+ }
+
+ /* 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_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,
+ };
+
+ 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 = 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->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 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
+ *attr++ = GLX_TEXTURE_FORMAT_RGB_EXT;
+ *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;
+
+ 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: a #GLPixmapObject
+ *
+ * Destroys the #GLPixmapObject object.
+ */
+void
+gl_destroy_pixmap_object(GLPixmapObject *pixo)
+{
+ GLVTable * const gl_vtable = gl_get_vtable();
+
+ if (!pixo)
+ return;
+
+ gl_unbind_pixmap_object(pixo);
+
+ 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->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;
+
+ 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;
+}
+
+/**
+ * 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;
+ }
+
+ gl_unbind_texture(&pixo->old_texture);
+
+ 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;
+ GLenum status;
+
+ 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->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
+ );
+
+ 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: 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) {
+ 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);
+
+ 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;
+}
--- /dev/null
+/*
+ * gstvaapiutils_glx.h - GLX utilties
+ *
+ * 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_UTILS_GLX_H
+#define GST_VAAPI_UTILS_GLX_H
+
+#include "config.h"
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <GL/glx.h>
+#include <GL/glxext.h>
+#include <glib.h>
+
+#if GLX_GLXEXT_VERSION < 18
+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 <GL/glx.h> 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
+
+G_GNUC_INTERNAL
+const char *
+gl_get_error_string(GLenum error);
+
+G_GNUC_INTERNAL
+void
+gl_purge_errors(void);
+
+G_GNUC_INTERNAL
+gboolean
+gl_check_error(void);
+
+G_GNUC_INTERNAL
+gboolean
+gl_get_param(GLenum param, guint *pval);
+
+G_GNUC_INTERNAL
+gboolean
+gl_get_texture_param(GLenum target, GLenum param, guint *pval);
+
+G_GNUC_INTERNAL
+void
+gl_set_bgcolor(guint32 color);
+
+G_GNUC_INTERNAL
+void
+gl_resize(guint width, guint height);
+
+typedef struct _GLContextState GLContextState;
+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);
+
+G_GNUC_INTERNAL
+void
+gl_destroy_context(GLContextState *cs);
+
+G_GNUC_INTERNAL
+void
+gl_get_current_context(GLContextState *cs);
+
+G_GNUC_INTERNAL
+gboolean
+gl_set_current_context(GLContextState *new_cs, GLContextState *old_cs);
+
+G_GNUC_INTERNAL
+void
+gl_swap_buffers(GLContextState *cs);
+
+typedef struct _GLTextureState GLTextureState;
+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);
+
+G_GNUC_INTERNAL
+void
+gl_unbind_texture(GLTextureState *ts);
+
+G_GNUC_INTERNAL
+GLuint
+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;
+ 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
+GLVTable *
+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;
+};
+
+G_GNUC_INTERNAL
+GLPixmapObject *
+gl_create_pixmap_object(Display *dpy, guint width, guint height);
+
+G_GNUC_INTERNAL
+void
+gl_destroy_pixmap_object(GLPixmapObject *pixo);
+
+G_GNUC_INTERNAL
+gboolean
+gl_bind_pixmap_object(GLPixmapObject *pixo);
+
+G_GNUC_INTERNAL
+gboolean
+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;
+};
+
+G_GNUC_INTERNAL
+GLFramebufferObject *
+gl_create_framebuffer_object(
+ GLenum target,
+ GLuint texture,
+ guint width,
+ guint height
+);
+
+G_GNUC_INTERNAL
+void
+gl_destroy_framebuffer_object(GLFramebufferObject *fbo);
+
+G_GNUC_INTERNAL
+gboolean
+gl_bind_framebuffer_object(GLFramebufferObject *fbo);
+
+G_GNUC_INTERNAL
+gboolean
+gl_unbind_framebuffer_object(GLFramebufferObject *fbo);
+
+#endif /* GST_VAAPI_UTILS_GLX_H */
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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 <glib.h>
+#include <X11/Xutil.h>
+#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);
+
+/**
+ * x11_create_window:
+ * @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. 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)
+{
+ 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);
+
+ if (!vis)
+ vis = DefaultVisual(dpy, screen);
+
+ 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;
+
+ 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;
+
+ XSelectInput(dpy, win, x11_event_mask);
+ return win;
+}
+
+gboolean
+x11_get_geometry(
+ Display *dpy,
+ Drawable drawable,
+ gint *px,
+ gint *py,
+ guint *pwidth,
+ guint *pheight
+)
+{
+ 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;
+
+ if (px) *px = x;
+ if (py) *py = y;
+ if (pwidth) *pwidth = width;
+ if (pheight) *pheight = height;
+ return TRUE;
+}
--- /dev/null
+/*
+ * gstvaapiutils_x11.h - X11 utilties
+ *
+ * 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_UTILS_X11_H
+#define GST_VAAPI_UTILS_X11_H
+
+#include "config.h"
+#include <X11/Xlib.h>
+#include <glib.h>
+
+G_GNUC_INTERNAL
+void
+x11_trap_errors(void);
+
+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);
+
+G_GNUC_INTERNAL
+gboolean
+x11_get_geometry(
+ Display *dpy,
+ Drawable drawable,
+ gint *px,
+ gint *py,
+ guint *pwidth,
+ guint *pheight
+);
+
+#endif /* GST_VAAPI_UTILS_X11_H */
--- /dev/null
+/*
+ * gstvaapivalue.c - GValue implementations specific to VA-API
+ *
+ * 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:gstvaapivalue
+ * @short_description: GValue implementations specific to VA-API
+ */
+
+#include "sysdeps.h"
+#include <gobject/gvaluecollector.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)
+# 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
+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;
+}
+
+/* --- 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" },
+ { 0, NULL, NULL },
+ };
+
+ if (!g_type)
+ g_type = g_enum_register_static("GstVaapiRotation", rotation_values);
+ return g_type;
+}
--- /dev/null
+/*
+ * gstvaapivalue.h - GValue implementations specific to VA-API
+ *
+ * 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_VALUE_H
+#define GST_VAAPI_VALUE_H
+
+#include <glib-object.h>
+#include <gst/vaapi/gstvaapitypes.h>
+
+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:
+ *
+ * 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()
+
+/**
+ * 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;
+
+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;
+
+GType
+gst_vaapi_rotation_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_VALUE_H */
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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:gstvaapivideobuffer
+ * @short_description: VA video buffer for GStreamer
+ */
+
+#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);
+
+#define GST_VAAPI_VIDEO_BUFFER_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
+ GST_VAAPI_TYPE_VIDEO_BUFFER, \
+ GstVaapiVideoBufferPrivate))
+
+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)
+{
+ GstVaapiVideoBufferPrivate * const priv = buffer->priv;
+
+ g_clear_object(&priv->display);
+
+ 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;
+
+ g_clear_object(&priv->proxy);
+
+ 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);
+}
+
+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->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
+ *
+ * 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 *
+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_typed_new(type);
+ if (!buffer)
+ return NULL;
+
+ set_display(GST_VAAPI_VIDEO_BUFFER(buffer), display);
+ 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(GST_VAAPI_IS_SURFACE_PROXY(proxy), 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:
+ * @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
+ *
+ * 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(GST_VAAPI_IS_SURFACE_PROXY(proxy));
+
+ 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 = g_object_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;
+}
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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 <gst/video/gstsurfacebuffer.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapisurfaceproxy.h>
+#include <gst/vaapi/gstvaapivideopool.h>
+
+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;
+
+/**
+ * GstVaapiVideoBuffer:
+ *
+ * A #GstBuffer holding video objects (#GstVaapiSurface and #GstVaapiImage).
+ */
+struct _GstVaapiVideoBuffer {
+ /*< private >*/
+ GstSurfaceBuffer parent_instance;
+
+ GstVaapiVideoBufferPrivate *priv;
+};
+
+/**
+ * GstVaapiVideoBufferClass:
+ *
+ * A #GstBuffer holding video objects
+ */
+struct _GstVaapiVideoBufferClass {
+ /*< private >*/
+ GstSurfaceBufferClass parent_class;
+};
+
+GType
+gst_vaapi_video_buffer_get_type(void) G_GNUC_CONST;
+
+GstVaapiDisplay *
+gst_vaapi_video_buffer_get_display(GstVaapiVideoBuffer *buffer);
+
+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);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_VIDEO_BUFFER_H */
--- /dev/null
+/*
+ * gstvaapivideobuffer_glx.c - Gst VA video buffer
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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)
+{
+}
--- /dev/null
+/*
+ * gstvaapivideobuffer_glx.h - Gstreamer/VA video buffer
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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 <gst/vaapi/gstvaapidisplay_glx.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+#include <gst/vaapi/gstvaapivideopool.h>
+#include <gst/video/gstsurfacebuffer.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapivideobuffer_priv.h - Gstreamer/VA video buffer (private interface)
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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 <gst/vaapi/gstvaapivideobuffer.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapivideoconverter_glx.c - Gst VA video converter
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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 <string.h>
+#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)
+{
+ 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;
+ 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));
+
+ 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_buffer_get_render_flags (vbuffer));
+}
--- /dev/null
+/*
+ * gstvaapivideoconverter_glx.h - Gstreamer/VA video converter
+ *
+ * Copyright (C) 2011 Intel Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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 <gst/video/gstsurfaceconverter.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapivideopool.c - Video object pool abstraction
+ *
+ * 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:gstvaapivideopool
+ * @short_description: Video object pool abstraction
+ */
+
+#include "sysdeps.h"
+#include "gstvaapivideopool.h"
+
+#define DEBUG 1
+#include "gstvaapidebug.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))
+
+#define VAAPI_VIDEO_POOL_LOCK(mutex) g_static_rec_mutex_lock(mutex)
+#define VAAPI_VIDEO_POOL_UNLOCK(mutex) g_static_rec_mutex_unlock(mutex)
+
+
+struct _GstVaapiVideoPoolPrivate {
+ GstVaapiDisplay *display;
+ GQueue free_objects;
+ GList *used_objects;
+ GstCaps *caps;
+ guint used_count;
+ guint capacity;
+
+ GStaticRecMutex mutex;
+};
+
+enum {
+ PROP_0,
+
+ 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)
+{
+ 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;
+ }
+
+ g_clear_object(&priv->display);
+}
+
+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;
+ 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;
+ }
+}
+
+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, 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);
+ g_static_rec_mutex_init(&priv->mutex);
+}
+
+/**
+ * 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
+ *
+ * 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);
+}
+
+/**
+ * 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)
+{
+ GstVaapiVideoPoolPrivate *priv;
+ gpointer object = NULL;
+
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), NULL);
+
+ priv = pool->priv;
+
+ VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
+ if (priv->capacity && priv->used_count >= priv->capacity)
+ goto end;
+
+ object = g_queue_pop_head(&priv->free_objects);
+ if (!object) {
+ VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
+ object = gst_vaapi_video_pool_alloc_object(pool);
+ VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
+ if (!object)
+ goto end;
+ }
+
+ ++priv->used_count;
+ priv->used_objects = g_list_prepend(priv->used_objects, object);
+ g_object_ref(object);
+
+ end:
+ VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
+ return object;
+}
+
+/**
+ * gst_vaapi_video_pool_put_object:
+ * @pool: a #GstVaapiVideoPool
+ * @object: the object to add back to the pool
+ *
+ * Pushes the @object back into the pool. The @object shall be
+ * 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)
+{
+ 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;
+
+ VAAPI_VIDEO_POOL_LOCK(&priv->mutex);
+ elem = g_list_find(priv->used_objects, object);
+ if (!elem)
+ goto end;
+
+ 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);
+
+ end:
+ VAAPI_VIDEO_POOL_UNLOCK(&priv->mutex);
+}
+
+/**
+ * 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);
+
+ VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+ g_queue_push_tail(&pool->priv->free_objects, g_object_ref(object));
+ VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+
+ 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)
+{
+ guint size;
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
+
+
+ VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+ size = g_queue_get_length(&pool->priv->free_objects);
+ VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+ 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
+ */
+gboolean
+gst_vaapi_video_pool_reserve(GstVaapiVideoPool *pool, guint n)
+{
+ guint i, num_allocated;
+ gboolean ret = TRUE;
+
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
+
+ VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+
+ num_allocated = gst_vaapi_video_pool_get_size(pool) + pool->priv->used_count;
+ if (n < num_allocated)
+ goto end;
+
+ 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) {
+ ret = FALSE;
+ goto end;
+ }
+ g_queue_push_tail(&pool->priv->free_objects, object);
+ }
+ ret = TRUE;
+ end:
+ VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+ return ret;
+}
+
+/**
+ * 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)
+{
+ guint capacity;
+ g_return_val_if_fail(GST_VAAPI_IS_VIDEO_POOL(pool), 0);
+ VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+ capacity = pool->priv->capacity;
+ VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+ return 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));
+ VAAPI_VIDEO_POOL_LOCK(&pool->priv->mutex);
+ pool->priv->capacity = capacity;
+ VAAPI_VIDEO_POOL_UNLOCK(&pool->priv->mutex);
+}
--- /dev/null
+/*
+ * gstvaapivideopool.h - Video object pool abstraction
+ *
+ * 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_POOL_H
+#define GST_VAAPI_VIDEO_POOL_H
+
+#include <glib.h>
+#include <gst/gstcaps.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+
+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;
+
+/**
+ * GstVaapiVideoPool:
+ *
+ * A pool of lazily allocated video objects. e.g. surfaces, images.
+ */
+struct _GstVaapiVideoPool {
+ /*< private >*/
+ GObject parent_instance;
+
+ 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;
+
+ /*< 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;
+
+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);
+
+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 */
--- /dev/null
+/*
+ * gstvaapiwindow.c - VA window 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:gstvaapiwindow
+ * @short_description: VA window abstraction
+ */
+
+#include "sysdeps.h"
+#include "gstvaapiwindow.h"
+#include "gstvaapi_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
+};
+
+static void
+gst_vaapi_window_ensure_size(GstVaapiWindow *window)
+{
+ GstVaapiWindowPrivate * const priv = window->priv;
+ GstVaapiWindowClass * const klass = GST_VAAPI_WINDOW_GET_CLASS(window);
+
+ if (!priv->check_geometry)
+ return;
+
+ if (klass->get_geometry)
+ klass->get_geometry(window, NULL, NULL, &priv->width, &priv->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);
+}
+
+static gboolean
+gst_vaapi_window_create(GstVaapiWindow *window)
+{
+ 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
+ );
+
+ if (!GST_VAAPI_WINDOW_GET_CLASS(window)->create(window, &width, &height))
+ return FALSE;
+
+ 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
+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;
+ 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;
+ }
+}
+
+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;
+ 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;
+ }
+}
+
+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);
+
+ 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",
+ "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_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 GST_VAAPI_OBJECT_DISPLAY(window);
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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);
+}
+
+/**
+ * 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);
+
+ gst_vaapi_window_ensure_size(window);
+
+ return window->priv->is_fullscreen;
+}
+
+/**
+ * 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;
+ window->priv->check_geometry = TRUE;
+ }
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * 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)
+{
+ 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;
+}
+
+/**
+ * gst_vaapi_window_get_size:
+ * @window: a #GstVaapiWindow
+ * @pwidth: return location for the width, or %NULL
+ * @pheight: 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)
+{
+ 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;
+
+ if (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)
+{
+ g_return_if_fail(GST_VAAPI_IS_WINDOW(window));
+
+ 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)
+{
+ 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: 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)
+{
+ 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, 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;
+}
+
+static inline void
+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->width = width;
+ rect->height = height;
+}
+
+/**
+ * gst_vaapi_window_put_surface:
+ * @window: a #GstVaapiWindow
+ * @surface: a #GstVaapiSurface
+ * @src_rect: the sub-rectangle of the source surface to
+ * extract and process. If %NULL, the entire surface will be used.
+ * @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
+ *
+ * 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(
+ GstVaapiWindow *window,
+ GstVaapiSurface *surface,
+ const GstVaapiRectangle *src_rect,
+ const GstVaapiRectangle *dst_rect,
+ 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);
+ }
+
+ 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);
+}
--- /dev/null
+/*
+ * gstvaapiwindow.h - VA window abstraction
+ *
+ * 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_WINDOW_H
+#define GST_VAAPI_WINDOW_H
+
+#include <gst/video/gstvideosink.h>
+#include <gst/vaapi/gstvaapitypes.h>
+#include <gst/vaapi/gstvaapiobject.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapisurface.h>
+
+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_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;
+
+/**
+ * GstVaapiWindow:
+ *
+ * Base class for system-dependent windows.
+ */
+struct _GstVaapiWindow {
+ /*< private >*/
+ GstVaapiObject parent_instance;
+
+ 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
+ * @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;
+
+GstVaapiDisplay *
+gst_vaapi_window_get_display(GstVaapiWindow *window);
+
+void
+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);
+
+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,
+ const GstVaapiRectangle *src_rect,
+ const GstVaapiRectangle *dst_rect,
+ guint flags
+);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_WINDOW_H */
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiwindow.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapiwindow_glx.c - VA/GLX window abstraction
+ *
+ * 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:gstvaapiwindow_glx
+ * @short_description: VA/GLX window abstraction
+ */
+
+#include "sysdeps.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"
+
+#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 {
+ Colormap cmap;
+ GLContextState *gl_context;
+ guint is_constructed : 1;
+ guint foreign_window : 1;
+};
+
+enum {
+ PROP_0,
+
+ PROP_GLX_CONTEXT
+};
+
+/* 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 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 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,
+ 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;
+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;
+
+ 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(
+ GstVaapiWindowGLX *window,
+ GLXContext foreign_context
+)
+{
+ GstVaapiWindowGLXPrivate * const priv = window->priv;
+ GLContextState old_cs;
+ guint width, height;
+
+ 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;
+ }
+
+ 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);
+ gl_set_current_context(&old_cs, NULL);
+ return TRUE;
+}
+
+static Visual *
+gst_vaapi_window_glx_get_visual(GstVaapiWindow *window)
+{
+ GstVaapiWindowGLX * const glx_window = GST_VAAPI_WINDOW_GLX(window);
+
+ if (!_gst_vaapi_window_glx_ensure_context(glx_window, NULL))
+ return NULL;
+ return glx_window->priv->gl_context->visual->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;
+ gboolean success = FALSE;
+
+ if (!priv->cmap) {
+ if (!priv->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;
+ }
+ 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 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 old_cs;
+
+ if (!GST_VAAPI_WINDOW_CLASS(gst_vaapi_window_glx_parent_class)->
+ 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;
+}
+
+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_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;
+
+ 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);
+}
+
+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));
+
+ 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));
+}
+
+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_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 #GstVaapiWindowGLX
+ *
+ * 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);
+ g_return_val_if_fail(window->priv->is_constructed, FALSE);
+
+ return window->priv->gl_context->context;
+}
+
+/**
+ * gst_vaapi_window_glx_set_context:
+ * @window: a #GstVaapiWindowGLX
+ * @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);
+ g_return_val_if_fail(window->priv->is_constructed, FALSE);
+
+ return gst_vaapi_window_glx_ensure_context(window, ctx);
+}
+
+/**
+ * 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_set_current_context(window->priv->gl_context, NULL);
+ GST_VAAPI_OBJECT_UNLOCK_DISPLAY(window);
+ return success;
+}
+
+/**
+ * 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));
+ g_return_if_fail(window->priv->is_constructed);
+
+ GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
+ gl_swap_buffers(window->priv->gl_context);
+ 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;
+
+ /* 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;
+}
--- /dev/null
+/*
+ * gstvaapiwindow_glx.h - VA/GLX window abstraction
+ *
+ * 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_WINDOW_GLX_H
+#define GST_VAAPI_WINDOW_GLX_H
+
+#include <GL/glx.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiwindow_x11.h>
+#include <gst/vaapi/gstvaapitexture.h>
+
+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) G_GNUC_CONST;
+
+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);
+
+gboolean
+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 */
--- /dev/null
+/*
+ * 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 <string.h>
+#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 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,
+ 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_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
+ );
+
+ 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, va_flags;
+ 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);
+
+ /* 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;
+
+ /* 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);
+}
--- /dev/null
+/*
+ * 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 <wayland-client.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiwindow.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapiwindow_x11.c - VA/X11 window abstraction
+ *
+ * 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:gstvaapiwindow_x11
+ * @short_description: VA/X11 window abstraction
+ */
+
+#include "sysdeps.h"
+#include <string.h>
+#include <X11/Xatom.h>
+#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"
+
+#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)
+{
+ GstVaapiWindowX11Private * const priv = window->priv;
+ Display * const dpy = GST_VAAPI_OBJECT_XDISPLAY(window);
+ XClientMessageEvent 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.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
+ );
+}
+
+static void
+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;
+
+ 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);
+ 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;
+}
+
+static gboolean
+gst_vaapi_window_x11_show(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);
+ XWindowAttributes wattr;
+ gboolean has_errors;
+
+ if (priv->is_mapped)
+ return TRUE;
+
+ GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
+ x11_trap_errors();
+ if (!priv->create_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 (!priv->create_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;
+}
+
+static gboolean
+gst_vaapi_window_x11_hide(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);
+ XWindowAttributes wattr;
+ gboolean has_errors;
+
+ if (!priv->is_mapped)
+ return TRUE;
+
+ GST_VAAPI_OBJECT_LOCK_DISPLAY(window);
+ x11_trap_errors();
+ if (!priv->create_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 (!has_errors) {
+ wait_event(window, UnmapNotify);
+ if (!priv->create_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;
+}
+
+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_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;
+
+ static const char *atom_names[2] = {
+ "_NET_WM_STATE",
+ "_NET_WM_STATE_FULLSCREEN",
+ };
+
+ if (!priv->create_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);
+ 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)
+{
+ 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) {
+ 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)
+{
+ 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);
+}
+
+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_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;
+
+ 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(
+ GST_VAAPI_WINDOW_X11(window),
+ priv->atom_NET_WM_STATE_FULLSCREEN,
+ TRUE
+ );
+ }
+ }
+ else {
+ if (!priv->is_mapped) {
+ priv->fullscreen_on_map = FALSE;
+
+ XDeleteProperty(
+ dpy,
+ xid,
+ priv->atom_NET_WM_STATE
+ );
+ }
+ else {
+ send_wmspec_change_state(
+ GST_VAAPI_WINDOW_X11(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 (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(
+ 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)
+{
+ gboolean has_errors;
+
+ 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;
+}
+
+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;
+
+ 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;
+
+ 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
+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->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->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;
+}
+
+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->is_mapped = FALSE;
+ priv->fullscreen_on_map = 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)
+{
+ 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);
+}
+
+/**
+ * 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)
+{
+ 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);
+}
+
+/**
+ * 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)
+{
+ g_return_val_if_fail(GST_VAAPI_IS_WINDOW_X11(window), None);
+
+ 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;
+}
--- /dev/null
+/*
+ * gstvaapiwindow_x11.h - VA/X11 window abstraction
+ *
+ * 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_WINDOW_X11_H
+#define GST_VAAPI_WINDOW_X11_H
+
+#include <X11/Xlib.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiwindow.h>
+
+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))
+
+/**
+ * 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;
+
+/**
+ * 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);
+
+GstVaapiWindow *
+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 */
--- /dev/null
+/*
+ * 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
+
+/*
+ * 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)
+
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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
+
+#include "glibcompat.h"
+
+#endif /* SYSDEPS_H */
--- /dev/null
+SUBDIRS = vaapi
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+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 =
+
+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
+endif
+
+if USE_GLX
+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 \
+ gstvaapidownload.c \
+ gstvaapipluginbuffer.c \
+ gstvaapipluginutil.c \
+ gstvaapipostproc.c \
+ gstvaapisink.c \
+ gstvaapiupload.c \
+ $(NULL)
+
+noinst_HEADERS = \
+ gstvaapidecode.h \
+ gstvaapidownload.h \
+ gstvaapipluginbuffer.h \
+ gstvaapipluginutil.h \
+ gstvaapipostproc.h \
+ gstvaapisink.h \
+ gstvaapiupload.h \
+ $(NULL)
+
+if USE_ENCODERS
+libgstvaapi_la_SOURCES += \
+ gstvaapiencode.c \
+ gstvaapiencode_h264.c \
+ gstvaapiencode_h263.c \
+ gstvaapiencode_mpeg4.c \
+ $(NULL)
+
+noinst_HEADERS += \
+ gstvaapiencode.h \
+ gstvaapiencode_h264.h \
+ gstvaapiencode_h263.h \
+ gstvaapiencode_mpeg4.h \
+ $(NULL)
+endif
+
+libgstvaapi_la_CFLAGS = \
+ $(libgstvaapi_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(GST_BASE_CFLAGS) \
+ $(GST_VIDEO_CFLAGS) \
+ $(GST_INTERFACES_CFLAGS) \
+ $(GST_BASEVIDEO_CFLAGS) \
+ $(GST_PLUGINS_BASE_CFLAGS)
+
+libgstvaapi_la_LIBADD = \
+ $(libgstvaapi_LIBS) \
+ $(GST_LIBS) \
+ $(GST_BASE_LIBS) \
+ $(GST_VIDEO_LIBS) \
+ $(GST_INTERFACES_LIBS) \
+ $(GST_BASEVIDEO_LIBS) \
+ $(GST_PLUGINS_BASE_LIBS)
+
+libgstvaapi_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
+libgstvaapi_la_LIBTOOLFLAGS = --tag=disable-static
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+/*
+ * gstvaapi.c - VA-API element registration
+ *
+ * Copyright (C) 2011-2012 Intel Corporation
+ * Copyright (C) 2011 Collabora Ltd.
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <gst/gst.h>
+
+#include "gstvaapidownload.h"
+#include "gstvaapiupload.h"
+#include "gstvaapidecode.h"
+#include "gstvaapipostproc.h"
+#include "gstvaapisink.h"
+
+#if USE_ENCODERS
+#include "gstvaapiencode.h"
+#include "gstvaapiencode_h264.h"
+#include "gstvaapiencode_h263.h"
+#include "gstvaapiencode_mpeg4.h"
+
+/* encoder plugin register*/
+static gboolean
+vaapi_encoder_plugins_init (GstPlugin * plugin)
+{
+ gboolean ret = TRUE;
+
+ ret &= gst_element_register (plugin, "vaapiencodeh264", GST_RANK_PRIMARY,
+ GST_TYPE_VAAPI_ENCODE_H264);
+ ret &= gst_element_register (plugin, "vaapiencodeh263", GST_RANK_PRIMARY,
+ GST_TYPE_VAAPI_ENCODE_H263);
+ ret &= gst_element_register (plugin, "vaapiencodempeg4", GST_RANK_PRIMARY,
+ GST_TYPE_VAAPI_ENCODE_MPEG4);
+ return ret;
+}
+#endif
+
+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);
+ 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);
+#if USE_ENCODERS
+ return vaapi_encoder_plugins_init(plugin);
+#endif
+ return TRUE;
+}
+
+GST_PLUGIN_DEFINE(
+ GST_VERSION_MAJOR, GST_VERSION_MINOR,
+ "vaapi",
+ "VA-API based elements",
+ plugin_init,
+ PACKAGE_VERSION,
+ "LGPL",
+ PACKAGE,
+ PACKAGE_BUGREPORT);
--- /dev/null
+/*
+ * gstvaapidecode.c - VA-API video 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: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 <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+#include <gst/video/videocontext.h>
+
+#include "gstvaapidecode.h"
+#include "gstvaapipluginutil.h"
+#include "gstvaapipluginbuffer.h"
+
+#include <gst/vaapi/gstvaapidecoder_h264.h>
+#include <gst/vaapi/gstvaapidecoder_jpeg.h>
+#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
+#include <gst/vaapi/gstvaapidecoder_mpeg4.h>
+#include <gst/vaapi/gstvaapidecoder_vc1.h>
+
+#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(
+ "VA-API decoder",
+ "Codec/Decoder/Video",
+ GST_PLUGIN_DESC,
+ "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
+
+/* Default templates */
+#define GST_CAPS_CODEC(CODEC) CODEC "; "
+
+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")
+ 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("image/jpeg")
+ ;
+
+static const char gst_vaapidecode_src_caps_str[] =
+ GST_VAAPI_SURFACE_CAPS;
+
+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));
+
+static void
+gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface);
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface);
+
+#define GstVideoContextClass GstVideoContextInterface
+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));
+
+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, *v_interlaced;
+ 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");
+ v_interlaced = gst_structure_get_value(structure, "interlaced");
+
+ 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);
+
+ gst_structure_set(structure, "type", G_TYPE_STRING, "vaapi", 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);
+ gst_caps_unref(other_caps);
+ return success;
+}
+
+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 gboolean
+gst_vaapidecode_is_valid_time(GstVaapiDecode *decode, gint64 time)
+{
+ if (decode->segment.format != GST_FORMAT_TIME)
+ return TRUE;
+ if (decode->segment.stop != -1 && time != -1 && time > decode->segment.stop)
+ return FALSE;
+ if (decode->segment.start != -1 && time != -1 && time < decode->segment.start)
+ return FALSE;
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_vaapidecode_step(GstVaapiDecode *decode)
+{
+ GstVaapiSurfaceProxy *proxy;
+ GstVaapiDecoderStatus status;
+ GstBuffer *buffer;
+ GstClockTime timestamp;
+ 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, 10000); /* 10 ms each step */
+ g_mutex_lock(decode->decoder_mutex);
+ g_cond_timed_wait(
+ decode->decoder_ready,
+ decode->decoder_mutex,
+ &timeout
+ );
+ g_mutex_unlock(decode->decoder_mutex);
+ goto again;
+ }
+ if (status != GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA)
+ goto error_decode;
+ /* More data is needed */
+ break;
+ }
+
+ timestamp = GST_VAAPI_SURFACE_PROXY_TIMESTAMP(proxy);
+ if (GST_CLOCK_TIME_IS_VALID(timestamp) &&
+ !gst_vaapidecode_is_valid_time(decode, (gint64)timestamp)) {
+ g_object_unref(proxy);
+ continue;
+ }
+
+ g_object_weak_ref(
+ G_OBJECT(proxy),
+ (GWeakNotify)gst_vaapidecode_release,
+ decode
+ );
+
+ buffer = gst_vaapi_video_buffer_new(decode->display);
+ if (!buffer)
+ goto error_create_buffer;
+
+ GST_BUFFER_TIMESTAMP(buffer) = timestamp;
+ 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
+ );
+
+ 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 */
+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);
+ 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:
+ {
+ 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 GST_FLOW_UNEXPECTED;
+ }
+error_commit_buffer:
+ {
+ GST_DEBUG("video sink rejected the video buffer (error %d)", ret);
+ g_object_unref(proxy);
+ return GST_FLOW_UNEXPECTED;
+ }
+}
+
+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)
+{
+ GstVaapiDisplay *dpy;
+ GstStructure *structure;
+ int version;
+
+ if (!gst_vaapidecode_ensure_display(decode))
+ 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;
+
+ 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"))
+ 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
+ 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;
+}
+
+static void
+gst_vaapidecode_destroy(GstVaapiDecode *decode)
+{
+ if (decode->decoder) {
+ gst_vaapi_decoder_put_buffer(decode->decoder, NULL);
+ g_object_unref(decode->decoder);
+ decode->decoder = NULL;
+ }
+
+ if (decode->decoder_caps) {
+ 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
+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_configure_segment(
+ GstVaapiDecode *decode,
+ GstEvent *event
+)
+{
+ gboolean update;
+ gdouble rate, applied_rate;
+ GstFormat format;
+ gint64 start, stop, time;
+
+ gst_event_parse_new_segment_full(event, &update, &rate, &applied_rate,
+ &format, &start, &stop, &time);
+ if (format == GST_FORMAT_TIME) {
+ gst_segment_set_newsegment_full(&decode->segment, update, rate, applied_rate,
+ format, start, stop, time);
+ GST_DEBUG("configured new segment, update %d, rate %lf, applied rate %lf, "
+ "format GST_FORMAT_TIME, "
+ "start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT ", "
+ "time %" GST_TIME_FORMAT,
+ update, rate, applied_rate,
+ GST_TIME_ARGS(start), GST_TIME_ARGS(stop),
+ GST_TIME_ARGS(time));
+ }
+}
+
+/* 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)
+{
+ GstVaapiDecode * const decode = GST_VAAPIDECODE(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;
+ }
+
+ g_clear_object(&decode->display);
+
+ if (decode->allowed_caps) {
+ gst_caps_unref(decode->allowed_caps);
+ decode->allowed_caps = NULL;
+ }
+
+ if (decode->delayed_new_seg) {
+ gst_event_unref(decode->delayed_new_seg);
+ decode->delayed_new_seg = NULL;
+ }
+
+ G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object);
+}
+
+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_NULL_TO_READY:
+ decode->is_ready = TRUE;
+ break;
+ case GST_STATE_CHANGE_READY_TO_PAUSED:
+ break;
+ case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
+ break;
+ default:
+ 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;
+}
+
+static void
+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);
+
+ object_class->finalize = gst_vaapidecode_finalize;
+
+ 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);
+}
+
+static gboolean
+gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
+{
+ GstCaps *decode_caps;
+ guint i, n_decode_caps;
+
+ if (decode->allowed_caps)
+ return TRUE;
+
+ if (!gst_vaapidecode_ensure_display(decode))
+ goto error_no_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);
+
+ 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);
+ 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");
+ return FALSE;
+ }
+error_no_memory:
+ {
+ GST_DEBUG("failed to allocate allowed-caps set");
+ gst_caps_unref(decode_caps);
+ return FALSE;
+ }
+}
+
+static GstCaps *
+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();
+
+ 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_FLUSH_STOP:
+ gst_segment_init(&decode->segment, GST_FORMAT_UNDEFINED);
+ if (decode->decoder)
+ gst_vaapi_decoder_clear_buffer(decode->decoder);
+ break;
+ 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;
+ }
+ gst_vaapidecode_configure_segment(decode, event);
+ 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));
+ 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 = GST_VAAPIDECODE_GET_CLASS(decode);
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ 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;
+ decode->is_ready = FALSE;
+ gst_segment_init(&decode->segment, GST_FORMAT_UNDEFINED);
+
+ /* 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_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);
+ 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 */
+ 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);
+ gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query);
+ gst_element_add_pad(GST_ELEMENT(decode), decode->srcpad);
+}
--- /dev/null
+/*
+ * gstvaapidecode.h - VA-API video decoder
+ *
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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
+#define GST_VAAPIDECODE_H
+
+#include <gst/gst.h>
+#include <gst/gsttask.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+
+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;
+ GstCaps *sinkpad_caps;
+ GstPad *srcpad;
+ GstCaps *srcpad_caps;
+ GstVaapiDisplay *display;
+ GstVaapiDecoder *decoder;
+ GMutex *decoder_mutex;
+ GCond *decoder_ready;
+ GstCaps *decoder_caps;
+ GstCaps *allowed_caps;
+ GstEvent *delayed_new_seg;
+ GstSegment segment;
+ unsigned int is_ready : 1;
+};
+
+struct _GstVaapiDecodeClass {
+ /*< private >*/
+ GstElementClass parent_class;
+};
+
+GType
+gst_vaapidecode_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GST_VAAPIDECODE_H */
--- /dev/null
+/*
+ * gstvaapidownload.c - VA-API video downloader
+ *
+ * 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:gstvaapidownload
+ * @short_description: A VA to video flow filter
+ *
+ * vaapidownload converts from VA surfaces to raw YUV pixels.
+ */
+
+#include "config.h"
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/videocontext.h>
+#include <gst/vaapi/gstvaapivideobuffer.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"
+
+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 <gwenole.beauchesne@intel.com>");
+
+/* 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;
+};
+
+static void
+gst_vaapidownload_implements_iface_init(GstImplementsInterfaceClass *iface);
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface);
+
+#define GstVideoContextClass GstVideoContextInterface
+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));
+
+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
+);
+
+/* 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)
+{
+ 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;
+ }
+
+ g_clear_object(&download->images);
+ g_clear_object(&download->display);
+}
+
+static void
+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,
+ 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);
+ 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
+gst_vaapidownload_init(GstVaapiDownload *download)
+{
+ 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 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_vaapidownload_ensure_display(download))
+ return FALSE;
+ return TRUE;
+}
+
+static gboolean
+gst_vaapidownload_stop(GstBaseTransform *trans)
+{
+ GstVaapiDownload * const download = GST_VAAPIDOWNLOAD(trans);
+
+ g_clear_object(&download->display);
+
+ 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_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 {
+ 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_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;
+ g_clear_object(&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;
+
+}
--- /dev/null
+/*
+ * gstvaapidownload.h - VA-API video downloader
+ *
+ * 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_VAAPIDOWNLOAD_H
+#define GST_VAAPIDOWNLOAD_H
+
+#include <gst/base/gstbasetransform.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapiimagepool.h>
+#include <gst/vaapi/gstvaapisurfacepool.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+
+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 */
--- /dev/null
+/*
+ * gstvaapiencode.c - VA-API video encoder
+ *
+ * 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 "config.h"
+#include "gstvaapiencode.h"
+
+#include <string.h>
+#include <X11/Xlib.h>
+#include <gst/video/videocontext.h>
+#include "gst/vaapi/gstvaapibaseencoder.h"
+
+#include "gstvaapiencode_h264.h"
+#include "gstvaapiencode_h263.h"
+#include "gstvaapiencode_mpeg4.h"
+#include "gstvaapipluginutil.h"
+#include "gstvaapipluginbuffer.h"
+
+/* gst_debug
+ GST_DEBUG_CATEGORY_STATIC (gst_vaapi_encode_debug)
+ #define GST_CAT_DEFAULT gst_vaapi_encode_debug
+ //class_init
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_encode_debug, "vaapiencode", 0,
+ "vaapiencode element");
+*/
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_encode_debug);
+#define GST_CAT_DEFAULT gst_vaapi_encode_debug
+
+#define GST_VAAPI_ENCODE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ GST_TYPE_VAAPI_ENCODE, \
+ GstVaapiEncodePrivate))
+
+typedef struct _GstVaapiEncodePrivate GstVaapiEncodePrivate;
+
+#define GstVideoContextClass GstVideoContextInterface
+
+GST_BOILERPLATE_WITH_INTERFACE(
+ GstVaapiEncode,
+ gst_vaapi_encode,
+ GstElement,
+ GST_TYPE_ELEMENT,
+ GstVideoContext,
+ GST_TYPE_VIDEO_CONTEXT,
+ gst_video_context)
+
+
+enum {
+ PROP_0,
+};
+
+static char*
+_encode_dump_caps(GstCaps *cpas)
+{
+ guint i = 0, j = 0;
+ GstStructure const *structure;
+ GValue const *value;
+ static char caps_string[4096*5];
+ char *tmp;
+
+ char *cur = caps_string;
+ memset(caps_string, 0, sizeof(caps_string));
+ for (i = 0; i < gst_caps_get_size(cpas); i++) {
+ structure = gst_caps_get_structure(cpas, i);
+ const char* caps_name = gst_structure_get_name (structure);
+ sprintf(cur, "cap_%02d:%s\n", i, caps_name);
+ cur += strlen(cur);
+
+ for (j = 0; j < gst_structure_n_fields(structure); j++) {
+ const char* name = gst_structure_nth_field_name(structure, j);
+ value = gst_structure_get_value(structure, name);
+ tmp = gst_value_serialize(value);
+ sprintf(cur, "\t%s:%s(%s)\n", name, tmp, G_VALUE_TYPE_NAME(value));
+ cur += strlen(cur);
+ g_free(tmp);
+ }
+ }
+
+ return caps_string;
+}
+
+/* context(display) interface */
+static void
+gst_vaapi_encode_set_video_context(
+ GstVideoContext *context,
+ const gchar *type,
+ const GValue *value
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE (context);
+ GstVaapiDisplay *display = NULL;
+ gst_vaapi_set_display (type, value, &display);
+ gst_vaapi_encoder_set_display(encode->encoder, display);
+}
+
+static gboolean
+gst_video_context_supported (GstVaapiEncode *decode, GType iface_type)
+{
+ return (iface_type == GST_TYPE_VIDEO_CONTEXT);
+}
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface)
+{
+ iface->set_context = gst_vaapi_encode_set_video_context;
+}
+
+static gboolean
+gst_vaapi_encode_query (GstPad *pad, GstQuery *query)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE (gst_pad_get_parent_element (pad));
+ gboolean res;
+
+ if (encode->encoder &&
+ gst_vaapi_reply_to_query(query, ENCODER_DISPLAY(encode->encoder)))
+ res = TRUE;
+ else
+ res = gst_pad_query_default (pad, query);
+
+ g_object_unref (encode);
+ return res;
+}
+
+static inline gboolean
+gst_vaapi_encode_ensure_display(GstVaapiEncode *encode)
+{
+ return gst_vaapi_ensure_display(encode,
+ GST_VAAPI_DISPLAY_TYPE_ANY,
+ &ENCODER_DISPLAY(encode->encoder));
+}
+
+static gboolean
+gst_vaapi_encode_set_caps(GstPad *sink_pad, GstCaps *caps)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(GST_OBJECT_PARENT(sink_pad));
+ GstVaapiEncodeClass *encode_class = GST_VAAPI_ENCODE_GET_CLASS(encode);
+ GstStructure *structure = NULL, *src_struct = NULL;
+ gint width = 0, height = 0;
+ gint fps_n = 0, fps_d = 0;
+ const GValue *fps_value = NULL, *format_value;
+ guint32 format = 0;
+ gboolean ret = TRUE;
+ EncoderStatus encoder_ret = ENCODER_NO_ERROR;
+
+ encode->sinkpad_caps = caps;
+ gst_caps_ref(caps);
+ ENCODER_LOG_INFO("gst_vaapi_encode_set_caps,\n%s",
+ _encode_dump_caps(caps));
+
+ structure = gst_caps_get_structure (caps, 0);
+ if (gst_structure_get_int (structure, "width", &width)) {
+ encode->encoder->width = width;
+ }
+ if (gst_structure_get_int (structure, "height", &height)) {
+ encode->encoder->height = height;
+ }
+ fps_value = gst_structure_get_value (structure, "framerate");
+ if (fps_value) {
+ fps_n = gst_value_get_fraction_numerator (fps_value);
+ fps_d = gst_value_get_fraction_denominator (fps_value);
+ encode->encoder->frame_rate = fps_n/fps_d;
+ }
+ format_value = gst_structure_get_value (structure, "format");
+ if (format_value && GST_IS_VAAPI_ENCODE_H264(encode)) {
+ ENCODER_CHECK_STATUS((format_value &&
+ GST_TYPE_FOURCC == G_VALUE_TYPE(format_value)),
+ FALSE,
+ "1st buffer caps' format type is not fourcc.");
+ format = gst_value_get_fourcc (format_value);
+ if (format) {
+ gst_vaapi_base_encoder_set_input_format(
+ GST_VAAPI_BASE_ENCODER(encode->encoder),
+ format);
+ }
+ }
+
+ /*set src pad caps*/
+ if (encode->srcpad_caps) {
+ gst_caps_unref(encode->srcpad_caps);
+ }
+ encode->srcpad_caps =
+ gst_caps_copy(gst_pad_get_pad_template_caps(encode->srcpad));
+ src_struct = gst_caps_get_structure(encode->srcpad_caps, 0);
+ gst_structure_set(src_struct,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
+ "framerate", GST_TYPE_FRACTION, fps_n, fps_d,
+ NULL);
+ if (encode_class->set_encoder_src_caps) {
+ encode_class->set_encoder_src_caps(encode, encode->srcpad_caps);
+ }
+
+ /*set display and initialize encoder*/
+ ENCODER_CHECK_STATUS(gst_vaapi_encode_ensure_display(encode),
+ FALSE,
+ "encoder ensure display failed on setting caps.");
+
+ encoder_ret = gst_vaapi_encoder_initialize(encode->encoder);
+ ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == encoder_ret,
+ FALSE,
+ "gst_vaapi_encoder_initialize failed.");
+
+ encoder_ret = gst_vaapi_encoder_open(encode->encoder);
+ ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == encoder_ret,
+ FALSE,
+ "gst_vaapi_encoder_open failed.");
+end:
+ return ret;
+}
+
+static GstCaps *
+gst_vaapi_encode_get_caps(GstPad *sink_pad)
+{
+ GstCaps *caps = NULL;
+ GstVaapiEncode * const encode =
+ GST_VAAPI_ENCODE(GST_OBJECT_PARENT(sink_pad));
+
+ if (encode->sinkpad_caps) {
+ gst_caps_ref(encode->sinkpad_caps);
+ ENCODER_LOG_INFO("get caps,\n%s",
+ _encode_dump_caps(encode->sinkpad_caps));
+ return encode->sinkpad_caps;
+ }
+ caps = gst_caps_copy(gst_pad_get_pad_template_caps(sink_pad));
+ return caps;
+}
+
+static GstStateChangeReturn
+gst_vaapi_encode_change_state(
+ GstElement *element,
+ GstStateChange transition
+)
+{
+ GstVaapiEncode * const encode = GST_VAAPI_ENCODE(element);
+ GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
+
+ switch (transition) {
+ 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: {
+ gst_vaapi_encoder_close(encode->encoder);
+ }
+ break;
+ default:
+ break;
+ }
+ return GST_STATE_CHANGE_SUCCESS;
+}
+
+static GstFlowReturn
+gst_vaapi_encode_chain(GstPad *sink_pad, GstBuffer *buf)
+{
+ GstFlowReturn ret = GST_FLOW_OK;
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(GST_OBJECT_PARENT(sink_pad));
+ EncoderStatus encoder_ret = ENCODER_NO_ERROR;
+ GList *out_buffers = NULL;
+ GstBuffer *tmp_buffer = NULL;
+
+ ENCODER_ASSERT(encode && encode->encoder);
+ if (encode->first_sink_frame) {
+ /* get first buffer caps and set encoder values */
+ if (GST_VAAPI_IS_VIDEO_BUFFER(buf)) {
+ GstVaapiVideoBuffer *video_buffer = GST_VAAPI_VIDEO_BUFFER(buf);
+ ENCODER_ASSERT(video_buffer);
+ ENCODER_ASSERT(gst_vaapi_video_buffer_get_display(video_buffer) ==
+ ENCODER_DISPLAY(encode->encoder));
+ }
+ encode->first_sink_frame = FALSE;
+ }
+
+ /*encoding frames*/
+ ENCODER_ASSERT(gst_vaapi_encoder_get_state(encode->encoder) >= VAAPI_ENC_OPENED);
+ encoder_ret = gst_vaapi_encoder_encode(encode->encoder, buf, &out_buffers);
+ ENCODER_CHECK_STATUS (ENCODER_NO_ERROR == encoder_ret,
+ GST_FLOW_ERROR,
+ "gst_vaapi_encoder_encode failed.");
+
+ /*check results*/
+ while (out_buffers) {
+ tmp_buffer = out_buffers->data;
+ out_buffers = g_list_remove(out_buffers, tmp_buffer);
+ if (encode->first_src_frame) {
+ GstBuffer *codec_data = NULL;
+ ENCODER_ASSERT(encode->srcpad_caps);
+ /*replace codec data in src pad caps*/
+ if ((ENCODER_NO_ERROR ==
+ gst_vaapi_encoder_get_codec_data(encode->encoder, &codec_data)) &&
+ codec_data) {
+ gst_caps_set_simple(encode->srcpad_caps,
+ "codec_data",GST_TYPE_BUFFER, codec_data,
+ NULL);
+ }
+ gst_pad_set_caps (encode->srcpad, encode->srcpad_caps);
+
+ GST_BUFFER_CAPS(tmp_buffer) = gst_caps_ref(encode->srcpad_caps);
+ ENCODER_LOG_INFO("gst_vaapi_encode_chain 1st push-buffer caps,\n%s",
+ _encode_dump_caps(encode->srcpad_caps));
+ encode->first_src_frame = FALSE;
+ }
+ ENCODER_LOG_DEBUG(
+ "output:%" GST_TIME_FORMAT ", 0x%s",
+ GST_TIME_ARGS(GST_BUFFER_TIMESTAMP(tmp_buffer)),
+ vaapi_encoder_dump_bytes(GST_BUFFER_DATA(tmp_buffer),
+ (GST_BUFFER_SIZE(tmp_buffer) > 16 ?
+ 16: GST_BUFFER_SIZE(tmp_buffer)))
+ );
+ gst_pad_push(encode->srcpad, tmp_buffer);
+ }
+
+end:
+ gst_buffer_unref(buf);
+ return ret;
+
+}
+
+static GstFlowReturn
+gst_vaapi_encode_buffer_alloc(
+ GstPad * pad,
+ guint64 offset,
+ guint size,
+ GstCaps * caps,
+ GstBuffer ** buf
+)
+{
+ GstVaapiEncode * const encode = GST_VAAPI_ENCODE(GST_OBJECT_PARENT(pad));
+ GstStructure *structure = NULL;
+ GstBuffer *buffer;
+ GstVaapiDisplay* display = NULL;
+ GstFlowReturn ret = GST_FLOW_ERROR;
+
+ if (caps) {
+ structure = gst_caps_get_structure(caps, 0);
+ }
+ if (!structure ||
+ gst_structure_has_name(structure, "video/x-vaapi-surface")) {
+ ENCODER_ASSERT(encode->encoder);
+ ENCODER_CHECK_STATUS(gst_vaapi_encode_ensure_display(encode),
+ GST_FLOW_ERROR,
+ "encoder ensure display failed.")
+ display = ENCODER_DISPLAY(encode->encoder);
+ buffer = (GstBuffer*)gst_vaapi_video_buffer_new(display);
+ } else { /* video/x-raw-yuv */
+ buffer = gst_buffer_new_and_alloc(size);
+ }
+
+ ENCODER_CHECK_STATUS(buffer,
+ GST_FLOW_ERROR,
+ "gst_vaapi_encode_buffer_alloc failed.");
+
+ GST_BUFFER_OFFSET (buffer) = offset;
+ if (caps) {
+ gst_buffer_set_caps(buffer, caps);
+ }
+ *buf = buffer;
+ ret = GST_FLOW_OK;
+
+end:
+ return ret;
+}
+
+static void
+gst_vaapi_encode_finalize(GObject *object)
+{
+ GstVaapiEncode * const encode = GST_VAAPI_ENCODE(object);
+
+ if (encode->sinkpad_caps) {
+ gst_caps_unref(encode->sinkpad_caps);
+ encode->sinkpad_caps = NULL;
+ }
+ encode->sinkpad = NULL;
+
+ if (encode->srcpad_caps) {
+ gst_caps_unref(encode->srcpad_caps);
+ encode->srcpad_caps = NULL;
+ }
+ encode->srcpad = NULL;
+
+ if (encode->encoder) {
+ gst_vaapi_encoder_close(encode->encoder);
+ gst_vaapi_encoder_uninitialize(encode->encoder);
+ gst_vaapi_encoder_unref(encode->encoder);
+ encode->encoder = NULL;
+ }
+
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encode_init(
+ GstVaapiEncode *encode,
+ GstVaapiEncodeClass *klass
+)
+{
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ encode->sinkpad_caps = NULL;
+ encode->srcpad_caps = NULL;
+ encode->first_sink_frame = TRUE;
+ encode->first_src_frame = TRUE;
+
+ encode->encoder = NULL;
+
+ /*sink pad */
+ encode->sinkpad = gst_pad_new_from_template(
+ gst_element_class_get_pad_template(element_class, "sink"),
+ "sink"
+ );
+ gst_pad_set_getcaps_function(encode->sinkpad, gst_vaapi_encode_get_caps);
+ gst_pad_set_setcaps_function(encode->sinkpad, gst_vaapi_encode_set_caps);
+ gst_pad_set_chain_function(encode->sinkpad, gst_vaapi_encode_chain);
+ gst_pad_set_bufferalloc_function(encode->sinkpad,
+ gst_vaapi_encode_buffer_alloc);
+ /*gst_pad_set_event_function(encode->sinkpad, gst_vaapi_encode_sink_event); */
+ /*gst_pad_use_fixed_caps(encode->sinkpad);*/
+ gst_pad_set_query_function(encode->sinkpad, gst_vaapi_encode_query);
+ gst_element_add_pad(GST_ELEMENT(encode), encode->sinkpad);
+
+ /* src pad */
+ encode->srcpad = gst_pad_new_from_template(
+ gst_element_class_get_pad_template(element_class, "src"),
+ "src"
+ );
+ encode->srcpad_caps = NULL;
+
+ gst_pad_use_fixed_caps(encode->srcpad);
+ /*gst_pad_set_event_function(encode->srcpad, gst_vaapi_encode_src_event);*/
+ gst_pad_set_query_function(encode->sinkpad, gst_vaapi_encode_query);
+ gst_element_add_pad(GST_ELEMENT(encode), encode->srcpad);
+}
+
+static void
+gst_vaapi_encode_set_property(
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
+ ENCODER_ASSERT(encode->encoder);
+
+ switch (prop_id) {
+ }
+}
+
+static void
+gst_vaapi_encode_get_property (
+ GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
+ ENCODER_ASSERT(encode->encoder);
+
+ switch (prop_id) {
+ }
+}
+
+static void
+gst_vaapi_encode_base_init(gpointer klass)
+{
+ #if 0
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ gst_element_class_set_details(element_class, &gst_vaapi_encode_details);
+
+ /* sink pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_sink_factory)
+ );
+
+ /* src pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_src_factory)
+ );
+ #endif
+}
+
+static void
+gst_vaapi_encode_class_init(GstVaapiEncodeClass *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ object_class->finalize = gst_vaapi_encode_finalize;
+ object_class->set_property = gst_vaapi_encode_set_property;
+ object_class->get_property = gst_vaapi_encode_get_property;
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_encode_debug,
+ "vaapiencode",
+ 0,
+ "vaapiencode element");
+
+ element_class->change_state = gst_vaapi_encode_change_state;
+
+ klass->set_encoder_src_caps = NULL;
+
+ /* Registering debug symbols for function pointers */
+ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapi_encode_change_state);
+ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapi_encode_get_caps);
+ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapi_encode_set_caps);
+ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapi_encode_chain);
+ GST_DEBUG_REGISTER_FUNCPTR (gst_vaapi_encode_buffer_alloc);
+}
--- /dev/null
+/*
+ * gstvaapiencode.h - VA-API video encoder
+ *
+ * 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_ENCODE_H
+#define GST_VAAPI_ENCODE_H
+
+#include <gst/gst.h>
+#include "gst/vaapi/gstvaapiencoder.h"
+
+G_BEGIN_DECLS
+
+/* Default templates */
+#define GST_CAPS_CODEC(CODEC) \
+ CODEC ", " \
+ "width = (int) [ 1, MAX ], " \
+ "height = (int) [ 1, MAX ]; "
+
+
+#define GST_TYPE_VAAPI_ENCODE \
+ (gst_vaapi_encode_get_type())
+
+#define GST_IS_VAAPI_ENCODE(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODE))
+
+#define GST_IS_VAAPI_ENCODE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODE))
+
+#define GST_VAAPI_ENCODE_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODE, \
+ GstVaapiEncodeClass))
+
+#define GST_VAAPI_ENCODE(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODE, \
+ GstVaapiEncode))
+
+#define GST_VAAPI_ENCODE_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODE, \
+ GstVaapiEncodeClass))
+
+typedef struct _GstVaapiEncode GstVaapiEncode;
+typedef struct _GstVaapiEncodeClass GstVaapiEncodeClass;
+
+struct _GstVaapiEncode {
+ GstElement parent_instance;
+
+ GstPad *sinkpad;
+ GstCaps *sinkpad_caps;
+
+ GstPad *srcpad;
+ GstCaps *srcpad_caps;
+
+ GstVaapiEncoder *encoder;
+ gboolean first_sink_frame;
+ gboolean first_src_frame;
+};
+
+struct _GstVaapiEncodeClass {
+ GstElementClass parent_class;
+ gboolean (*set_encoder_src_caps)(GstVaapiEncode* encode, GstCaps *caps);
+};
+
+GType gst_vaapi_encode_get_type(void);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODE_H */
+
--- /dev/null
+/*
+ * gstvaapiencode_h263.c - VA-API H.263 encoder
+ *
+ * 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 "gstvaapiencode_h263.h"
+#include "gst/vaapi/gstvaapiencoder_h263.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h263_encode_debug);
+#define GST_CAT_DEFAULT gst_vaapi_h263_encode_debug
+
+#define GST_VAAPI_ENCODE_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
+ GST_TYPE_VAAPI_ENCODE, \
+ GstVaapiEncodePrivate))
+
+static const char gst_vaapi_encode_h263_sink_caps_str[] =
+ GST_VAAPI_SURFACE_CAPS;
+
+static const GstElementDetails gst_vaapi_encode_h263_details =
+ GST_ELEMENT_DETAILS(
+ "VA-API h263 encoder",
+ "Codec/Encoder/Video",
+ "A VA-API based h263 encoder",
+ "Feng Yuan <feng.yuan@intel.com>");
+
+
+static const char gst_vaapi_encode_h263_src_caps_str[] =
+ GST_CAPS_CODEC("video/x-h263");
+
+static GstStaticPadTemplate gst_vaapi_encode_h263_sink_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(gst_vaapi_encode_h263_sink_caps_str));
+
+static GstStaticPadTemplate gst_vaapi_encode_h263_src_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(gst_vaapi_encode_h263_src_caps_str));
+
+/* h263 encode */
+GST_BOILERPLATE(
+ GstVaapiEncodeH263,
+ gst_vaapi_encode_h263,
+ GstVaapiEncode,
+ GST_TYPE_VAAPI_ENCODE)
+
+enum {
+ H263_PROP_0,
+ H263_PROP_BITRATE,
+ H263_PROP_INTRA_PERIOD,
+ H263_PROP_INIT_QP,
+ H263_PROP_MIN_QP,
+};
+
+static void
+gst_vaapi_encode_h263_init(
+ GstVaapiEncodeH263 *h263_encode,
+ GstVaapiEncodeH263Class *klass
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(h263_encode);
+ encode->encoder = GST_VAAPI_ENCODER(gst_vaapi_encoder_h263_new());
+ ENCODER_ASSERT(encode->encoder);
+}
+
+static void
+gst_vaapi_encode_h263_set_property(
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+)
+{
+ GstVaapiEncode *base = GST_VAAPI_ENCODE(object);
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263(base->encoder);
+
+ ENCODER_ASSERT(encoder);
+
+ switch (prop_id) {
+ case H263_PROP_BITRATE: {
+ encoder->bitrate = g_value_get_uint(value);
+ }
+ break;
+
+ case H263_PROP_INTRA_PERIOD: {
+ encoder->intra_period = g_value_get_uint(value);
+ }
+ break;
+
+ case H263_PROP_INIT_QP: {
+ encoder->init_qp = g_value_get_uint(value);
+ }
+ break;
+
+ case H263_PROP_MIN_QP: {
+ encoder->min_qp = g_value_get_uint(value);
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_vaapi_encode_h263_get_property (
+ GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec
+)
+{
+ GstVaapiEncode *base = GST_VAAPI_ENCODE(object);
+ GstVaapiEncoderH263 *encoder = GST_VAAPI_ENCODER_H263(base->encoder);
+ ENCODER_ASSERT(encoder);
+
+ switch (prop_id) {
+ case H263_PROP_BITRATE:
+ g_value_set_uint (value, encoder->bitrate);
+ break;
+
+ case H263_PROP_INTRA_PERIOD:
+ g_value_set_uint (value, encoder->intra_period);
+ break;
+
+ case H263_PROP_INIT_QP:
+ g_value_set_uint (value, encoder->init_qp);
+ break;
+
+ case H263_PROP_MIN_QP:
+ g_value_set_uint (value, encoder->min_qp);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_vaapi_encode_h263_base_init(gpointer klass)
+{
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ gst_element_class_set_details(element_class, &gst_vaapi_encode_h263_details);
+
+ /* sink pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_h263_sink_factory)
+ );
+
+ /* src pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_h263_src_factory)
+ );
+}
+
+static void
+gst_vaapi_encode_h263_class_init(GstVaapiEncodeH263Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_h263_encode_debug,
+ "vaapih263encode",
+ 0,
+ "vaapih263encode element");
+
+ /* object_class->finalize = gst_vaapi_encode_h263_finalize; */
+ object_class->set_property = gst_vaapi_encode_h263_set_property;
+ object_class->get_property = gst_vaapi_encode_h263_get_property;
+
+ g_object_class_install_property (
+ object_class,
+ H263_PROP_BITRATE,
+ g_param_spec_uint (
+ "bitrate",
+ "H263 encoding bitrate",
+ "H263 encoding bitrate, 10k~100M, (0, auto-calculate)",
+ 0,
+ 100*1000*1000,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H263_PROP_INTRA_PERIOD,
+ g_param_spec_uint (
+ "intra-period",
+ "H263 encoding intra-period",
+ "H263 encoding intra-period",
+ 1,
+ 300,
+ H263_DEFAULT_INTRA_PERIOD,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H263_PROP_INIT_QP,
+ g_param_spec_uint (
+ "init-qp",
+ "H263 init-qp",
+ "H263 init-qp",
+ 1,
+ 51,
+ H263_DEFAULT_INIT_QP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H263_PROP_MIN_QP,
+ g_param_spec_uint (
+ "min-qp",
+ "H263 min-qp",
+ "H263 min-qp",
+ 1,
+ 51,
+ H263_DEFAULT_MIN_QP,
+ G_PARAM_READWRITE));
+
+}
--- /dev/null
+/*
+ * gstvaapiencode_h263.h - VA-API H.263 encoder
+ *
+ * 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_ENCODE_H263_H
+#define GST_VAAPI_ENCODE_H263_H
+
+#include <gst/gst.h>
+#include "gstvaapiencode.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VAAPI_ENCODE_H263 \
+ (gst_vaapi_encode_h263_get_type())
+
+#define GST_IS_VAAPI_ENCODE_H263(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODE_H263))
+
+#define GST_IS_VAAPI_ENCODE_H263_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODE_H263))
+
+#define GST_VAAPI_ENCODE_H263_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODE_H263, \
+ GstVaapiEncodeH263Class))
+
+#define GST_VAAPI_ENCODE_H263(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODE_H263, \
+ GstVaapiEncodeH263))
+
+#define GST_VAAPI_ENCODE_H263_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODE_H263, \
+ GstVaapiEncodeH263Class))
+
+typedef struct _GstVaapiEncodeH263 GstVaapiEncodeH263;
+typedef struct _GstVaapiEncodeH263Class GstVaapiEncodeH263Class;
+
+struct _GstVaapiEncodeH263 {
+ GstVaapiEncode parent;
+};
+
+struct _GstVaapiEncodeH263Class {
+ GstVaapiEncodeClass parent_class;
+};
+
+GType gst_vaapi_encode_h263_get_type(void);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODE_H263_H */
--- /dev/null
+/*
+ * gstvaapiencode_h264.c - VA-API H.264 encoder
+ *
+ * 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 "gstvaapiencode_h264.h"
+#include "gst/vaapi/gstvaapiencoder_h264.h"
+
+#include <string.h>
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_h264_encode_debug);
+#define GST_CAT_DEFAULT gst_vaapi_h264_encode_debug
+
+static const char gst_vaapi_encode_h264_sink_caps_str[] =
+ GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { I420 } ")
+ GST_CAPS_CODEC("video/x-raw-yuv, " "format = (fourcc) { NV12 } ")
+ GST_VAAPI_SURFACE_CAPS;
+
+static const GstElementDetails gst_vaapi_encode_h264_details =
+ GST_ELEMENT_DETAILS(
+ "VA-API h264 encoder",
+ "Codec/Encoder/Video",
+ "A VA-API based h264 encoder",
+ "Feng Yuan<feng.yuan@intel.com>");
+
+
+static const char gst_vaapi_encode_h264_src_caps_str[] =
+ GST_CAPS_CODEC("video/x-h264");
+
+static GstStaticPadTemplate gst_vaapi_encode_h264_sink_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(gst_vaapi_encode_h264_sink_caps_str));
+
+static GstStaticPadTemplate gst_vaapi_encode_h264_src_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(gst_vaapi_encode_h264_src_caps_str));
+
+/* h264 encode */
+GST_BOILERPLATE(
+ GstVaapiEncodeH264,
+ gst_vaapi_encode_h264,
+ GstVaapiEncode,
+ GST_TYPE_VAAPI_ENCODE)
+
+enum {
+ H264_PROP_0,
+ H264_PROP_PROFILE,
+ H264_PROP_LEVEL,
+ H264_PROP_BITRATE,
+ H264_PROP_INTRA_PERIOD,
+ H264_PROP_INIT_QP,
+ H264_PROP_MIN_QP,
+ H264_PROP_SLICE_NUM,
+ H264_PROP_B_FRAME_NUM,
+};
+
+static void
+gst_vaapi_encode_h264_init(
+ GstVaapiEncodeH264 *h264_encode,
+ GstVaapiEncodeH264Class *klass
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(h264_encode);
+ encode->encoder = GST_VAAPI_ENCODER(gst_vaapi_encoder_h264_new());
+ ENCODER_ASSERT(encode->encoder);
+}
+
+static void
+gst_vaapi_encode_h264_finalize(GObject *object)
+{
+ //GstVaapiEncodeH264 * const h264_encode = GST_VAAPI_ENCODE_H264(object);
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+
+static inline gboolean
+h264_check_valid_profile(guint profile)
+{
+ static const guint limit_profiles[] = {
+ H264_PROFILE_BASELINE,
+ H264_PROFILE_MAIN,
+ H264_PROFILE_HIGH
+ };
+ guint n_profiles = sizeof(limit_profiles)/sizeof(limit_profiles[0]);
+ guint i;
+ for (i = 0; i < n_profiles; ++i) {
+ if (limit_profiles[i] == profile)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static inline gboolean
+h264_check_valid_level(guint level)
+{
+ static const guint limit_levels[] = {
+ H264_LEVEL_10,
+ H264_LEVEL_11,
+ H264_LEVEL_12,
+ H264_LEVEL_13,
+ H264_LEVEL_20,
+ H264_LEVEL_21,
+ H264_LEVEL_22,
+ H264_LEVEL_30,
+ H264_LEVEL_31,
+ H264_LEVEL_32,
+ H264_LEVEL_40,
+ H264_LEVEL_41,
+ H264_LEVEL_42,
+ H264_LEVEL_50,
+ H264_LEVEL_51
+ };
+ guint n_levels = sizeof(limit_levels)/sizeof(limit_levels[0]);
+ guint i;
+ for (i = 0; i < n_levels; ++i) {
+ if (limit_levels[i] == level)
+ return TRUE;
+ }
+ return FALSE;
+
+}
+
+
+static void
+gst_vaapi_encode_h264_set_property(
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
+ GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
+
+ ENCODER_ASSERT(h264encoder);
+
+ switch (prop_id) {
+ case H264_PROP_PROFILE: {
+ guint profile = g_value_get_uint(value);
+ if (h264_check_valid_profile(profile)) {
+ h264encoder->profile = profile;
+ } else {
+ ENCODER_LOG_ERROR("h264encode set property <profile> failed.");
+ }
+ }
+ break;
+
+ case H264_PROP_LEVEL: {
+ guint level = g_value_get_uint(value);
+ if (h264_check_valid_level(level)) {
+ h264encoder->level= level;
+ } else {
+ ENCODER_LOG_ERROR("h264encode set property <level> failed.");
+ }
+ }
+ break;
+
+ case H264_PROP_BITRATE: {
+ h264encoder->bitrate = g_value_get_uint(value);
+ }
+ break;
+
+ case H264_PROP_INTRA_PERIOD: {
+ h264encoder->intra_period = g_value_get_uint(value);
+ }
+ break;
+
+ case H264_PROP_INIT_QP: {
+ h264encoder->init_qp = g_value_get_uint(value);
+ }
+ break;
+
+ case H264_PROP_MIN_QP: {
+ h264encoder->min_qp = g_value_get_uint(value);
+ }
+ break;
+
+ case H264_PROP_SLICE_NUM: {
+ h264encoder->slice_num= g_value_get_uint(value);
+ }
+ break;
+
+ case H264_PROP_B_FRAME_NUM: {
+ h264encoder->b_frame_num= g_value_get_uint(value);
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_vaapi_encode_h264_get_property (
+ GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
+ GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
+ ENCODER_ASSERT(h264encoder);
+
+ switch (prop_id) {
+ case H264_PROP_PROFILE:
+ g_value_set_uint (value, h264encoder->profile);
+ break;
+
+ case H264_PROP_LEVEL:
+ g_value_set_uint (value, h264encoder->level);
+ break;
+
+ case H264_PROP_BITRATE:
+ g_value_set_uint (value, h264encoder->bitrate);
+ break;
+
+ case H264_PROP_INTRA_PERIOD:
+ g_value_set_uint (value, h264encoder->intra_period);
+ break;
+
+ case H264_PROP_INIT_QP:
+ g_value_set_uint (value, h264encoder->init_qp);
+ break;
+
+ case H264_PROP_MIN_QP:
+ g_value_set_uint (value, h264encoder->min_qp);
+ break;
+
+ case H264_PROP_SLICE_NUM:
+ g_value_set_uint (value, h264encoder->slice_num);
+ break;
+
+ case H264_PROP_B_FRAME_NUM:
+ g_value_set_uint (value, h264encoder->b_frame_num);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static gboolean
+gst_vaapi_encode_h264_set_src_caps(
+ GstVaapiEncode* encode,
+ GstCaps *caps
+)
+{
+ GstVaapiEncoderH264 *h264encoder = GST_VAAPI_ENCODER_H264(encode->encoder);
+ GstCaps *peer_caps, *allowed_caps;
+ GstStructure *s;
+ const gchar *stream_format;
+
+ g_return_val_if_fail(caps,FALSE);
+ peer_caps = gst_pad_peer_get_caps_reffed(encode->srcpad);
+ if (peer_caps) {
+ allowed_caps = gst_caps_intersect(peer_caps, caps);
+ if (allowed_caps) {
+ allowed_caps = gst_caps_make_writable(allowed_caps);
+ gst_pad_fixate_caps(encode->srcpad, caps);
+ s = gst_caps_get_structure (allowed_caps, 0);
+ stream_format = gst_structure_get_string (s, "stream-format");
+ if (stream_format) {
+ if (!strcmp (stream_format, "avc")) {
+ gst_vaapi_encoder_h264_set_avc_flag(h264encoder, TRUE);
+ } else if (!strcmp (stream_format, "byte-stream")) {
+ gst_vaapi_encoder_h264_set_avc_flag(h264encoder, FALSE);
+ }
+ }
+ gst_caps_unref(allowed_caps);
+ }
+ gst_caps_unref(peer_caps);
+ }
+ gst_caps_set_simple(caps, "stream-format",
+ G_TYPE_STRING,
+ (gst_vaapi_encoder_h264_get_avc_flag(h264encoder) ? "avc" : "byte-stream"),
+ "alignment", G_TYPE_STRING, "au",
+ NULL);
+ return TRUE;
+}
+
+static void
+gst_vaapi_encode_h264_base_init(gpointer klass)
+{
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ gst_element_class_set_details(element_class, &gst_vaapi_encode_h264_details);
+
+ /* sink pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_h264_sink_factory)
+ );
+
+ /* src pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_h264_src_factory)
+ );
+}
+
+static void
+gst_vaapi_encode_h264_class_init(GstVaapiEncodeH264Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+ GstVaapiEncodeClass *const encode_class = GST_VAAPI_ENCODE_CLASS(klass);
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_h264_encode_debug,
+ "vaapih264encode",
+ 0,
+ "vaapih264encode element");
+
+ object_class->finalize = gst_vaapi_encode_h264_finalize;
+ object_class->set_property = gst_vaapi_encode_h264_set_property;
+ object_class->get_property = gst_vaapi_encode_h264_get_property;
+
+ encode_class->set_encoder_src_caps = gst_vaapi_encode_h264_set_src_caps;
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_PROFILE,
+ g_param_spec_uint (
+ "profile",
+ "H264 Profile",
+ "Profile supports: 66(Baseline), 77(Main), 100(High)",
+ H264_PROFILE_BASELINE,
+ H264_PROFILE_HIGH10,
+ H264_DEFAULT_PROFILE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_LEVEL,
+ g_param_spec_uint (
+ "level",
+ "H264 level idc",
+ "Level idc supports: 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41",
+ H264_LEVEL_10,
+ H264_LEVEL_41,
+ H264_DEFAULT_LEVEL,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_BITRATE,
+ g_param_spec_uint (
+ "bitrate",
+ "H264 encoding bitrate",
+ "H264 encoding bitrate, 10k~100M, (0, auto-calculate)",
+ 0,
+ 100*1000*1000,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_INTRA_PERIOD,
+ g_param_spec_uint (
+ "intra-period",
+ "H264 encoding intra-period",
+ "H264 encoding intra-period",
+ 1,
+ 300,
+ H264_DEFAULT_INTRA_PERIOD,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_INIT_QP,
+ g_param_spec_uint (
+ "init-qp",
+ "H264 init-qp",
+ "H264 init-qp",
+ 1,
+ 51,
+ H264_DEFAULT_INIT_QP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_MIN_QP,
+ g_param_spec_uint (
+ "min-qp",
+ "H264 min-qp",
+ "H264 min-qp",
+ 1,
+ 51,
+ H264_DEFAULT_MIN_QP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_SLICE_NUM,
+ g_param_spec_uint (
+ "slice-num",
+ "H264 slice num",
+ "H264 slice num",
+ 1,
+ 200,
+ 1,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ H264_PROP_B_FRAME_NUM,
+ g_param_spec_uint (
+ "b-frame-num",
+ "B frams num",
+ "B frams num",
+ 0,
+ 10,
+ 0,
+ G_PARAM_READWRITE));
+}
--- /dev/null
+/*
+ * gstvaapiencode_h264.h - VA-API H.264 encoder
+ *
+ * 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_ENCODE_H264_H
+#define GST_VAAPI_ENCODE_H264_H
+
+#include <gst/gst.h>
+#include "gstvaapiencode.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VAAPI_ENCODE_H264 \
+ (gst_vaapi_encode_h264_get_type())
+
+#define GST_IS_VAAPI_ENCODE_H264(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODE_H264))
+
+#define GST_IS_VAAPI_ENCODE_H264_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODE_H264))
+
+#define GST_VAAPI_ENCODE_H264_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODE_H264, \
+ GstVaapiEncodeH264Class))
+
+#define GST_VAAPI_ENCODE_H264(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODE_H264, \
+ GstVaapiEncodeH264))
+
+#define GST_VAAPI_ENCODE_H264_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODE_H264, \
+ GstVaapiEncodeH264Class))
+
+
+typedef struct _GstVaapiEncodeH264 GstVaapiEncodeH264;
+typedef struct _GstVaapiEncodeH264Class GstVaapiEncodeH264Class;
+
+struct _GstVaapiEncodeH264 {
+ GstVaapiEncode parent;
+};
+
+struct _GstVaapiEncodeH264Class {
+ GstVaapiEncodeClass parent_class;
+};
+
+GType gst_vaapi_encode_h264_get_type(void);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODE_H264_H */
--- /dev/null
+/*
+ * gstvaapiencode_mpeg4.c - VA-API MPEG-4 encoder
+ *
+ * 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 "gstvaapiencode_mpeg4.h"
+#include "gst/vaapi/gstvaapiencoder_mpeg4.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_vaapi_encode_mpeg4_debug);
+#define GST_CAT_DEFAULT gst_vaapi_encode_mpeg4_debug
+
+
+static const char gst_vaapi_encode_mpeg4_sink_caps_str[] =
+ GST_VAAPI_SURFACE_CAPS;
+
+static const GstElementDetails gst_vaapi_encode_mpeg4_details =
+ GST_ELEMENT_DETAILS(
+ "VA-API mpeg4 encoder",
+ "Codec/Encoder/Video",
+ "A VA-API based mpeg4 encoder",
+ "Feng Yuan<feng.yuan@intel.com>");
+
+
+static const char gst_vaapi_encode_mpeg4_src_caps_str[] =
+ GST_CAPS_CODEC("video/mpeg, mpegversion=4");
+
+static GstStaticPadTemplate gst_vaapi_encode_mpeg4_sink_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(gst_vaapi_encode_mpeg4_sink_caps_str));
+
+static GstStaticPadTemplate gst_vaapi_encode_mpeg4_src_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "src",
+ GST_PAD_SRC,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(gst_vaapi_encode_mpeg4_src_caps_str));
+
+
+/* mpeg4 encode */
+GST_BOILERPLATE(
+ GstVaapiEncodeMpeg4,
+ gst_vaapi_encode_mpeg4,
+ GstVaapiEncode,
+ GST_TYPE_VAAPI_ENCODE)
+
+enum {
+ MPEG4_PROP_0,
+ MPEG4_PROP_PROFILE,
+ MPEG4_PROP_BITRATE,
+ MPEG4_PROP_INTRA_PERIOD,
+ MPEG4_PROP_INIT_QP,
+ MPEG4_PROP_MIN_QP,
+};
+
+static void
+gst_vaapi_encode_mpeg4_init(
+ GstVaapiEncodeMpeg4 *mpeg4_encode,
+ GstVaapiEncodeMpeg4Class *klass)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(mpeg4_encode);
+ encode->encoder = GST_VAAPI_ENCODER(gst_vaapi_encoder_mpeg4_new());
+ ENCODER_ASSERT(encode->encoder);
+}
+
+static void
+gst_vaapi_encode_mpeg4_finalize(GObject *object)
+{
+ //GstVaapiEncodeMpeg4 * const mpeg4_encode = GST_VAAPI_ENCODE_MPEG4(object);
+ G_OBJECT_CLASS(parent_class)->finalize(object);
+}
+
+static void
+gst_vaapi_encode_mpeg4_set_property(
+ GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
+ GstVaapiEncoderMpeg4 *mpeg4encoder = GST_VAAPI_ENCODER_MPEG4(encode->encoder);
+
+ ENCODER_ASSERT(mpeg4encoder);
+
+ switch (prop_id) {
+ case MPEG4_PROP_PROFILE: {
+ mpeg4encoder->profile = g_value_get_uint(value);
+ }
+ break;
+
+ case MPEG4_PROP_BITRATE: {
+ mpeg4encoder->bitrate = g_value_get_uint(value);
+ }
+ break;
+
+ case MPEG4_PROP_INTRA_PERIOD: {
+ mpeg4encoder->intra_period = g_value_get_uint(value);
+ }
+ break;
+
+ case MPEG4_PROP_INIT_QP: {
+ mpeg4encoder->init_qp = g_value_get_uint(value);
+ }
+ break;
+
+ case MPEG4_PROP_MIN_QP: {
+ mpeg4encoder->min_qp = g_value_get_uint(value);
+ }
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_vaapi_encode_mpeg4_get_property(
+ GObject * object,
+ guint prop_id,
+ GValue * value,
+ GParamSpec * pspec
+)
+{
+ GstVaapiEncode *encode = GST_VAAPI_ENCODE(object);
+ GstVaapiEncoderMpeg4 *mpeg4encoder = GST_VAAPI_ENCODER_MPEG4(encode->encoder);
+ ENCODER_ASSERT(mpeg4encoder);
+
+ switch (prop_id) {
+ case MPEG4_PROP_PROFILE:
+ g_value_set_uint (value, mpeg4encoder->profile);
+ break;
+
+ case MPEG4_PROP_BITRATE:
+ g_value_set_uint (value, mpeg4encoder->bitrate);
+ break;
+
+ case MPEG4_PROP_INTRA_PERIOD:
+ g_value_set_uint (value, mpeg4encoder->intra_period);
+ break;
+
+ case MPEG4_PROP_INIT_QP:
+ g_value_set_uint (value, mpeg4encoder->init_qp);
+ break;
+
+ case MPEG4_PROP_MIN_QP:
+ g_value_set_uint (value, mpeg4encoder->min_qp);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+gst_vaapi_encode_mpeg4_base_init(gpointer klass)
+{
+ GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
+
+ gst_element_class_set_details(element_class, &gst_vaapi_encode_mpeg4_details);
+
+ /* sink pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_mpeg4_sink_factory)
+ );
+
+ /* src pad */
+ gst_element_class_add_pad_template(
+ element_class,
+ gst_static_pad_template_get(&gst_vaapi_encode_mpeg4_src_factory)
+ );
+}
+
+static void
+gst_vaapi_encode_mpeg4_class_init(GstVaapiEncodeMpeg4Class *klass)
+{
+ GObjectClass * const object_class = G_OBJECT_CLASS(klass);
+
+ GST_DEBUG_CATEGORY_INIT (gst_vaapi_encode_mpeg4_debug,
+ "vaapimpeg4encode",
+ 0,
+ "vaapimpeg4encode element");
+
+ object_class->finalize = gst_vaapi_encode_mpeg4_finalize;
+ object_class->set_property = gst_vaapi_encode_mpeg4_set_property;
+ object_class->get_property = gst_vaapi_encode_mpeg4_get_property;
+
+
+ g_object_class_install_property (
+ object_class,
+ MPEG4_PROP_PROFILE,
+ g_param_spec_uint (
+ "profile",
+ "MPEG4 Profile",
+ "Profile supports: 2(Baseline), 3(ASP)",
+ 2,
+ 3,
+ 2,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ MPEG4_PROP_BITRATE,
+ g_param_spec_uint (
+ "bitrate",
+ "MPEG4 encoding bitrate",
+ "MPEG4 encoding bitrate, 10k~100M, (0, auto-calculate)",
+ 0,
+ 100*1000*1000,
+ 0,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ MPEG4_PROP_INTRA_PERIOD,
+ g_param_spec_uint (
+ "intra-period",
+ "MPEG4 encoding intra-period",
+ "MPEG4 encoding intra-period",
+ 1,
+ 300,
+ MPEG4_DEFAULT_INTRA_PERIOD,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ MPEG4_PROP_INIT_QP,
+ g_param_spec_uint (
+ "init-qp",
+ "MPEG4 init-qp",
+ "MPEG4 init-qp",
+ 1,
+ 51,
+ MPEG4_DEFAULT_INIT_QP,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (
+ object_class,
+ MPEG4_PROP_MIN_QP,
+ g_param_spec_uint (
+ "min-qp",
+ "MPEG4 min-qp",
+ "MPEG4 min-qp",
+ 1,
+ 51,
+ MPEG4_DEFAULT_MIN_QP,
+ G_PARAM_READWRITE));
+}
--- /dev/null
+/*
+ * gstvaapiencode_mpeg4.h - VA-API MPEG-4 encoder
+ *
+ * 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_ENCODE_MPEG4_H
+#define GST_VAAPI_ENCODE_MPEG4_H
+
+#include <gst/gst.h>
+#include "gstvaapiencode.h"
+
+G_BEGIN_DECLS
+
+#define GST_TYPE_VAAPI_ENCODE_MPEG4 \
+ (gst_vaapi_encode_mpeg4_get_type())
+
+#define GST_IS_VAAPI_ENCODE_MPEG4(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VAAPI_ENCODE_MPEG4))
+
+#define GST_IS_VAAPI_ENCODE_MPEG4_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_VAAPI_ENCODE_MPEG4))
+
+#define GST_VAAPI_ENCODE_MPEG4_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ GST_TYPE_VAAPI_ENCODE_MPEG4, \
+ GstVaapiEncodeMpeg4Class))
+
+#define GST_VAAPI_ENCODE_MPEG4(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ GST_TYPE_VAAPI_ENCODE_MPEG4, \
+ GstVaapiEncodeMpeg4))
+
+#define GST_VAAPI_ENCODE_MPEG4_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), \
+ GST_TYPE_VAAPI_ENCODE_MPEG4, \
+ GstVaapiEncodeMpeg4Class))
+
+
+typedef struct _GstVaapiEncodeMpeg4 GstVaapiEncodeMpeg4;
+typedef struct _GstVaapiEncodeMpeg4Class GstVaapiEncodeMpeg4Class;
+
+struct _GstVaapiEncodeMpeg4 {
+ GstVaapiEncode parent;
+};
+
+struct _GstVaapiEncodeMpeg4Class {
+ GstVaapiEncodeClass parent_class;
+};
+
+GType gst_vaapi_encode_mpeg4_get_type(void);
+
+G_END_DECLS
+
+#endif /* GST_VAAPI_ENCODE_MPEG4_H */
--- /dev/null
+/*
+ * 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 <gst/vaapi/gstvaapivideobuffer.h>
+#include <gst/vaapi/gstvaapivideobuffer_priv.h>
+#if USE_GLX
+# include <gst/vaapi/gstvaapivideobuffer_glx.h>
+#endif
+#include "gstvaapipluginbuffer.h"
+
+static GType
+get_type(GstVaapiDisplay *display)
+{
+ GType type;
+
+ switch (gst_vaapi_display_get_display_type(display)) {
+#if USE_GLX
+ case GST_VAAPI_DISPLAY_TYPE_GLX:
+ type = GST_VAAPI_TYPE_VIDEO_BUFFER_GLX;
+ break;
+#endif
+ default:
+ type = GST_VAAPI_TYPE_VIDEO_BUFFER;
+ break;
+ }
+ return type;
+}
+
+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;
+ GstVaapiSurface *surface;
+
+ g_return_val_if_fail(GST_VAAPI_IS_SURFACE_PROXY(proxy), 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);
+}
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * gstvaapipluginutil.h - VA-API plugin helpers
+ *
+ * Copyright (C) 2011-2012 Intel Corporation
+ * Copyright (C) 2011 Collabora
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * 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 <string.h>
+#include <gst/video/videocontext.h>
+#if USE_DRM
+# include <gst/vaapi/gstvaapidisplay_drm.h>
+#endif
+#if USE_X11
+# include <gst/vaapi/gstvaapidisplay_x11.h>
+#endif
+#if USE_GLX
+# include <gst/vaapi/gstvaapidisplay_glx.h>
+#endif
+#if USE_WAYLAND
+# include <gst/vaapi/gstvaapidisplay_wayland.h>
+#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
+#if USE_X11
+ "x11-display",
+ "x11-display-name",
+#endif
+#if USE_DRM
+ "drm-device",
+ "drm-device-path",
+#endif
+ NULL
+};
+
+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 },
+#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_DRM
+ { "drm",
+ GST_VAAPI_DISPLAY_TYPE_DRM,
+ gst_vaapi_display_drm_new },
+#endif
+ { NULL, }
+};
+
+gboolean
+gst_vaapi_ensure_display(
+ gpointer element,
+ GstVaapiDisplayType display_type,
+ GstVaapiDisplay **display_ptr
+)
+{
+ 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);
+
+ /* Already exist ? */
+ display = *display_ptr;
+ if (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 &&
+ 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;
+ }
+ g_object_unref(display);
+ display = NULL;
+ }
+
+ if (display_type != GST_VAAPI_DISPLAY_TYPE_ANY)
+ break;
+ }
+
+ if (display_ptr)
+ *display_ptr = display;
+ return display != NULL;
+}
+
+void
+gst_vaapi_set_display(
+ const gchar *type,
+ const GValue *value,
+ GstVaapiDisplay **display
+)
+{
+ GstVaapiDisplay *dpy = 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_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));
+#if USE_GLX
+ 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 USE_GLX
+ 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));
+ }
+#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);
+ }
+#endif
+
+ if (dpy) {
+ if (*display)
+ g_object_unref(*display);
+ *display = dpy;
+ }
+}
+
+gboolean
+gst_vaapi_reply_to_query(GstQuery *query, GstVaapiDisplay *display)
+{
+ GstVaapiDisplayType display_type;
+ 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;
+
+ 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));
+ }
+ 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
+#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;
+ }
+#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;
+}
+
+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;
+}
--- /dev/null
+/*
+ * gstvaapipluginutil.h - VA-API plugins private helper
+ *
+ * Copyright (C) 2011-2012 Intel Corporation
+ * Copyright (C) 2011 Collabora
+ * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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_UTIL_H
+#define GST_VAAPI_PLUGIN_UTIL_H
+
+#include <gst/vaapi/gstvaapidisplay.h>
+
+G_GNUC_INTERNAL
+gboolean
+gst_vaapi_ensure_display(
+ gpointer element,
+ GstVaapiDisplayType display_type,
+ GstVaapiDisplay **display
+);
+
+G_GNUC_INTERNAL
+void
+gst_vaapi_set_display(
+ const gchar *type,
+ const GValue *value,
+ 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);
+
+#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 */
--- /dev/null
+/*
+ * 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 <gst/video/video.h>
+#include <gst/video/videocontext.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+
+#include "gstvaapipostproc.h"
+#include "gstvaapipluginutil.h"
+#include "gstvaapipluginbuffer.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 <gwenole.beauchesne@intel.com>");
+
+/* 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));
+
+static void
+gst_vaapipostproc_implements_iface_init(GstImplementsInterfaceClass *iface);
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface);
+
+#define GstVideoContextClass GstVideoContextInterface
+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));
+
+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));
+}
+
+/* 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)
+{
+ return gst_vaapi_ensure_display(postproc, GST_VAAPI_DISPLAY_TYPE_ANY,
+ &postproc->display);
+}
+
+static gboolean
+gst_vaapipostproc_create(GstVaapiPostproc *postproc, GstCaps *caps)
+{
+ 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);
+
+ g_clear_object(&postproc->display);
+}
+
+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_vaapipostproc_ensure_display(postproc))
+ 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;
+ gboolean interlaced, tff;
+
+ flags = gst_vaapi_video_buffer_get_render_flags(vbuf);
+
+ /* 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);
+ 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);
+ if (!outbuf)
+ goto error_create_buffer;
+
+ vbuf = GST_VAAPI_VIDEO_BUFFER(outbuf);
+ outbuf_flags = flags;
+ outbuf_flags |= interlaced ? (
+ 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_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 |= interlaced ? (
+ 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_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_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(gst_vaapipostproc_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(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);
+ GstPadTemplate *pad_template;
+
+ 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;
+
+ 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:
+ *
+ * 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));
+
+ /**
+ * 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_TYPE_VAAPI_DEINTERLACE_METHODS,
+ DEFAULT_DEINTERLACE_METHOD,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+}
+
+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;
+
+ 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);
+}
--- /dev/null
+/*
+ * 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 <gst/gst.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapisurfacepool.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+
+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_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GST_VAAPIPOSTPROC_H */
--- /dev/null
+/*
+ * gstvaapisink.c - VA-API video sink
+ *
+ * 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: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 <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/videocontext.h>
+#include <gst/vaapi/gstvaapivalue.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+#if USE_DRM
+# include <gst/vaapi/gstvaapidisplay_drm.h>
+#endif
+#if USE_X11
+# include <gst/vaapi/gstvaapidisplay_x11.h>
+# include <gst/vaapi/gstvaapiwindow_x11.h>
+#endif
+#if USE_GLX
+# include <gst/vaapi/gstvaapidisplay_glx.h>
+# include <gst/vaapi/gstvaapiwindow_glx.h>
+#endif
+#if USE_WAYLAND
+# include <gst/vaapi/gstvaapidisplay_wayland.h>
+# include <gst/vaapi/gstvaapiwindow_wayland.h>
+#endif
+
+/* Supported interfaces */
+#include <gst/interfaces/xoverlay.h>
+
+#include "gstvaapisink.h"
+#include "gstvaapipluginutil.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(
+ "VA-API sink",
+ "Sink/Video",
+ GST_PLUGIN_DESC,
+ "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
+
+/* Default template */
+static GstStaticPadTemplate gst_vaapisink_sink_factory =
+ GST_STATIC_PAD_TEMPLATE(
+ "sink",
+ GST_PAD_SINK,
+ GST_PAD_ALWAYS,
+ GST_STATIC_CAPS(GST_VAAPI_SURFACE_CAPS));
+
+static void
+gst_vaapisink_implements_iface_init(GstImplementsInterfaceClass *iface);
+
+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,
+ GST_TYPE_VIDEO_SINK,
+ 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,
+
+ PROP_DISPLAY_TYPE,
+ PROP_FULLSCREEN,
+ PROP_SYNCHRONOUS,
+ PROP_USE_REFLECTION,
+ PROP_ROTATION,
+};
+
+#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
+static gboolean
+gst_vaapisink_ensure_window_xid(GstVaapiSink *sink, guintptr window_id);
+#endif
+
+static gboolean
+gst_vaapisink_ensure_display_rect(GstVaapiSink *sink, guint width, guint height);
+
+static GstFlowReturn
+gst_vaapisink_show_frame(GstBaseSink *base_sink, GstBuffer *buffer);
+
+static void
+gst_vaapisink_xoverlay_set_window_handle(GstXOverlay *overlay, guintptr window)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(overlay);
+
+ /* 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;
+
+ sink->foreign_window = TRUE;
+
+ 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
+gst_vaapisink_xoverlay_set_render_rectangle(
+ GstXOverlay *overlay,
+ gint x,
+ gint y,
+ gint width,
+ gint height
+)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(overlay);
+ GstVaapiRectangle * const render_rect = &sink->render_rect;
+
+ render_rect->x = x;
+ render_rect->y = y;
+ render_rect->width = width;
+ render_rect->height = height;
+
+ GST_DEBUG("render rect (%d,%d):%ux%u",
+ render_rect->x, render_rect->y,
+ render_rect->width, render_rect->height);
+
+ gst_vaapisink_ensure_display_rect(
+ sink,
+ sink->render_rect.width,
+ sink->render_rect.height);
+}
+
+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_window_handle = gst_vaapisink_xoverlay_set_window_handle;
+ iface->set_render_rectangle = gst_vaapisink_xoverlay_set_render_rectangle;
+ iface->expose = gst_vaapisink_xoverlay_expose;
+}
+
+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_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
+)
+{
+ 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;
+}
+#endif
+
+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 "<unknown-type>";
+}
+
+static inline gboolean
+gst_vaapisink_ensure_display(GstVaapiSink *sink)
+{
+ GstVaapiDisplayType display_type;
+ GstVaapiRenderMode render_mode;
+ GstVaapiDisplay *old_display = sink->display;
+
+ 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 || old_display != sink->display) {
+ 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");
+
+ sink->use_rotation = gst_vaapi_display_has_property(
+ sink->display, GST_VAAPI_DISPLAY_PROP_ROTATION);
+ }
+ return TRUE;
+}
+
+static gboolean
+gst_vaapisink_ensure_display_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;
+
+ /* 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(
+ 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,
+ 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;
+
+ display_rect->x += sink->render_rect.x;
+ display_rect->y += sink->render_rect.y;
+
+ 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)
+{
+ 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)
+{
+ GstVaapiDisplay * const display = sink->display;
+
+ if (!sink->window) {
+ sink->render_rect.x = 0;
+ sink->render_rect.y = 0;
+ sink->render_rect.width = width;
+ sink->render_rect.height = height;
+
+ switch (sink->display_type) {
+#if USE_GLX
+ case GST_VAAPI_DISPLAY_TYPE_GLX:
+ 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:
+ 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;
+#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", sink->display_type);
+ return FALSE;
+ }
+ }
+ return sink->window != NULL;
+}
+
+#if USE_X11
+static gboolean
+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;
+
+ gst_vaapi_display_lock(sink->display);
+ XGetGeometry(
+ gst_vaapi_display_x11_get_display(GST_VAAPI_DISPLAY_X11(sink->display)),
+ xid,
+ &rootwin,
+ &x, &y, &width, &height, &border_width, &depth
+ );
+ gst_vaapi_display_unlock(sink->display);
+
+ sink->render_rect.x = 0;
+ sink->render_rect.y = 0;
+ sink->render_rect.width = width;
+ sink->render_rect.height = height;
+
+ if ((width != sink->window_width || height != sink->window_height) &&
+ !configure_notify_event_pending(sink, xid, width, height)) {
+ if (!gst_vaapisink_ensure_display_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;
+
+ g_clear_object(&sink->window);
+
+ 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);
+ 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;
+}
+#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 )
+ gst_vaapisink_ensure_display_rect(sink, sink->render_rect.width,
+ sink->render_rect.height);
+ success = TRUE;
+
+end:
+ sink->rotation = sink->rotation_req;
+ return success;
+}
+
+static gboolean
+gst_vaapisink_start(GstBaseSink *base_sink)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
+
+ return gst_vaapisink_ensure_display(sink);
+}
+
+static gboolean
+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);
+
+ 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);
+ 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)
+ 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;
+
+ 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))
+ return 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(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);
+ 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;
+ if (!sink->render_rect.width || !sink->render_rect.height) {
+ sink->render_rect.width = win_width;
+ sink->render_rect.height = win_height;
+ }
+ GST_DEBUG("window size %ux%u", win_width, win_height);
+
+ return gst_vaapisink_ensure_display_rect(sink,
+ sink->render_rect.width,
+ sink->render_rect.height);
+}
+
+#if USE_GLX
+static void
+render_background(GstVaapiSink *sink)
+{
+ /* Original code from Mirco Muller (MacSlow):
+ <http://cgit.freedesktop.org/~macslow/gl-gst-player/> */
+ 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)
+{
+ 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(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();
+}
+
+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_show_frame_glx(
+ GstVaapiSink *sink,
+ GstVaapiSurface *surface,
+ guint flags
+)
+{
+ GstVaapiWindowGLX * const window = GST_VAAPI_WINDOW_GLX(sink->window);
+ GLenum target;
+ 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_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);
+ 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,
+ 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)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(base_sink);
+ GstVaapiVideoBuffer * const vbuffer = GST_VAAPI_VIDEO_BUFFER(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)) {
+ g_clear_object(&sink->display);
+ sink->display = g_object_ref (gst_vaapi_video_buffer_get_display (vbuffer));
+ }
+
+ 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;
+
+ 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);
+
+ if (!gst_vaapi_surface_set_subpictures_from_composition(surface,
+ composition, TRUE))
+ 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_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);
+ break;
+#endif
+ default:
+ GST_ERROR("unsupported display type %d", sink->display_type);
+ success = FALSE;
+ break;
+ }
+ if (!success)
+ return GST_FLOW_UNEXPECTED;
+
+ /* Retain VA surface until the next one is displayed */
+ if (sink->use_overlay)
+ gst_buffer_replace(&sink->video_buffer, buffer);
+ return GST_FLOW_OK;
+}
+
+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)
+{
+ gst_vaapisink_destroy(GST_VAAPISINK(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
+)
+{
+ GstVaapiSink * const sink = GST_VAAPISINK(object);
+
+ switch (prop_id) {
+ case PROP_DISPLAY_TYPE:
+ sink->display_type = g_value_get_enum(value);
+ break;
+ case PROP_FULLSCREEN:
+ sink->fullscreen = g_value_get_boolean(value);
+ break;
+ case PROP_SYNCHRONOUS:
+ sink->synchronous = 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;
+ 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_TYPE:
+ g_value_set_enum(value, sink->display_type);
+ break;
+ case PROP_FULLSCREEN:
+ g_value_set_boolean(value, sink->fullscreen);
+ break;
+ case PROP_SYNCHRONOUS:
+ g_value_set_boolean(value, sink->synchronous);
+ 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;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+ break;
+ }
+}
+
+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);
+
+ 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->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);
+
+ 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));
+
+#if USE_GLX
+ 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
+ (object_class,
+ PROP_FULLSCREEN,
+ g_param_spec_boolean("fullscreen",
+ "Fullscreen",
+ "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));
+
+ /**
+ * 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
+gst_vaapisink_init(GstVaapiSink *sink)
+{
+ sink->caps = NULL;
+ sink->display = NULL;
+ 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;
+ sink->video_par_n = 1;
+ sink->video_par_d = 1;
+ 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;
+ sink->use_overlay = FALSE;
+ sink->use_rotation = FALSE;
+ sink->render_rect.x = 0;
+ sink->render_rect.y = 0;
+ sink->render_rect.width = 0;
+ sink->render_rect.height = 0;
+}
--- /dev/null
+/*
+ * 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
+ * as published by the Free Software Foundation; either version 2.1
+ * of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along 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
+
+#include <gst/video/gstvideosink.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiwindow.h>
+#if USE_GLX
+#include <gst/vaapi/gstvaapitexture.h>
+#endif
+#include "gstvaapipluginutil.h"
+
+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, \
+ GstVaapiSinkClass))
+
+typedef struct _GstVaapiSink GstVaapiSink;
+typedef struct _GstVaapiSinkClass GstVaapiSinkClass;
+#if !USE_GLX
+typedef struct _GstVaapiTexture GstVaapiTexture;
+#endif
+
+struct _GstVaapiSink {
+ /*< private >*/
+ GstVideoSink parent_instance;
+
+ GstCaps *caps;
+ GstVaapiDisplay *display;
+ GstVaapiDisplayType display_type;
+ GstVaapiWindow *window;
+ guint window_width;
+ guint window_height;
+ GstVaapiTexture *texture;
+ GstBuffer *video_buffer;
+ guint video_width;
+ guint video_height;
+ gint video_par_n;
+ gint video_par_d;
+ GstVaapiRectangle display_rect; /* centralized video display position */
+ GstVaapiRectangle render_rect; /* user defined rendering position */
+ 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 {
+ /*< private >*/
+ GstVideoSinkClass parent_class;
+};
+
+GType
+gst_vaapisink_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GST_VAAPISINK_H */
--- /dev/null
+/*
+ * gstvaapiupload.c - VA-API video uploader
+ *
+ * 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:gstvaapiupload
+ * @short_description: A video to VA flow filter
+ *
+ * vaapiupload uploads from raw YUV pixels to VA surfaces suitable
+ * for the vaapisink element, for example.
+ */
+
+#include "config.h"
+
+#include <gst/gst.h>
+#include <gst/video/video.h>
+#include <gst/video/videocontext.h>
+#include <gst/vaapi/gstvaapivideobuffer.h>
+#include <gst/vaapi/gstvaapidebug.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"
+
+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 uploader",
+ "Filter/Converter/Video",
+ GST_PLUGIN_DESC,
+ "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
+
+/* 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));
+
+static void
+gst_vaapiupload_implements_iface_init(GstImplementsInterfaceClass *iface);
+
+static void
+gst_video_context_interface_init(GstVideoContextInterface *iface);
+
+#define GstVideoContextClass GstVideoContextInterface
+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));
+
+/*
+ * 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);
+
+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
+);
+
+/* 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 *upload = GST_VAAPIUPLOAD (context);
+ gst_vaapi_set_display (type, value, &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)
+{
+ g_clear_object(&upload->images);
+ g_clear_object(&upload->surfaces);
+ g_clear_object(&upload->display);
+}
+
+static void
+gst_vaapiupload_finalize(GObject *object)
+{
+ gst_vaapiupload_destroy(GST_VAAPIUPLOAD(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)
+{
+ 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);
+
+ 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;
+ 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_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:
+ *
+ * Selects the direct rendering level.
+ * <orderedlist>
+ * <listitem override="0">
+ * Disables direct rendering.
+ * </listitem>
+ * <listitem>
+ * Enables direct rendering to the output buffer. i.e. this
+ * tries to use a single buffer for both sink and src pads.
+ * </listitem>
+ * <listitem>
+ * Enables direct rendering to the underlying surface. i.e. with
+ * drivers supporting vaDeriveImage(), the output surface pixels
+ * will be modified directly.
+ * </listitem>
+ * </orderedlist>
+ */
+ 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
+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;
+ upload->need_manual_upload = FALSE;
+
+ /* 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);
+ g_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);
+}
+
+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_vaapiupload_ensure_display(upload))
+ return FALSE;
+ return TRUE;
+}
+
+static gboolean
+gst_vaapiupload_stop(GstBaseTransform *trans)
+{
+ GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
+
+ g_clear_object(&upload->display);
+
+ return TRUE;
+}
+
+static GstFlowReturn
+gst_vaapiupload_transform(
+ GstBaseTransform *trans,
+ GstBuffer *inbuf,
+ GstBuffer *outbuf
+)
+{
+ 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)
+ 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;
+ }
+ goto flow_ok;
+ }
+
+ image = gst_vaapi_video_pool_get_object(upload->images);
+ if (!image)
+ goto error_put_image;
+
+ if (!upload->need_manual_upload) {
+ gst_vaapi_image_update_from_buffer(image, inbuf, NULL);
+ } else { /* manually copy data to image*/
+ success = gst_vaapi_convert_buffer_to_image(image, inbuf);
+ if (!success)
+ goto error_put_image;
+ }
+
+ success = gst_vaapi_surface_put_image(surface, image);
+ gst_vaapi_video_pool_put_object(upload->images, image);
+ if (!success)
+ goto error_put_image;
+
+flow_ok:
+ FPS_CALCULATION(vaapiupload);
+ 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 *
+gst_vaapi_get_other_support_caps(GstVaapiUpload *upload)
+{
+ GstCaps *caps;
+ caps = gst_caps_from_string(GST_VIDEO_CAPS_YUV("YUY2"));
+ return caps;
+}
+
+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 (upload->display) {
+ GstCaps *allowed_caps, *inter_caps, *other_caps;
+ allowed_caps = gst_vaapi_display_get_image_caps(upload->display);
+ if (!allowed_caps)
+ return NULL;
+ /* can direct copy other YUV to va surface */
+ other_caps = gst_vaapi_get_other_support_caps(upload);
+ gst_caps_merge(allowed_caps, other_caps);
+
+ inter_caps = gst_caps_intersect(out_caps, allowed_caps);
+ gst_caps_unref(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_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);
+ }
+}
+
+typedef enum YUV_TYPE {
+ YUV_UNKOWN = 0,
+ YUV_411 = 1,
+ YUV_422 = 2,
+ YUV_444 = 4
+} YUV_TYPE;
+
+static YUV_TYPE
+_image_format_to_yuv_type(guint32 fourcc)
+{
+ switch (fourcc) {
+ case GST_MAKE_FOURCC('N','V','1','2'):
+ case GST_MAKE_FOURCC('Y','V','1','2'):
+ case GST_MAKE_FOURCC('I','4','2','0'):
+ case GST_MAKE_FOURCC('N','V','2','1'):
+ return YUV_411;
+
+ case GST_MAKE_FOURCC('Y','U','Y','2'):
+ case GST_MAKE_FOURCC('Y','V','Y','U'):
+ return YUV_422;
+
+ case GST_MAKE_FOURCC('A','Y','U','V'):
+ return YUV_UNKOWN;
+
+ default:
+ return YUV_UNKOWN;
+ }
+}
+
+static GstCaps *
+_get_nearest_caps(GstCaps *caps_list, GstCaps *src_caps)
+{
+ GstCaps *ret = NULL;
+ GstStructure *cur_struct, *tmp_struct;
+ guint32 cur_format, dest_format, tmp_format;
+ YUV_TYPE cur_type, tmp_type;
+ const GValue*tmp_val;
+ guint n_caps;
+ guint i;
+ guint min_diff, tmp_diff;
+
+ cur_struct = gst_caps_get_structure(src_caps, 0);
+ tmp_val = gst_structure_get_value (cur_struct, "format");
+ if (!tmp_val)
+ return NULL;
+
+ cur_format = gst_value_get_fourcc(tmp_val);
+ if((cur_type = _image_format_to_yuv_type(cur_format)) == YUV_UNKOWN)
+ return NULL;
+
+ n_caps = gst_caps_get_size(caps_list);
+ min_diff = 100;
+ dest_format = 0;
+ for (i = 0; i < n_caps; ++i) {
+ tmp_struct = gst_caps_get_structure(caps_list, i);
+ tmp_val = gst_structure_get_value (tmp_struct, "format");
+ if (!tmp_val)
+ continue;
+ tmp_format = gst_value_get_fourcc(tmp_val);
+ if ((tmp_type = _image_format_to_yuv_type(tmp_format)) == YUV_UNKOWN)
+ continue;
+ tmp_diff = abs(tmp_type - cur_type);
+ if (tmp_diff < min_diff) {
+ min_diff = tmp_diff;
+ dest_format = tmp_format;
+ }
+ }
+
+ if (dest_format == 0)
+ return NULL;
+
+ ret = gst_caps_copy(src_caps);
+ tmp_struct = gst_caps_get_structure(ret, 0);
+ gst_structure_set(tmp_struct, "format", GST_TYPE_FOURCC, dest_format, NULL);
+ return ret;
+}
+
+static gboolean
+gst_vaapiupload_negotiate_buffers(
+ GstVaapiUpload *upload,
+ GstCaps *incaps,
+ GstCaps *outcaps
+)
+{
+ guint dr;
+ gboolean ret = TRUE;
+ GstCaps *image_allowed_caps = NULL;
+ GstCaps *image_caps = NULL;
+
+ image_allowed_caps = gst_vaapi_display_get_image_caps(upload->display);
+ if (gst_caps_can_intersect(incaps, image_allowed_caps)) {
+ image_caps = gst_caps_ref(incaps);
+ upload->need_manual_upload = FALSE;
+ } else {
+ image_caps = _get_nearest_caps(image_allowed_caps, incaps);
+ upload->need_manual_upload = TRUE;
+ }
+
+ if (!gst_vaapiupload_ensure_image_pool(upload, image_caps))
+ goto failed;
+
+ if (!gst_vaapiupload_ensure_surface_pool(upload, outcaps))
+ goto failed;
+
+ if (upload->direct_rendering && !upload->need_manual_upload)
+ 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);
+ }
+ ret = TRUE;
+ goto end;
+
+ failed:
+ ret = FALSE;
+
+ end:
+ gst_caps_unref(image_caps);
+ gst_caps_unref(image_allowed_caps);
+ return ret;
+}
+
+static gboolean
+gst_vaapiupload_set_caps(
+ GstBaseTransform *trans,
+ GstCaps *incaps,
+ GstCaps *outcaps
+)
+{
+ GstVaapiUpload * const upload = GST_VAAPIUPLOAD(trans);
+
+ if (!gst_vaapiupload_negotiate_buffers(upload, incaps, outcaps))
+ return FALSE;
+
+ GST_INFO("set caps\nIN caps:\n%" GST_PTR_FORMAT "\nOUT caps:\n%" GST_PTR_FORMAT,
+ incaps, outcaps);
+ 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);
+ GstBuffer *buffer = NULL;
+ GstVaapiImage *image = NULL;
+ GstVaapiSurface *surface = NULL;
+ GstVaapiVideoBuffer *vbuffer;
+
+ /* already checked */
+ if (!upload->direct_rendering)
+ return GST_FLOW_OK;
+
+ /* Check if we can use direct-rendering */
+ if (!gst_vaapiupload_negotiate_buffers(upload, caps, caps))
+ goto error;
+ if (!upload->direct_rendering)
+ 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;
+ 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);
+ g_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 = NULL;
+
+ 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;
+ }
+ }
+
+ if (!buffer) {
+ buffer = gst_vaapi_video_buffer_new_from_pool(upload->surfaces);
+ if (!buffer)
+ return GST_FLOW_UNEXPECTED;
+ gst_buffer_set_caps(buffer, caps);
+ }
+
+ *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", upload->display);
+
+ if (gst_vaapi_reply_to_query (query, upload->display))
+ res = TRUE;
+ else
+ res = gst_pad_query_default (pad, query);
+
+ g_object_unref (upload);
+ return res;
+}
--- /dev/null
+/*
+ * gstvaapiupload.h - VA-API video uploader
+ *
+ * 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_VAAPIUPLOAD_H
+#define GST_VAAPIUPLOAD_H
+
+#include <gst/base/gstbasetransform.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapiimagepool.h>
+#include <gst/vaapi/gstvaapisurfacepool.h>
+#include <gst/vaapi/gstvaapivideobuffer.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;
+
+/* 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;
+ unsigned int need_manual_upload : 1;
+};
+
+struct _GstVaapiUploadClass {
+ /*< private >*/
+ GstBaseTransformClass parent_class;
+};
+
+GType
+gst_vaapiupload_get_type(void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* GST_VAAPIUPLOAD_H */
--- /dev/null
+* Mon Sep 24 2012 Yan Yin <yan.yin@intel.com> accepted/2.0_beta/20120917.204432@eadd4f0
+- decoder_h264: reduce max_dec_frame_buffering from 16 to 8
+- vaapidecode: dynamically add surface to vaapicontext.
+
+* Mon Sep 17 2012 Yan Yin <yan.yin@intel.com> accepted/2.0_beta/20120912.025253@838e26e
+- vaapisink: ensure render rect for foreign window
+- vaapisink: centralizing display_rect even in user defined render_rect
+- vaapsink: fix display properties check after display_type set
+
+* Tue Sep 11 2012 Yan Yin <yan.yin@intel.com> submit/2.0_beta/20120907.063807@d0aadd7
+- fix summary for devel pacakge
+
+* Wed Sep 05 2012 Yan Yin <yan.yin@intel.com> submit/2.0_beta/20120831.083100@c9d3506
+- fix build failure of libdrm.
+
+* Tue Aug 07 2012 Yan Yin <yan.yin@intel.com> build/2012-08-01.041209@c9c8547
+- fix wrong version number to 0.4.0.pre1
+
+* Wed Aug 01 2012 Yan Yin <yan.yin@intel.com> build/2012-08-01.041020@bc1613b
+- rebase to 0.3.8pre
+
+* Thu Jun 28 2012 Yan Yin <yan.yin@intel.com> 0.2.6@0372cfd
+- add manifest file
+
+* Tue Jun 26 2012 Yan Yin <yan.yin@intel.com> 0.2.6@f766365
+- add packaging files
+
+* Mon Jun 25 2012 Yan Yin <yan.yin@intel.com> 0.2.6@3706b26
+- fix build failure when compiling without GLX
+
+* Fri May 04 2012 Markus Lehtonen <markus.lehtonen@linux.intel.com> 0.2.6@1860d12
+- tizen build: disable docs
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+Name: gstreamer-vaapi
+Version: 0.4.0.pre1
+Release: 0
+Summary: VA-API based plugins for GStreamer and helper libraries
+Group: Multimedia/Gstreamer
+License: LGPLv2+ and GPLv2+
+URL: http://gitorious.org/vaapi/gstreamer-vaapi
+Source0: %{name}-%{version}.tar.bz2
+Source1001: packaging/gstreamer-vaapi.manifest
+BuildRequires: pkgconfig(x11)
+BuildRequires: pkgconfig(libva)
+BuildRequires: pkgconfig(gstreamer-0.10)
+BuildRequires: pkgconfig(gstreamer-basevideo-0.10)
+BuildRequires: pkgconfig(gstreamer-plugins-base-0.10)
+BuildRequires: pvr-bin-mdfld-devel
+BuildRequires: pkgconfig(libdrm)
+BuildRequires: which
+ExclusiveArch: %{ix86}
+
+%description
+Gstreamer-vaapi is 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-surface surfaces, depending
+on the underlying HW capabilities. 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 the screen.
+
+%package devel
+Summary: Development files for gstreamer-vaapi
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires: pkgconfig
+
+%description devel
+The %{name}-devel package contains libraries and header files for
+developing applications that use %{name}.
+
+%prep
+%setup -q -n %{name}-%{version}
+
+%build
+cp %{SOURCE1001} .
+
+./autogen.sh --prefix=/usr --enable-encoders
+make %{?_smp_mflags}
+
+%install
+rm -rf %{buildroot}
+make install DESTDIR=%{buildroot}
+find %{buildroot} -regex ".*\.la$" | xargs rm -f --
+find %{buildroot} -regex ".*\.a$" | xargs rm -f --
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest gstreamer-vaapi.manifest
+%defattr(-,root,root,-)
+%doc AUTHORS COPYING.LIB NEWS README
+%{_libdir}/*.so.*
+%{_libdir}/gstreamer-0.10/*.so
+
+%files devel
+%manifest gstreamer-vaapi.manifest
+%defattr(-,root,root,-)
+%doc README COPYING.LIB
+%{_includedir}/gstreamer-0.10/gst/vaapi
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/%{name}*.pc
--- /dev/null
+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_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
+
+all_pcfiles = $(all_pcfiles_in:%.pc.in=%-@GST_MAJORMINOR@.pc)
+
+pkgconfigdir = @pkgconfigdir@
+pkgconfig_DATA = $(pcfiles)
+
+EXTRA_DIST = $(all_pcfiles_in)
+
+DISTCLEANFILES = $(all_pcfiles)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+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}
--- /dev/null
+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@
--- /dev/null
+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}
--- /dev/null
+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_PKGNAME@
+Version: @VERSION@
+Libs: -L${libdir} -lgstvaapi-x11-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@
+Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@
--- /dev/null
+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_PKGNAME@
+Version: @VERSION@
+Libs: -L${libdir} -lgstvaapi-@GST_MAJORMINOR@ @LIBVA_EXTRA_LIBS@
+Cflags: -I${includedir} @LIBVA_EXTRA_CFLAGS@
--- /dev/null
+noinst_PROGRAMS = \
+ test-decode \
+ test-display \
+ test-surfaces \
+ test-windows \
+ test-subpicture \
+ $(NULL)
+
+if USE_GLX
+noinst_PROGRAMS += \
+ test-textures \
+ $(NULL)
+endif
+
+TEST_CFLAGS = \
+ -DGST_USE_UNSTABLE_API \
+ -I$(top_srcdir)/gst-libs \
+ $(LIBVA_CFLAGS) \
+ $(GST_CFLAGS) \
+ $(NULL)
+
+TEST_LIBS = \
+ $(LIBVA_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 += \
+ $(LIBVA_X11_LIBS) \
+ $(X11_LIBS) \
+ $(top_builddir)/gst-libs/gst/vaapi/libgstvaapi-x11-@GST_MAJORMINOR@.la
+endif
+
+if USE_GLX
+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
+
+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
+
+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)
+libutils_la_CFLAGS = $(TEST_CFLAGS)
+
+test_decode_SOURCES = test-decode.c $(test_codecs_source_c)
+test_decode_CFLAGS = $(TEST_CFLAGS)
+test_decode_LDADD = libutils.la $(TEST_LIBS)
+
+test_display_SOURCES = test-display.c
+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_subpicture_SOURCES = test-subpicture.c test-subpicture-data.c
+test_subpicture_CFLAGS = $(TEST_CFLAGS)
+test_subpicture_LDADD = libutils.la $(TEST_LIBS)
+
+test_windows_SOURCES = test-windows.c
+test_windows_CFLAGS = $(TEST_CFLAGS)
+test_windows_LDADD = libutils.la $(TEST_LIBS)
+
+test_textures_SOURCES = test-textures.c
+test_textures_CFLAGS = $(TEST_CFLAGS)
+test_textures_LDADD = libutils.la $(TEST_LIBS)
+
+EXTRA_DIST = \
+ test-subpicture-data.h \
+ $(test_utils_source_h) \
+ $(NULL)
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
--- /dev/null
+/*
+ * image.c - Image utilities for the tests
+ *
+ * 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
+*/
+
+#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);
+}
+
+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;
+}
--- /dev/null
+/*
+ * image.h - Image utilities for the tests
+ *
+ * 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 IMAGE_H
+#define IMAGE_H
+
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/vaapi/gstvaapisurface.h>
+
+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
+);
+
+gboolean
+image_upload(GstVaapiImage *image, GstVaapiSurface *surface);
+
+#endif /* IMAGE_H */
--- /dev/null
+/*
+ * 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 <string.h>
+#include <gst/gst.h>
+#if USE_DRM
+# include <gst/vaapi/gstvaapidisplay_drm.h>
+# include <gst/vaapi/gstvaapiwindow_drm.h>
+#endif
+#if USE_X11
+# include <gst/vaapi/gstvaapidisplay_x11.h>
+# include <gst/vaapi/gstvaapiwindow_x11.h>
+#endif
+#if USE_GLX
+# include <gst/vaapi/gstvaapidisplay_glx.h>
+# include <gst/vaapi/gstvaapiwindow_glx.h>
+#endif
+#if USE_WAYLAND
+# include <gst/vaapi/gstvaapidisplay_wayland.h>
+# include <gst/vaapi/gstvaapiwindow_wayland.h>
+#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,
+ gst_vaapi_window_x11_new
+ },
+#endif
+#if USE_GLX
+ { "glx",
+ 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, }
+};
+
+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);
+}
--- /dev/null
+/*
+ * 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 <glib.h>
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiwindow.h>
+
+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 */
--- /dev/null
+/*
+ * test-decode.c - Test GstVaapiDecoder
+ *
+ * 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 <string.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapidecoder_h264.h>
+#include <gst/vaapi/gstvaapidecoder_jpeg.h>
+#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
+#include <gst/vaapi/gstvaapidecoder_vc1.h>
+#include "test-jpeg.h"
+#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
+
+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(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");
+ 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[])
+{
+ GstVaapiDisplay *display, *display2;
+ GstVaapiWindow *window;
+ GstVaapiDecoder *decoder;
+ GstCaps *decoder_caps;
+ GstStructure *structure;
+ GstVaapiDecoderStatus status;
+ const CodecDefs *codec;
+ GstBuffer *buffer;
+ GstVaapiSurfaceProxy *proxy;
+ VideoDecodeInfo info;
+
+ 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 (!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 = 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 = g_object_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");
+
+ 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_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);
+
+ 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);
+
+ 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();
+
+ g_object_unref(proxy);
+ g_object_unref(decoder);
+ g_object_unref(window);
+ g_object_unref(display);
+ g_object_unref(display2);
+ g_free(g_codec_str);
+ video_output_exit();
+ return 0;
+}
--- /dev/null
+/*
+ * test-decode.h - Test GstVaapiDecoder
+ *
+ * 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 TEST_DECODE_H
+#define TEST_DECODE_H
+
+#include <gst/vaapi/gstvaapidisplay.h>
+#include <gst/vaapi/gstvaapiprofile.h>
+
+typedef struct _VideoDecodeInfo VideoDecodeInfo;
+struct _VideoDecodeInfo {
+ GstVaapiProfile profile;
+ guint width;
+ guint height;
+ const guchar *data;
+ guint data_size;
+};
+
+#endif /* TEST_DECODE_H */
--- /dev/null
+/*
+ * test-display.c - Test GstVaapiDisplayX11
+ *
+ * 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
+*/
+
+#include "config.h"
+#include <gst/video/video.h>
+#if USE_DRM
+# include <gst/vaapi/gstvaapidisplay_drm.h>
+# include <va/va_drm.h>
+# include <fcntl.h>
+# include <unistd.h>
+# ifndef DRM_DEVICE_PATH
+# define DRM_DEVICE_PATH "/dev/dri/card0"
+# endif
+#endif
+#if USE_X11
+# include <gst/vaapi/gstvaapidisplay_x11.h>
+#endif
+#if USE_GLX
+# include <gst/vaapi/gstvaapidisplay_glx.h>
+#endif
+#if USE_WAYLAND
+# include <gst/vaapi/gstvaapidisplay_wayland.h>
+#endif
+
+#ifdef HAVE_VA_VA_GLX_H
+# include <va/va_glx.h>
+#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)
+{
+ 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);
+
+ 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");
+ }
+}
+
+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 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;
+
+ 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_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_format_caps(caps, "subpicture");
+ gst_caps_unref(caps);
+
+ dump_properties(display);
+}
+
+int
+main(int argc, char *argv[])
+{
+ GstVaapiDisplay *display;
+ guint width, height, par_n, par_d;
+
+ 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_info(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_info(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_info(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");
+ g_print("#\n");
+ {
+ display = gst_vaapi_display_x11_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_info(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");
+ {
+ Display *x11_display;
+
+ 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_info(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() [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");
+
+ 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_info(display);
+ g_object_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");
+
+ 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);
+ 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");
+ {
+ 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);
+ g_object_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;
+
+ 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_info(display);
+ g_object_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");
+
+ 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);
+ g_object_unref(display);
+ }
+ g_print("\n");
+#endif
+
+ gst_deinit();
+ return 0;
+}
--- /dev/null
+/*
+ * test-h264.c - H.264 test data
+ *
+ * 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
+*/
+
+#include "test-h264.h"
+
+#define H264_CLIP_WIDTH 320
+#define H264_CLIP_HEIGHT 240
+#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[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_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;
+}
--- /dev/null
+/*
+ * test-h264.h - H.264 test data
+ *
+ * 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 TEST_H264_H
+#define TEST_H264_H
+
+#include <glib.h>
+#include "test-decode.h"
+
+void h264_get_video_info(VideoDecodeInfo *info);
+
+#endif /* TEST_H264_H */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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 <glib.h>
+#include "test-decode.h"
+
+void jpeg_get_video_info(VideoDecodeInfo *info);
+
+#endif /* TEST_JPEG_H */
--- /dev/null
+/*
+ * test-mpeg2.c - MPEG-2 test data
+ *
+ * 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
+*/
+
+#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_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;
+}
--- /dev/null
+/*
+ * test-mpeg2.h - MPEG-2 test data
+ *
+ * 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 TEST_MPEG2_H
+#define TEST_MPEG2_H
+
+#include <glib.h>
+#include "test-decode.h"
+
+void mpeg2_get_video_info(VideoDecodeInfo *info);
+
+#endif /* TEST_MPEG2_H */
--- /dev/null
+/*
+ * test-subpicture-data.c - subpicture data
+ *
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * 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;
+}
--- /dev/null
+/*
+ * test-subpicture-data.h - subpicture data
+ *
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * 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 <glib.h>
+#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*/
--- /dev/null
+/*
+ * test-subpicture.c - Test GstVaapiSubpicture
+ *
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * 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 <string.h>
+#include <gst/vaapi/gstvaapidecoder.h>
+#include <gst/vaapi/gstvaapidecoder_mpeg2.h>
+#include <gst/vaapi/gstvaapisurface.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");
+ 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, }
+};
+
+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[])
+{
+ GstVaapiDisplay *display;
+ GstVaapiWindow *window;
+ GstVaapiDecoder *decoder = NULL;
+ GstCaps *decoder_caps;
+ GstStructure *structure;
+ GstVaapiDecoderStatus status;
+ const CodecDefs *codec;
+ GstBuffer *buffer;
+ GstVaapiSurfaceProxy *proxy;
+ GstVaapiSurface *surface;
+ VideoDecodeInfo info;
+ VideoSubpictureInfo subinfo;
+ GstVaapiImage *subtitle_image;
+ GstVaapiSubpicture *subpicture;
+ GstCaps *argbcaps;
+ GstVaapiRectangle sub_rect;
+ guint surf_width, surf_height;
+
+ 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 (!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);
+
+ 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");
+
+ 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);
+ if (!decoder)
+ g_error("could not create video 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);
+
+ 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, 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_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);
+
+ 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);
+
+ /* 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");
+
+ 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);
+ video_output_exit();
+ return 0;
+}
--- /dev/null
+/*
+ * test-surfaces.c - Test GstVaapiSurface and GstVaapiSurfacePool
+ *
+ * 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
+ */
+
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapisurfacepool.h>
+#include "output.h"
+
+#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[])
+{
+ 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;
+ static const guint height = 240;
+
+ 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");
+
+ 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_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));
+
+ g_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");
+
+ 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 %" GST_VAAPI_ID_FORMAT " from pool\n",
+ GST_VAAPI_ID_ARGS(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 %" 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;
+ }
+
+ 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_caps_unref(caps);
+ g_print("unref pool\n");
+ g_object_unref(pool);
+ g_print("unref surface\n");
+ g_object_unref(surface);
+ video_output_exit();
+ return 0;
+}
--- /dev/null
+/*
+ * test-textures.c - Test GstVaapiTexture
+ *
+ * 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
+*/
+
+#include <gst/vaapi/gstvaapidisplay_glx.h>
+#include <gst/vaapi/gstvaapiwindow_glx.h>
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapiimage.h>
+#include <gst/vaapi/gstvaapitexture.h>
+#include "image.h"
+
+static inline void pause(void)
+{
+ g_print("Press any key to continue...\n");
+ 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;
+ 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;
+
+ gst_init(&argc, &argv);
+
+ 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");
+
+ 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);
+
+ 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_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();
+ return 0;
+}
--- /dev/null
+/*
+ * test-vc1.c - VC-1 test data
+ *
+ * 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
+*/
+
+#include "test-vc1.h"
+
+#define VC1_CLIP_WIDTH 293
+#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] = {
+ 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)
+{
+ 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;
+}
--- /dev/null
+/*
+ * test-vc1.h - VC-1 test data
+ *
+ * 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 TEST_VC1_H
+#define TEST_VC1_H
+
+#include <glib.h>
+#include "test-decode.h"
+
+void vc1_get_video_info(VideoDecodeInfo *info);
+
+#endif /* TEST_VC1_H */
--- /dev/null
+/*
+ * test-windows.c - Test GstVaapiWindow
+ *
+ * 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
+*/
+
+#include "config.h"
+#include <gst/vaapi/gstvaapisurface.h>
+#include <gst/vaapi/gstvaapiimage.h>
+#if USE_DRM
+# include <gst/vaapi/gstvaapidisplay_drm.h>
+# include <gst/vaapi/gstvaapiwindow_drm.h>
+#endif
+#if USE_X11
+# include <gst/vaapi/gstvaapidisplay_x11.h>
+# include <gst/vaapi/gstvaapiwindow_x11.h>
+#endif
+#if USE_WAYLAND
+# include <gst/vaapi/gstvaapidisplay_wayland.h>
+# include <gst/vaapi/gstvaapiwindow_wayland.h>
+#endif
+#include "image.h"
+
+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)
+{
+ 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,
+ 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
+ };
+
+ 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];
+
+ image = image_generate(display, format, width, height);
+ if (!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");
+
+ 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_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)
+ 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");
+ {
+ window = gst_vaapi_window_x11_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_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);
+
+ 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");
+
+ 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);
+ XUnmapWindow(dpy, win);
+ XDestroyWindow(dpy, win);
+ }
+
+ 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;
+}