include ext/codecparsers instead of git submodule
authorZhao Halley <halley.zhao@intel.com>
Thu, 21 Mar 2013 06:22:12 +0000 (14:22 +0800)
committerZhao Halley <halley.zhao@intel.com>
Thu, 21 Mar 2013 06:22:40 +0000 (14:22 +0800)
    this part can't be handled by git patch:
    1. git rm .gitmodules # or update it to remove corresponding module
    2. # Delete the relevant section from .git/config
    3. git rm -r --cached ext/codecparsers # (no trailing slash)
    4. rm -rf ext/codecparsers/.git
    4. git add ext/codecparsers
    5. git commit -a -m "include ext/codecparsers instead of git submodule"

31 files changed:
.gitmodules [deleted file]
ext/codecparsers [deleted submodule]
ext/codecparsers/.gitignore [new file with mode: 0644]
ext/codecparsers/COPYING.LIB [new file with mode: 0644]
ext/codecparsers/INSTALL [new file with mode: 0644]
ext/codecparsers/Makefile.am [new file with mode: 0644]
ext/codecparsers/TAG [new file with mode: 0644]
ext/codecparsers/autogen.sh [new file with mode: 0755]
ext/codecparsers/configure.ac [new file with mode: 0644]
ext/codecparsers/gst-libs/Makefile.am [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/Makefile.am [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/Makefile.am [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gsth264parser.c [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gsth264parser.h [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstjpegparser.c [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstjpegparser.h [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstmpeg4parser.c [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstmpeg4parser.h [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstmpegvideoparser.c [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstmpegvideoparser.h [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstvc1parser.c [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/gstvc1parser.h [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/parserutils.c [new file with mode: 0644]
ext/codecparsers/gst-libs/gst/codecparsers/parserutils.h [new file with mode: 0644]
ext/codecparsers/tests/Makefile.am [new file with mode: 0644]
ext/codecparsers/tests/check/Makefile.am [new file with mode: 0644]
ext/codecparsers/tests/check/libs/.gitignore [new file with mode: 0644]
ext/codecparsers/tests/check/libs/Makefile.am [new file with mode: 0644]
ext/codecparsers/tests/check/libs/h264parser.c [new file with mode: 0644]
ext/codecparsers/tests/check/libs/mpegvideoparser.c [new file with mode: 0644]
ext/codecparsers/tests/check/libs/vc1parser.c [new file with mode: 0644]

diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644 (file)
index e40ceed..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-[submodule "ext/codecparsers"]
-       path = ext/codecparsers
-       url = git://gitorious.org/vaapi/gstreamer-codecparsers.git
diff --git a/ext/codecparsers b/ext/codecparsers
deleted file mode 160000 (submodule)
index b8efe57..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit b8efe57d706b90c7c0e0d55d5a7ac75b888987ab
diff --git a/ext/codecparsers/.gitignore b/ext/codecparsers/.gitignore
new file mode 100644 (file)
index 0000000..de0209b
--- /dev/null
@@ -0,0 +1,28 @@
+aclocal.m4
+autom4te.cache
+config.guess
+config.h*
+config.log
+config.status
+config.sub
+configure
+install-sh
+libtool
+ltmain.sh
+missing
+mkinstalldirs
+stamp-h
+stamp-h.in
+stamp-h1
+
+/m4
+
+*.la
+*.lo
+*.o
+*.swp
+*~
+.deps
+.libs
+Makefile
+Makefile.in
diff --git a/ext/codecparsers/COPYING.LIB b/ext/codecparsers/COPYING.LIB
new file mode 100644 (file)
index 0000000..eb685a5
--- /dev/null
@@ -0,0 +1,481 @@
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+                      Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+                    675 Mass Ave, Cambridge, MA 02139, 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 library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+                           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 Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the 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 a program 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.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+\f
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  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, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+\f
+                 GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+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 compile 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) 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.
+
+    c) 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.
+
+    d) 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 source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  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 to
+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 Library 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
+     Appendix: 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 Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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!
diff --git a/ext/codecparsers/INSTALL b/ext/codecparsers/INSTALL
new file mode 100644 (file)
index 0000000..b42a17a
--- /dev/null
@@ -0,0 +1,182 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
diff --git a/ext/codecparsers/Makefile.am b/ext/codecparsers/Makefile.am
new file mode 100644 (file)
index 0000000..63df8d2
--- /dev/null
@@ -0,0 +1,11 @@
+ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
+
+AUTOMAKE_OPTIONS = foreign
+
+SUBDIRS = gst-libs tests
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = \
+       aclocal.m4 compile config.guess config.sub \
+       configure depcomp install-sh ltmain.sh     \
+       Makefile.in missing config.h.in
diff --git a/ext/codecparsers/TAG b/ext/codecparsers/TAG
new file mode 100644 (file)
index 0000000..f436908
--- /dev/null
@@ -0,0 +1 @@
+10639eb88972bf89656af694b8bf8c4b41255c69
\ No newline at end of file
diff --git a/ext/codecparsers/autogen.sh b/ext/codecparsers/autogen.sh
new file mode 100755 (executable)
index 0000000..e5a49c4
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+
+PROJECT="codecparsers"
+
+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
+
+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
diff --git a/ext/codecparsers/configure.ac b/ext/codecparsers/configure.ac
new file mode 100644 (file)
index 0000000..dd41609
--- /dev/null
@@ -0,0 +1,100 @@
+# codecparsers package version number
+m4_define([gst_codecparsers_major_version], [0])
+m4_define([gst_codecparsers_minor_version], [10])
+m4_define([gst_codecparsers_micro_version], [23])
+m4_define([gst_codecparsers_pre_version],   [1])
+m4_define([gst_codecparsers_version],
+          [gst_codecparsers_major_version.gst_codecparsers_minor_version.gst_codecparsers_micro_version])
+m4_if(gst_codecparsers_pre_version, [0], [], [
+m4_append([gst_codecparsers_version], gst_codecparsers_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], [36])
+m4_define([gst_major_minor_version],
+          [gst_major_version.gst_minor_version])
+m4_define([gst_version],
+          [gst_major_version.gst_minor_version.gst_micro_version])
+
+# gst plugins-base version number
+m4_define([gst_plugins_base_major_version], [0])
+m4_define([gst_plugins_base_minor_version], [10])
+m4_define([gst_plugins_base_micro_version], [31])
+m4_define([gst_plugins_base_version],
+          [gst_plugins_base_major_version.gst_plugins_base_minor_version.gst_plugins_base_micro_version])
+
+AC_PREREQ([2.58])
+AC_INIT([gst_codecparsers], [gst_codecparsers_version],
+    [gwenole.beauchesne@intel.com],
+    [gstreamer-codecparsers])
+
+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([1.9 tar-ustar no-dist-gzip dist-bzip2])
+
+dnl Versions for GStreamer and plugins-base
+GST_MAJORMINOR=gst_major_minor_version
+GST_API_VERSION=$GST_MAJORMINOR
+GST_VERSION_REQUIRED=gst_version
+GST_PLUGINS_BASE_VERSION_REQUIRED=gst_plugins_base_version
+AC_SUBST(GST_MAJORMINOR)
+AC_SUBST(GST_API_VERSION)
+AC_SUBST(GST_VERSION_REQUIRED)
+AC_SUBST(GST_PLUGINS_BASE_VERSION_REQUIRED)
+
+dnl Use pretty build output with automake >= 1.11
+m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])], [
+  AM_DEFAULT_VERBOSITY=1
+  AC_SUBST(AM_DEFAULT_VERBOSITY)
+])
+
+dnl Check for tools
+AC_PROG_CC
+AM_PROG_CC_C_O
+
+dnl Initialize libtool
+LT_PREREQ([2.2])
+LT_INIT
+
+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 GStreamer Core
+PKG_CHECK_MODULES([GST],       [gstreamer-$GST_MAJORMINOR >= gst_version])
+PKG_CHECK_MODULES([GST_BASE],  [gstreamer-base-$GST_MAJORMINOR >= gst_version])
+PKG_CHECK_MODULES([GST_CHECK], [gstreamer-check-$GST_MAJORMINOR])
+
+dnl GST_ALL_LDFLAGS:
+dnl LDFLAGS really should only contain flags, not libs - they get added before
+dnl whatevertarget_LIBS and -L flags here affect the rest of the linking
+GST_ALL_LDFLAGS="-no-undefined"
+AC_SUBST(GST_ALL_LDFLAGS)
+
+AC_CONFIG_FILES([
+    Makefile
+    gst-libs/Makefile
+    gst-libs/gst/Makefile
+    gst-libs/gst/codecparsers/Makefile
+    tests/Makefile
+    tests/check/Makefile
+    tests/check/libs/Makefile
+])
+AC_OUTPUT
diff --git a/ext/codecparsers/gst-libs/Makefile.am b/ext/codecparsers/gst-libs/Makefile.am
new file mode 100644 (file)
index 0000000..d5356a6
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = gst
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/ext/codecparsers/gst-libs/gst/Makefile.am b/ext/codecparsers/gst-libs/gst/Makefile.am
new file mode 100644 (file)
index 0000000..125d345
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = codecparsers
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/Makefile.am b/ext/codecparsers/gst-libs/gst/codecparsers/Makefile.am
new file mode 100644 (file)
index 0000000..74ab273
--- /dev/null
@@ -0,0 +1,45 @@
+lib_LTLIBRARIES = libgstcodecparsers-@GST_API_VERSION@.la
+
+libgstcodecparsers_@GST_API_VERSION@_la_SOURCES = \
+       gstmpegvideoparser.c gsth264parser.c gstvc1parser.c gstmpeg4parser.c \
+       gstjpegparser.c \
+       parserutils.c
+
+libgstcodecparsers_@GST_API_VERSION@includedir = \
+       $(includedir)/gstreamer-@GST_API_VERSION@/gst/codecparsers
+
+noinst_HEADERS = parserutils.h
+
+libgstcodecparsers_@GST_API_VERSION@include_HEADERS = \
+       gstmpegvideoparser.h gsth264parser.h gstvc1parser.h gstmpeg4parser.h \
+       gstjpegparser.h
+
+libgstcodecparsers_@GST_API_VERSION@_la_CFLAGS = \
+       $(GST_PLUGINS_BAD_CFLAGS) \
+       -DGST_USE_UNSTABLE_API \
+       $(GST_CFLAGS)
+
+libgstcodecparsers_@GST_API_VERSION@_la_LIBADD = \
+       $(GST_BASE_LIBS) \
+       $(GST_LIBS)
+
+libgstcodecparsers_@GST_API_VERSION@_la_LDFLAGS = \
+       $(GST_LIB_LDFLAGS) \
+       $(GST_ALL_LDFLAGS) \
+       $(GST_LT_LDFLAGS)
+
+Android.mk:  $(BUILT_SOURCES) Makefile.am
+       androgenizer -:PROJECT libgstcodecparsers -:STATIC libgstcodecparsers-@GST_API_VERSION@ \
+        -:TAGS eng debug \
+         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
+        -:SOURCES $(libgstcodecparsers_@GST_API_VERSION@_la_SOURCES) \
+         $(built_sources) \
+        -:CFLAGS $(DEFS) $(libgstcodecparsers_@GST_API_VERSION@_la_CFLAGS) \
+        -:LDFLAGS $(libgstcodecparsers_@GST_API_VERSION@_la_LDFLAGS) \
+                  $(libgstcodecparsers@GST_API_VERSION@_la_LIBADD) \
+                  -ldl \
+        -:HEADER_TARGET gstreamer-@GST_API_VERSION@/gst/codecparsers \
+        -:HEADERS $(libgstcodecparsersinclude_HEADERS) \
+         $(built_headers) \
+        -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
+       > $@
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gsth264parser.c b/ext/codecparsers/gst-libs/gst/codecparsers/gsth264parser.c
new file mode 100644 (file)
index 0000000..0da1006
--- /dev/null
@@ -0,0 +1,1982 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * Some bits C-c,C-v'ed and s/4/3 from h264parse and videoparsers/h264parse.c:
+ *    Copyright (C) <2010> Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+ *    Copyright (C) <2010> Collabora Multimedia
+ *    Copyright (C) <2010> Nokia Corporation
+ *
+ *    (C) 2005 Michal Benes <michal.benes@itonis.tv>
+ *    (C) 2008 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gsth264parser
+ * @short_description: Convenience library for h264 video
+ * bitstream parsing.
+ *
+ * It offers you bitstream parsing in AVC mode or not. To identify Nals in a bitstream and
+ * parse its headers, you should call:
+ * <itemizedlist>
+ *   <listitem>
+ *      #gst_h264_parser_identify_nalu to identify the following nalu in not AVC bitstreams
+ *   </listitem>
+ *   <listitem>
+ *      #gst_h264_parser_identify_nalu_avc to identify the nalu in AVC bitstreams
+ *   </listitem>
+ * </itemizedlist>
+ *
+ * Then, depending on the #GstH264NalUnitType of the newly parsed #GstH264NalUnit, you should
+ * call the differents functions to parse the structure:
+ * <itemizedlist>
+ *   <listitem>
+ *      From #GST_H264_NAL_SLICE to #GST_H264_NAL_SLICE_IDR: #gst_h264_parser_parse_slice_hdr
+ *   </listitem>
+ *   <listitem>
+ *      #GST_H264_NAL_SEI: #gst_h264_parser_parse_sei
+ *   </listitem>
+ *   <listitem>
+ *      #GST_H264_NAL_SPS: #gst_h264_parser_parse_sps
+ *   </listitem>
+ *   <listitem>
+ *      #GST_H264_NAL_PPS: #gst_h264_parser_parse_pps
+ *   </listitem>
+ *   <listitem>
+ *      Any other: #gst_h264_parser_parse_nal
+ *   </listitem>
+ * </itemizedlist>
+ *
+ * Note: You should always call gst_h264_parser_parse_nal if you don't actually need
+ * #GstH264NalUnitType to be parsed for your personnal use, in order to guarantee that the
+ * #GstH264NalParser is always up to date.
+ *
+ * For more details about the structures, look at the ITU-T H.264 and ISO/IEC 14496-10 â€“ MPEG-4
+ * Part 10 specifications, you can download them from:
+ *
+ * <itemizedlist>
+ *   <listitem>
+ *     ITU-T H.264: http://www.itu.int/rec/T-REC-H.264
+ *   </listitem>
+ *   <listitem>
+ *     ISO/IEC 14496-10: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=56538
+ *   </listitem>
+ * </itemizedlist>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "gsth264parser.h"
+
+#include <gst/base/gstbytereader.h>
+#include <gst/base/gstbitreader.h>
+#include <string.h>
+
+GST_DEBUG_CATEGORY (h264_parser_debug);
+#define GST_CAT_DEFAULT h264_parser_debug
+
+/**** Default scaling_lists according to Table 7-2 *****/
+static const guint8 default_4x4_intra[16] = {
+  6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32,
+  32, 37, 37, 42
+};
+
+static const guint8 default_4x4_inter[16] = {
+  10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27,
+  27, 30, 30, 34
+};
+
+static const guint8 default_8x8_intra[64] = {
+  6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18,
+  18, 18, 18, 23, 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27,
+  27, 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, 31, 33,
+  33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42
+};
+
+static const guint8 default_8x8_inter[64] = {
+  9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19,
+  19, 19, 19, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24,
+  24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, 27, 28,
+  28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35
+};
+
+static const guint8 zigzag_8x8[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
+};
+
+static const guint8 zigzag_4x4[16] = {
+  0, 1, 4, 8,
+  5, 2, 3, 6,
+  9, 12, 13, 10,
+  7, 11, 14, 15,
+};
+
+typedef struct
+{
+  guint par_n, par_d;
+} PAR;
+
+/* Table E-1 - Meaning of sample aspect ratio indicator (1..16) */
+static PAR aspect_ratios[17] = {
+  {0, 0},
+  {1, 1},
+  {12, 11},
+  {10, 11},
+  {16, 11},
+  {40, 33},
+  {24, 11},
+  {20, 11},
+  {32, 11},
+  {80, 33},
+  {18, 11},
+  {15, 11},
+  {64, 33},
+  {160, 99},
+  {4, 3},
+  {3, 2},
+  {2, 1}
+};
+
+/* Compute Ceil(Log2(v)) */
+/* Derived from branchless code for integer log2(v) from:
+   <http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog> */
+static guint
+ceil_log2 (guint32 v)
+{
+  guint r, shift;
+
+  v--;
+  r = (v > 0xFFFF) << 4;
+  v >>= r;
+  shift = (v > 0xFF) << 3;
+  v >>= shift;
+  r |= shift;
+  shift = (v > 0xF) << 2;
+  v >>= shift;
+  r |= shift;
+  shift = (v > 0x3) << 1;
+  v >>= shift;
+  r |= shift;
+  r |= (v >> 1);
+  return r + 1;
+}
+
+/****** Nal parser ******/
+
+typedef struct
+{
+  const guint8 *data;
+  guint size;
+
+  guint n_epb;                  /* Number of emulation prevention bytes */
+  guint byte;                   /* Byte position */
+  guint bits_in_cache;          /* bitpos in the cache of next bit */
+  guint8 first_byte;
+  guint64 cache;                /* cached bytes */
+} NalReader;
+
+static void
+nal_reader_init (NalReader * nr, const guint8 * data, guint size)
+{
+  nr->data = data;
+  nr->size = size;
+  nr->n_epb = 0;
+
+  nr->byte = 0;
+  nr->bits_in_cache = 0;
+  /* fill with something other than 0 to detect emulation prevention bytes */
+  nr->first_byte = 0xff;
+  nr->cache = 0xff;
+}
+
+static inline gboolean
+nal_reader_read (NalReader * nr, guint nbits)
+{
+  if (G_UNLIKELY (nr->byte * 8 + (nbits - nr->bits_in_cache) > nr->size * 8)) {
+    GST_DEBUG ("Can not read %u bits, bits in cache %u, Byte * 8 %u, size in "
+        "bits %u", nbits, nr->bits_in_cache, nr->byte * 8, nr->size * 8);
+    return FALSE;
+  }
+
+  while (nr->bits_in_cache < nbits) {
+    guint8 byte;
+    gboolean check_three_byte;
+
+    check_three_byte = TRUE;
+  next_byte:
+    if (G_UNLIKELY (nr->byte >= nr->size))
+      return FALSE;
+
+    byte = nr->data[nr->byte++];
+
+    /* check if the byte is a emulation_prevention_three_byte */
+    if (check_three_byte && byte == 0x03 && nr->first_byte == 0x00 &&
+        ((nr->cache & 0xff) == 0)) {
+      /* next byte goes unconditionally to the cache, even if it's 0x03 */
+      check_three_byte = FALSE;
+      nr->n_epb++;
+      goto next_byte;
+    }
+    nr->cache = (nr->cache << 8) | nr->first_byte;
+    nr->first_byte = byte;
+    nr->bits_in_cache += 8;
+  }
+
+  return TRUE;
+}
+
+static inline gboolean
+nal_reader_skip (NalReader * nr, guint nbits)
+{
+  if (G_UNLIKELY (!nal_reader_read (nr, nbits)))
+    return FALSE;
+
+  nr->bits_in_cache -= nbits;
+
+  return TRUE;
+}
+
+static inline gboolean
+nal_reader_skip_to_byte (NalReader * nr)
+{
+  if (nr->bits_in_cache == 0) {
+    if (G_LIKELY ((nr->size - nr->byte) > 0))
+      nr->byte++;
+    else
+      return FALSE;
+  }
+
+  nr->bits_in_cache = 0;
+
+  return TRUE;
+}
+
+static inline guint
+nal_reader_get_pos (const NalReader * nr)
+{
+  return nr->byte * 8 - nr->bits_in_cache;
+}
+
+static inline guint
+nal_reader_get_remaining (const NalReader * nr)
+{
+  return (nr->size - nr->byte) * 8 + nr->bits_in_cache;
+}
+
+static inline guint
+nal_reader_get_epb_count (const NalReader * nr)
+{
+  return nr->n_epb;
+}
+
+#define GST_NAL_READER_READ_BITS(bits) \
+static gboolean \
+nal_reader_get_bits_uint##bits (NalReader *nr, guint##bits *val, guint nbits) \
+{ \
+  guint shift; \
+  \
+  if (!nal_reader_read (nr, nbits)) \
+    return FALSE; \
+  \
+  /* bring the required bits down and truncate */ \
+  shift = nr->bits_in_cache - nbits; \
+  *val = nr->first_byte >> shift; \
+  \
+  *val |= nr->cache << (8 - shift); \
+  /* mask out required bits */ \
+  if (nbits < bits) \
+    *val &= ((guint##bits)1 << nbits) - 1; \
+  \
+  nr->bits_in_cache = shift; \
+  \
+  return TRUE; \
+} \
+
+GST_NAL_READER_READ_BITS (8);
+GST_NAL_READER_READ_BITS (16);
+GST_NAL_READER_READ_BITS (32);
+
+static gboolean
+nal_reader_get_ue (NalReader * nr, guint32 * val)
+{
+  guint i = 0;
+  guint8 bit;
+  guint32 value;
+
+  if (G_UNLIKELY (!nal_reader_get_bits_uint8 (nr, &bit, 1))) {
+
+    return FALSE;
+  }
+
+  while (bit == 0) {
+    i++;
+    if G_UNLIKELY
+      ((!nal_reader_get_bits_uint8 (nr, &bit, 1)))
+          return FALSE;
+  }
+
+  if (G_UNLIKELY (i > 32))
+    return FALSE;
+
+  if (G_UNLIKELY (!nal_reader_get_bits_uint32 (nr, &value, i)))
+    return FALSE;
+
+  *val = (1 << i) - 1 + value;
+
+  return TRUE;
+}
+
+static inline gboolean
+nal_reader_get_se (NalReader * nr, gint32 * val)
+{
+  guint32 value;
+
+  if (G_UNLIKELY (!nal_reader_get_ue (nr, &value)))
+    return FALSE;
+
+  if (value % 2)
+    *val = (value / 2) + 1;
+  else
+    *val = -(value / 2);
+
+  return TRUE;
+}
+
+#define CHECK_ALLOWED(val, min, max) { \
+  if (val < min || val > max) { \
+    GST_WARNING ("value not in allowed range. value: %d, range %d-%d", \
+                     val, min, max); \
+    goto error; \
+  } \
+}
+
+#define READ_UINT8(nr, val, nbits) { \
+  if (!nal_reader_get_bits_uint8 (nr, &val, nbits)) { \
+    GST_WARNING ("failed to read uint8, nbits: %d", nbits); \
+    goto error; \
+  } \
+}
+
+#define READ_UINT16(nr, val, nbits) { \
+  if (!nal_reader_get_bits_uint16 (nr, &val, nbits)) { \
+  GST_WARNING ("failed to read uint16, nbits: %d", nbits); \
+    goto error; \
+  } \
+}
+
+#define READ_UINT32(nr, val, nbits) { \
+  if (!nal_reader_get_bits_uint32 (nr, &val, nbits)) { \
+  GST_WARNING ("failed to read uint32, nbits: %d", nbits); \
+    goto error; \
+  } \
+}
+
+#define READ_UINT64(nr, val, nbits) { \
+  if (!nal_reader_get_bits_uint64 (nr, &val, nbits)) { \
+    GST_WARNING ("failed to read uint32, nbits: %d", nbits); \
+    goto error; \
+  } \
+}
+
+#define READ_UE(nr, val) { \
+  if (!nal_reader_get_ue (nr, &val)) { \
+    GST_WARNING ("failed to read UE"); \
+    goto error; \
+  } \
+}
+
+#define READ_UE_ALLOWED(nr, val, min, max) { \
+  guint32 tmp; \
+  READ_UE (nr, tmp); \
+  CHECK_ALLOWED (tmp, min, max); \
+  val = tmp; \
+}
+
+#define READ_SE(nr, val) { \
+  if (!nal_reader_get_se (nr, &val)) { \
+    GST_WARNING ("failed to read SE"); \
+    goto error; \
+  } \
+}
+
+#define READ_SE_ALLOWED(nr, val, min, max) { \
+  gint32 tmp; \
+  READ_SE (nr, tmp); \
+  CHECK_ALLOWED (tmp, min, max); \
+  val = tmp; \
+}
+
+/***********  end of nal parser ***************/
+
+/*****  Utils ****/
+#define EXTENDED_SAR 255
+
+static GstH264SPS *
+gst_h264_parser_get_sps (GstH264NalParser * nalparser, guint8 sps_id)
+{
+  GstH264SPS *sps;
+
+  sps = &nalparser->sps[sps_id];
+
+  if (sps->valid)
+    return sps;
+
+  return NULL;
+}
+
+static GstH264PPS *
+gst_h264_parser_get_pps (GstH264NalParser * nalparser, guint8 pps_id)
+{
+  GstH264PPS *pps;
+
+  pps = &nalparser->pps[pps_id];
+
+  if (pps->valid)
+    return pps;
+
+  return NULL;
+}
+
+static inline void
+set_nalu_datas (GstH264NalUnit * nalu)
+{
+  guint8 *data = nalu->data + nalu->offset;
+
+  nalu->type = (data[0] & 0x1f);
+  nalu->ref_idc = (data[0] & 0x60) >> 5;
+  nalu->idr_pic_flag = (nalu->type == 5 ? 1 : 0);
+
+  GST_DEBUG ("Nal type %u, ref_idc %u", nalu->type, nalu->ref_idc);
+}
+
+static inline gint
+scan_for_start_codes (const guint8 * data, guint size)
+{
+  GstByteReader br;
+  gst_byte_reader_init (&br, data, size);
+
+  /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
+  return gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
+      0, size);
+}
+
+static gboolean
+gst_h264_parser_more_data (NalReader * nr)
+{
+  NalReader nr_tmp;
+  guint remaining, nbits;
+  guint8 rbsp_stop_one_bit, zero_bits;
+
+  remaining = nal_reader_get_remaining (nr);
+  if (remaining == 0)
+    return FALSE;
+
+  nr_tmp = *nr;
+  nr = &nr_tmp;
+
+  if (!nal_reader_get_bits_uint8 (nr, &rbsp_stop_one_bit, 1))
+    return FALSE;
+  if (!rbsp_stop_one_bit)
+    return TRUE;
+
+  nbits = --remaining % 8;
+  while (remaining > 0) {
+    if (!nal_reader_get_bits_uint8 (nr, &zero_bits, nbits))
+      return FALSE;
+    if (zero_bits != 0)
+      return TRUE;
+    remaining -= nbits;
+    nbits = 8;
+  }
+  return FALSE;
+}
+
+/****** Parsing functions *****/
+
+static gboolean
+gst_h264_parse_hrd_parameters (GstH264HRDParams * hrd, NalReader * nr)
+{
+  guint sched_sel_idx;
+
+  GST_DEBUG ("parsing \"HRD Parameters\"");
+
+  READ_UE_ALLOWED (nr, hrd->cpb_cnt_minus1, 0, 31);
+  READ_UINT8 (nr, hrd->bit_rate_scale, 4);
+  READ_UINT8 (nr, hrd->cpb_size_scale, 4);
+
+  for (sched_sel_idx = 0; sched_sel_idx <= hrd->cpb_cnt_minus1; sched_sel_idx++) {
+    READ_UE (nr, hrd->bit_rate_value_minus1[sched_sel_idx]);
+    READ_UE (nr, hrd->cpb_size_value_minus1[sched_sel_idx]);
+    READ_UINT8 (nr, hrd->cbr_flag[sched_sel_idx], 1);
+  }
+
+  READ_UINT8 (nr, hrd->initial_cpb_removal_delay_length_minus1, 5);
+  READ_UINT8 (nr, hrd->cpb_removal_delay_length_minus1, 5);
+  READ_UINT8 (nr, hrd->dpb_output_delay_length_minus1, 5);
+  READ_UINT8 (nr, hrd->time_offset_length, 5);
+
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing \"HRD Parameters\"");
+  return FALSE;
+}
+
+static gboolean
+gst_h264_parse_vui_parameters (GstH264SPS * sps, NalReader * nr)
+{
+  GstH264VUIParams *vui = &sps->vui_parameters;
+
+  GST_DEBUG ("parsing \"VUI Parameters\"");
+
+  /* set default values for fields that might not be present in the bitstream
+     and have valid defaults */
+  vui->aspect_ratio_idc = 0;
+  vui->video_format = 5;
+  vui->video_full_range_flag = 0;
+  vui->colour_primaries = 2;
+  vui->transfer_characteristics = 2;
+  vui->matrix_coefficients = 2;
+  vui->chroma_sample_loc_type_top_field = 0;
+  vui->chroma_sample_loc_type_bottom_field = 0;
+  vui->low_delay_hrd_flag = 0;
+  vui->par_n = 0;
+  vui->par_d = 0;
+
+  READ_UINT8 (nr, vui->aspect_ratio_info_present_flag, 1);
+  if (vui->aspect_ratio_info_present_flag) {
+    READ_UINT8 (nr, vui->aspect_ratio_idc, 8);
+    if (vui->aspect_ratio_idc == EXTENDED_SAR) {
+      READ_UINT16 (nr, vui->sar_width, 16);
+      READ_UINT16 (nr, vui->sar_height, 16);
+      vui->par_n = vui->sar_width;
+      vui->par_d = vui->sar_height;
+    } else if (vui->aspect_ratio_idc <= 16) {
+      vui->par_n = aspect_ratios[vui->aspect_ratio_idc].par_n;
+      vui->par_d = aspect_ratios[vui->aspect_ratio_idc].par_d;
+    }
+  }
+
+  READ_UINT8 (nr, vui->overscan_info_present_flag, 1);
+  if (vui->overscan_info_present_flag)
+    READ_UINT8 (nr, vui->overscan_appropriate_flag, 1);
+
+  READ_UINT8 (nr, vui->video_signal_type_present_flag, 1);
+  if (vui->video_signal_type_present_flag) {
+
+    READ_UINT8 (nr, vui->video_format, 3);
+    READ_UINT8 (nr, vui->video_full_range_flag, 1);
+    READ_UINT8 (nr, vui->colour_description_present_flag, 1);
+    if (vui->colour_description_present_flag) {
+      READ_UINT8 (nr, vui->colour_primaries, 8);
+      READ_UINT8 (nr, vui->transfer_characteristics, 8);
+      READ_UINT8 (nr, vui->matrix_coefficients, 8);
+    }
+  }
+
+  READ_UINT8 (nr, vui->chroma_loc_info_present_flag, 1);
+  if (vui->chroma_loc_info_present_flag) {
+    READ_UE_ALLOWED (nr, vui->chroma_sample_loc_type_top_field, 0, 5);
+    READ_UE_ALLOWED (nr, vui->chroma_sample_loc_type_bottom_field, 0, 5);
+  }
+
+  READ_UINT8 (nr, vui->timing_info_present_flag, 1);
+  if (vui->timing_info_present_flag) {
+    READ_UINT32 (nr, vui->num_units_in_tick, 32);
+    if (vui->num_units_in_tick == 0)
+      GST_WARNING ("num_units_in_tick = 0 detected in stream "
+          "(incompliant to H.264 E.2.1).");
+
+    READ_UINT32 (nr, vui->time_scale, 32);
+    if (vui->time_scale == 0)
+      GST_WARNING ("time_scale = 0 detected in stream "
+          "(incompliant to H.264 E.2.1).");
+
+    READ_UINT8 (nr, vui->fixed_frame_rate_flag, 1);
+  }
+
+  READ_UINT8 (nr, vui->nal_hrd_parameters_present_flag, 1);
+  if (vui->nal_hrd_parameters_present_flag) {
+    if (!gst_h264_parse_hrd_parameters (&vui->nal_hrd_parameters, nr))
+      goto error;
+  }
+
+  READ_UINT8 (nr, vui->vcl_hrd_parameters_present_flag, 1);
+  if (vui->vcl_hrd_parameters_present_flag) {
+    if (!gst_h264_parse_hrd_parameters (&vui->vcl_hrd_parameters, nr))
+      goto error;
+  }
+
+  if (vui->nal_hrd_parameters_present_flag ||
+      vui->vcl_hrd_parameters_present_flag)
+    READ_UINT8 (nr, vui->low_delay_hrd_flag, 1);
+
+  READ_UINT8 (nr, vui->pic_struct_present_flag, 1);
+  READ_UINT8 (nr, vui->bitstream_restriction_flag, 1);
+  if (vui->bitstream_restriction_flag) {
+    READ_UINT8 (nr, vui->motion_vectors_over_pic_boundaries_flag, 1);
+    READ_UE (nr, vui->max_bytes_per_pic_denom);
+    READ_UE_ALLOWED (nr, vui->max_bits_per_mb_denom, 0, 16);
+    READ_UE_ALLOWED (nr, vui->log2_max_mv_length_horizontal, 0, 16);
+    READ_UE_ALLOWED (nr, vui->log2_max_mv_length_vertical, 0, 16);
+    READ_UE (nr, vui->num_reorder_frames);
+    READ_UE (nr, vui->max_dec_frame_buffering);
+  }
+
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing \"VUI Parameters\"");
+  return FALSE;
+}
+
+static gboolean
+gst_h264_parser_parse_scaling_list (NalReader * nr,
+    guint8 scaling_lists_4x4[6][16], guint8 scaling_lists_8x8[6][64],
+    const guint8 fallback_4x4_inter[16], const guint8 fallback_4x4_intra[16],
+    const guint8 fallback_8x8_inter[64], const guint8 fallback_8x8_intra[64],
+    guint8 n_lists)
+{
+  guint i;
+
+  GST_DEBUG ("parsing scaling lists");
+
+  for (i = 0; i < 12; i++) {
+    gboolean use_default = FALSE;
+
+    if (i < n_lists) {
+      guint8 scaling_list_present_flag;
+
+      READ_UINT8 (nr, scaling_list_present_flag, 1);
+      if (scaling_list_present_flag) {
+        guint8 *scaling_list;
+        const guint8 *scan;
+        guint size;
+        guint j;
+        guint8 last_scale, next_scale;
+
+        if (i < 6) {
+          scaling_list = scaling_lists_4x4[i];
+          scan = zigzag_4x4;
+          size = 16;
+        } else {
+          scaling_list = scaling_lists_8x8[i - 6];
+          scan = zigzag_8x8;
+          size = 64;
+        }
+
+        last_scale = 8;
+        next_scale = 8;
+        for (j = 0; j < size; j++) {
+          if (next_scale != 0) {
+            gint32 delta_scale;
+
+            READ_SE (nr, delta_scale);
+            next_scale = (last_scale + delta_scale) & 0xff;
+          }
+          if (j == 0 && next_scale == 0) {
+            use_default = TRUE;
+            break;
+          }
+          last_scale = scaling_list[scan[j]] =
+              (next_scale == 0) ? last_scale : next_scale;
+        }
+      } else
+        use_default = TRUE;
+    } else
+      use_default = TRUE;
+
+    if (use_default) {
+      switch (i) {
+        case 0:
+          memcpy (scaling_lists_4x4[0], fallback_4x4_intra, 16);
+          break;
+        case 1:
+          memcpy (scaling_lists_4x4[1], scaling_lists_4x4[0], 16);
+          break;
+        case 2:
+          memcpy (scaling_lists_4x4[2], scaling_lists_4x4[1], 16);
+          break;
+        case 3:
+          memcpy (scaling_lists_4x4[3], fallback_4x4_inter, 16);
+          break;
+        case 4:
+          memcpy (scaling_lists_4x4[4], scaling_lists_4x4[3], 16);
+          break;
+        case 5:
+          memcpy (scaling_lists_4x4[5], scaling_lists_4x4[4], 16);
+          break;
+        case 6:
+          memcpy (scaling_lists_8x8[0], fallback_8x8_intra, 64);
+          break;
+        case 7:
+          memcpy (scaling_lists_8x8[1], fallback_8x8_inter, 64);
+          break;
+        case 8:
+          memcpy (scaling_lists_8x8[2], scaling_lists_8x8[0], 64);
+          break;
+        case 9:
+          memcpy (scaling_lists_8x8[3], scaling_lists_8x8[1], 64);
+          break;
+        case 10:
+          memcpy (scaling_lists_8x8[4], scaling_lists_8x8[2], 64);
+          break;
+        case 11:
+          memcpy (scaling_lists_8x8[5], scaling_lists_8x8[3], 64);
+          break;
+
+        default:
+          break;
+      }
+    }
+  }
+
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing scaling lists");
+  return FALSE;
+}
+
+static gboolean
+slice_parse_ref_pic_list_modification_1 (GstH264SliceHdr * slice,
+    NalReader * nr, guint list)
+{
+  GstH264RefPicListModification *entries;
+  guint8 *ref_pic_list_modification_flag, *n_ref_pic_list_modification;
+  guint32 modification_of_pic_nums_idc;
+  guint i = 0;
+
+  if (list == 0) {
+    entries = slice->ref_pic_list_modification_l0;
+    ref_pic_list_modification_flag = &slice->ref_pic_list_modification_flag_l0;
+    n_ref_pic_list_modification = &slice->n_ref_pic_list_modification_l0;
+  } else {
+    entries = slice->ref_pic_list_modification_l1;
+    ref_pic_list_modification_flag = &slice->ref_pic_list_modification_flag_l1;
+    n_ref_pic_list_modification = &slice->n_ref_pic_list_modification_l1;
+  }
+
+  READ_UINT8 (nr, *ref_pic_list_modification_flag, 1);
+  if (*ref_pic_list_modification_flag) {
+    while (1) {
+      READ_UE (nr, modification_of_pic_nums_idc);
+      if (modification_of_pic_nums_idc == 3)
+        break;
+      if (modification_of_pic_nums_idc == 0 ||
+          modification_of_pic_nums_idc == 1) {
+        READ_UE_ALLOWED (nr, entries[i].value.abs_diff_pic_num_minus1, 0,
+            slice->max_pic_num - 1);
+      } else if (modification_of_pic_nums_idc == 2) {
+        READ_UE (nr, entries[i].value.long_term_pic_num);
+      }
+      entries[i++].modification_of_pic_nums_idc = modification_of_pic_nums_idc;
+    }
+  }
+  *n_ref_pic_list_modification = i;
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing \"Reference picture list %u modification\"",
+      list);
+  return FALSE;
+}
+
+static gboolean
+slice_parse_ref_pic_list_modification (GstH264SliceHdr * slice, NalReader * nr)
+{
+  if (!GST_H264_IS_I_SLICE (slice) && !GST_H264_IS_SI_SLICE (slice)) {
+    if (!slice_parse_ref_pic_list_modification_1 (slice, nr, 0))
+      return FALSE;
+  }
+
+  if (GST_H264_IS_B_SLICE (slice)) {
+    if (!slice_parse_ref_pic_list_modification_1 (slice, nr, 1))
+      return FALSE;
+  }
+  return TRUE;
+}
+
+static gboolean
+gst_h264_slice_parse_dec_ref_pic_marking (GstH264SliceHdr * slice,
+    GstH264NalUnit * nalu, NalReader * nr)
+{
+  GstH264DecRefPicMarking *dec_ref_pic_m;
+
+  GST_DEBUG ("parsing \"Decoded reference picture marking\"");
+
+  dec_ref_pic_m = &slice->dec_ref_pic_marking;
+
+  if (nalu->idr_pic_flag) {
+    READ_UINT8 (nr, dec_ref_pic_m->no_output_of_prior_pics_flag, 1);
+    READ_UINT8 (nr, dec_ref_pic_m->long_term_reference_flag, 1);
+  } else {
+    READ_UINT8 (nr, dec_ref_pic_m->adaptive_ref_pic_marking_mode_flag, 1);
+    if (dec_ref_pic_m->adaptive_ref_pic_marking_mode_flag) {
+      guint32 mem_mgmt_ctrl_op;
+      GstH264RefPicMarking *refpicmarking;
+
+      dec_ref_pic_m->n_ref_pic_marking = 0;
+      while (1) {
+        refpicmarking =
+            &dec_ref_pic_m->ref_pic_marking[dec_ref_pic_m->n_ref_pic_marking];
+
+        READ_UE (nr, mem_mgmt_ctrl_op);
+        if (mem_mgmt_ctrl_op == 0)
+          break;
+
+        refpicmarking->memory_management_control_operation = mem_mgmt_ctrl_op;
+
+        if (mem_mgmt_ctrl_op == 1 || mem_mgmt_ctrl_op == 3)
+          READ_UE (nr, refpicmarking->difference_of_pic_nums_minus1);
+
+        if (mem_mgmt_ctrl_op == 2)
+          READ_UE (nr, refpicmarking->long_term_pic_num);
+
+        if (mem_mgmt_ctrl_op == 3 || mem_mgmt_ctrl_op == 6)
+          READ_UE (nr, refpicmarking->long_term_frame_idx);
+
+        if (mem_mgmt_ctrl_op == 4)
+          READ_UE (nr, refpicmarking->max_long_term_frame_idx_plus1);
+
+        dec_ref_pic_m->n_ref_pic_marking++;
+      }
+    }
+  }
+
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing \"Decoded reference picture marking\"");
+  return FALSE;
+}
+
+static gboolean
+gst_h264_slice_parse_pred_weight_table (GstH264SliceHdr * slice,
+    NalReader * nr, guint8 chroma_array_type)
+{
+  GstH264PredWeightTable *p;
+  gint16 default_luma_weight, default_chroma_weight;
+  gint i;
+
+  GST_DEBUG ("parsing \"Prediction weight table\"");
+
+  p = &slice->pred_weight_table;
+
+  READ_UE_ALLOWED (nr, p->luma_log2_weight_denom, 0, 7);
+  /* set default values */
+  default_luma_weight = 1 << p->luma_log2_weight_denom;
+  for (i = 0; i < G_N_ELEMENTS (p->luma_weight_l0); i++)
+    p->luma_weight_l0[i] = default_luma_weight;
+  memset (p->luma_offset_l0, 0, sizeof (p->luma_offset_l0));
+  if (GST_H264_IS_B_SLICE (slice)) {
+    for (i = 0; i < G_N_ELEMENTS (p->luma_weight_l1); i++)
+      p->luma_weight_l1[i] = default_luma_weight;
+    memset (p->luma_offset_l1, 0, sizeof (p->luma_offset_l1));
+  }
+
+  if (chroma_array_type != 0) {
+    READ_UE_ALLOWED (nr, p->chroma_log2_weight_denom, 0, 7);
+    /* set default values */
+    default_chroma_weight = 1 << p->chroma_log2_weight_denom;
+    for (i = 0; i < G_N_ELEMENTS (p->chroma_weight_l0); i++) {
+      p->chroma_weight_l0[i][0] = default_chroma_weight;
+      p->chroma_weight_l0[i][1] = default_chroma_weight;
+    }
+    memset (p->chroma_offset_l0, 0, sizeof (p->chroma_offset_l0));
+    if (GST_H264_IS_B_SLICE (slice)) {
+      for (i = 0; i < G_N_ELEMENTS (p->chroma_weight_l1); i++) {
+        p->chroma_weight_l1[i][0] = default_chroma_weight;
+        p->chroma_weight_l1[i][1] = default_chroma_weight;
+      }
+      memset (p->chroma_offset_l1, 0, sizeof (p->chroma_offset_l1));
+    }
+  }
+
+  for (i = 0; i <= slice->num_ref_idx_l0_active_minus1; i++) {
+    guint8 luma_weight_l0_flag;
+
+    READ_UINT8 (nr, luma_weight_l0_flag, 1);
+    if (luma_weight_l0_flag) {
+      READ_SE_ALLOWED (nr, p->luma_weight_l0[i], -128, 127);
+      READ_SE_ALLOWED (nr, p->luma_offset_l0[i], -128, 127);
+    }
+    if (chroma_array_type != 0) {
+      guint8 chroma_weight_l0_flag;
+      gint j;
+
+      READ_UINT8 (nr, chroma_weight_l0_flag, 1);
+      if (chroma_weight_l0_flag) {
+        for (j = 0; j < 2; j++) {
+          READ_SE_ALLOWED (nr, p->chroma_weight_l0[i][j], -128, 127);
+          READ_SE_ALLOWED (nr, p->chroma_offset_l0[i][j], -128, 127);
+        }
+      }
+    }
+  }
+
+  if (GST_H264_IS_B_SLICE (slice)) {
+    for (i = 0; i <= slice->num_ref_idx_l1_active_minus1; i++) {
+      guint8 luma_weight_l1_flag;
+
+      READ_UINT8 (nr, luma_weight_l1_flag, 1);
+      if (luma_weight_l1_flag) {
+        READ_SE_ALLOWED (nr, p->luma_weight_l1[i], -128, 127);
+        READ_SE_ALLOWED (nr, p->luma_offset_l1[i], -128, 127);
+      }
+      if (chroma_array_type != 0) {
+        guint8 chroma_weight_l1_flag;
+        gint j;
+
+        READ_UINT8 (nr, chroma_weight_l1_flag, 1);
+        if (chroma_weight_l1_flag) {
+          for (j = 0; j < 2; j++) {
+            READ_SE_ALLOWED (nr, p->chroma_weight_l1[i][j], -128, 127);
+            READ_SE_ALLOWED (nr, p->chroma_offset_l1[i][j], -128, 127);
+          }
+        }
+      }
+    }
+  }
+
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing \"Prediction weight table\"");
+  return FALSE;
+}
+
+static gboolean
+gst_h264_parser_parse_buffering_period (GstH264NalParser * nalparser,
+    GstH264BufferingPeriod * per, NalReader * nr)
+{
+  GstH264SPS *sps;
+  guint8 sps_id;
+
+  GST_DEBUG ("parsing \"Buffering period\"");
+
+  READ_UE_ALLOWED (nr, sps_id, 0, GST_H264_MAX_SPS_COUNT - 1);
+  sps = gst_h264_parser_get_sps (nalparser, sps_id);
+  if (!sps) {
+    GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
+        sps_id);
+    return GST_H264_PARSER_BROKEN_LINK;
+  }
+  per->sps = sps;
+
+  if (sps->vui_parameters_present_flag) {
+    GstH264VUIParams *vui = &sps->vui_parameters;
+
+    if (vui->nal_hrd_parameters_present_flag) {
+      GstH264HRDParams *hrd = &vui->nal_hrd_parameters;
+      guint8 sched_sel_idx;
+
+      for (sched_sel_idx = 0; sched_sel_idx <= hrd->cpb_cnt_minus1;
+          sched_sel_idx++) {
+        READ_UINT8 (nr, per->nal_initial_cpb_removal_delay[sched_sel_idx], 5);
+        READ_UINT8 (nr,
+            per->nal_initial_cpb_removal_delay_offset[sched_sel_idx], 5);
+      }
+    }
+
+    if (vui->vcl_hrd_parameters_present_flag) {
+      GstH264HRDParams *hrd = &vui->vcl_hrd_parameters;
+      guint8 sched_sel_idx;
+
+      for (sched_sel_idx = 0; sched_sel_idx <= hrd->cpb_cnt_minus1;
+          sched_sel_idx++) {
+        READ_UINT8 (nr, per->vcl_initial_cpb_removal_delay[sched_sel_idx], 5);
+        READ_UINT8 (nr,
+            per->vcl_initial_cpb_removal_delay_offset[sched_sel_idx], 5);
+      }
+    }
+  }
+
+  return GST_H264_PARSER_OK;
+
+error:
+  GST_WARNING ("error parsing \"Buffering period\"");
+  return GST_H264_PARSER_ERROR;
+}
+
+static gboolean
+gst_h264_parse_clock_timestamp (GstH264ClockTimestamp * tim,
+    GstH264VUIParams * vui, NalReader * nr)
+{
+  guint8 full_timestamp_flag;
+  guint8 time_offset_length;
+
+  GST_DEBUG ("parsing \"Clock timestamp\"");
+
+  /* defalt values */
+  tim->time_offset = 0;
+
+  READ_UINT8 (nr, tim->ct_type, 2);
+  READ_UINT8 (nr, tim->nuit_field_based_flag, 1);
+  READ_UINT8 (nr, tim->counting_type, 5);
+  READ_UINT8 (nr, full_timestamp_flag, 1);
+  READ_UINT8 (nr, tim->discontinuity_flag, 1);
+  READ_UINT8 (nr, tim->cnt_dropped_flag, 1);
+  READ_UINT8 (nr, tim->n_frames, 8);
+
+  if (full_timestamp_flag) {
+    tim->seconds_flag = TRUE;
+    READ_UINT8 (nr, tim->seconds_value, 6);
+
+    tim->minutes_flag = TRUE;
+    READ_UINT8 (nr, tim->minutes_value, 6);
+
+    tim->hours_flag = TRUE;
+    READ_UINT8 (nr, tim->hours_value, 5);
+  } else {
+    READ_UINT8 (nr, tim->seconds_flag, 1);
+    if (tim->seconds_flag) {
+      READ_UINT8 (nr, tim->seconds_value, 6);
+      READ_UINT8 (nr, tim->minutes_flag, 1);
+      if (tim->minutes_flag) {
+        READ_UINT8 (nr, tim->minutes_value, 6);
+        READ_UINT8 (nr, tim->hours_flag, 1);
+        if (tim->hours_flag)
+          READ_UINT8 (nr, tim->hours_value, 5);
+      }
+    }
+  }
+
+  time_offset_length = 0;
+  if (vui->nal_hrd_parameters_present_flag)
+    time_offset_length = vui->nal_hrd_parameters.time_offset_length;
+  else if (vui->vcl_hrd_parameters_present_flag)
+    time_offset_length = vui->vcl_hrd_parameters.time_offset_length;
+
+  if (time_offset_length > 0)
+    READ_UINT32 (nr, tim->time_offset, time_offset_length);
+
+  return TRUE;
+
+error:
+  GST_WARNING ("error parsing \"Clock timestamp\"");
+  return FALSE;
+}
+
+static gboolean
+gst_h264_parser_parse_pic_timing (GstH264NalParser * nalparser,
+    GstH264PicTiming * tim, NalReader * nr)
+{
+  GST_DEBUG ("parsing \"Picture timing\"");
+  if (!nalparser->last_sps || !nalparser->last_sps->valid) {
+    GST_WARNING ("didn't get the associated sequence paramater set for the "
+        "current access unit");
+    goto error;
+  }
+
+  /* default values */
+  memset (tim->clock_timestamp_flag, 0, 3);
+
+  if (nalparser->last_sps->vui_parameters_present_flag) {
+    GstH264VUIParams *vui = &nalparser->last_sps->vui_parameters;
+
+    if (vui->nal_hrd_parameters_present_flag) {
+      READ_UINT32 (nr, tim->cpb_removal_delay,
+          vui->nal_hrd_parameters.cpb_removal_delay_length_minus1 + 1);
+      READ_UINT32 (nr, tim->dpb_output_delay,
+          vui->nal_hrd_parameters.dpb_output_delay_length_minus1 + 1);
+    } else if (vui->nal_hrd_parameters_present_flag) {
+      READ_UINT32 (nr, tim->cpb_removal_delay,
+          vui->vcl_hrd_parameters.cpb_removal_delay_length_minus1 + 1);
+      READ_UINT32 (nr, tim->dpb_output_delay,
+          vui->vcl_hrd_parameters.dpb_output_delay_length_minus1 + 1);
+    }
+
+    if (vui->pic_struct_present_flag) {
+      const guint8 num_clock_ts_table[9] = {
+        1, 1, 1, 2, 2, 3, 3, 2, 3
+      };
+      guint8 num_clock_num_ts;
+      guint i;
+
+      tim->pic_struct_present_flag = TRUE;
+      READ_UINT8 (nr, tim->pic_struct, 4);
+      CHECK_ALLOWED ((gint8) tim->pic_struct, 0, 8);
+
+      num_clock_num_ts = num_clock_ts_table[tim->pic_struct];
+      for (i = 0; i < num_clock_num_ts; i++) {
+        READ_UINT8 (nr, tim->clock_timestamp_flag[i], 1);
+        if (tim->clock_timestamp_flag[i]) {
+          if (!gst_h264_parse_clock_timestamp (&tim->clock_timestamp[i], vui,
+                  nr))
+            goto error;
+        }
+      }
+    }
+  }
+
+  return GST_H264_PARSER_OK;
+
+error:
+  GST_WARNING ("error parsing \"Picture timing\"");
+  return GST_H264_PARSER_ERROR;
+}
+
+/******** API *************/
+
+/**
+ * gst_h264_nal_parser_new:
+ *
+ * Creates a new #GstH264NalParser. It should be freed with
+ * gst_h264_nal_parser_free after use.
+ *
+ * Returns: a new #GstH264NalParser
+ */
+GstH264NalParser *
+gst_h264_nal_parser_new (void)
+{
+  GstH264NalParser *nalparser;
+
+  nalparser = g_slice_new0 (GstH264NalParser);
+  GST_DEBUG_CATEGORY_INIT (h264_parser_debug, "codecparsers_h264", 0,
+      "h264 parser library");
+
+  return nalparser;
+}
+
+/**
+ * gst_h264_nal_parser_free:
+ * @nalparser: the #GstH264NalParser to free
+ *
+ * Frees @nalparser and sets it to %NULL
+ */
+void
+gst_h264_nal_parser_free (GstH264NalParser * nalparser)
+{
+  g_slice_free (GstH264NalParser, nalparser);
+
+  nalparser = NULL;
+}
+
+/**
+ * gst_h264_parser_identify_nalu_unchecked:
+ * @nalparser: a #GstH264NalParser
+ * @data: The data to parse
+ * @offset: the offset from which to parse @data
+ * @size: the size of @data
+ * @nalu: The #GstH264NalUnit where to store parsed nal headers
+ *
+ * Parses @data and fills @nalu from the next nalu data from @data.
+ *
+ * This differs from @gst_h264_parser_identify_nalu in that it doesn't
+ * check whether the packet is complete or not.
+ *
+ * Note: Only use this function if you already know the provided @data
+ * is a complete NALU, else use @gst_h264_parser_identify_nalu.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_identify_nalu_unchecked (GstH264NalParser * nalparser,
+    const guint8 * data, guint offset, gsize size, GstH264NalUnit * nalu)
+{
+  gint off1;
+
+  if (size < offset + 4) {
+    GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
+        ", offset %u", size, offset);
+    return GST_H264_PARSER_ERROR;
+  }
+
+  off1 = scan_for_start_codes (data + offset, size - offset);
+
+  if (off1 < 0) {
+    GST_DEBUG ("No start code prefix in this buffer");
+    return GST_H264_PARSER_NO_NAL;
+  }
+
+  if (offset + off1 == size - 1) {
+    GST_DEBUG ("Missing data to identify nal unit");
+
+    return GST_H264_PARSER_ERROR;
+  }
+
+  nalu->valid = TRUE;
+  nalu->sc_offset = offset + off1;
+
+  /* sc might have 2 or 3 0-bytes */
+  if (nalu->sc_offset > 0 && data[nalu->sc_offset - 1] == 00)
+    nalu->sc_offset--;
+
+  nalu->offset = offset + off1 + 3;
+  nalu->data = (guint8 *) data;
+
+  set_nalu_datas (nalu);
+
+  if (nalu->type == GST_H264_NAL_SEQ_END ||
+      nalu->type == GST_H264_NAL_STREAM_END) {
+    GST_DEBUG ("end-of-seq or end-of-stream nal found");
+    nalu->size = 0;
+    return GST_H264_PARSER_OK;
+  }
+
+  nalu->size = size - nalu->offset;
+
+  return GST_H264_PARSER_OK;
+}
+
+/**
+ * gst_h264_parser_identify_nalu:
+ * @nalparser: a #GstH264NalParser
+ * @data: The data to parse
+ * @offset: the offset from which to parse @data
+ * @size: the size of @data
+ * @nalu: The #GstH264NalUnit where to store parsed nal headers
+ *
+ * Parses @data and fills @nalu from the next nalu data from @data
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_identify_nalu (GstH264NalParser * nalparser,
+    const guint8 * data, guint offset, gsize size, GstH264NalUnit * nalu)
+{
+  GstH264ParserResult res;
+  gint off2;
+
+  res =
+      gst_h264_parser_identify_nalu_unchecked (nalparser, data, offset, size,
+      nalu);
+
+  if (res != GST_H264_PARSER_OK || nalu->size == 0)
+    goto beach;
+
+  off2 = scan_for_start_codes (data + nalu->offset, size - nalu->offset);
+  if (off2 < 0) {
+    GST_DEBUG ("Nal start %d, No end found", nalu->offset);
+
+    return GST_H264_PARSER_NO_NAL_END;
+  }
+
+  if (off2 > 0 && data[nalu->offset + off2 - 1] == 00)
+    off2--;
+
+  nalu->size = off2;
+  if (nalu->size < 2)
+    return GST_H264_PARSER_BROKEN_DATA;
+
+  GST_DEBUG ("Complete nal found. Off: %d, Size: %d", nalu->offset, nalu->size);
+
+beach:
+  return res;
+}
+
+
+/**
+ * gst_h264_parser_identify_nalu_avc:
+ * @nalparser: a #GstH264NalParser
+ * @data: The data to parse, must be the beging of the Nal unit
+ * @offset: the offset from which to parse @data
+ * @size: the size of @data
+ * @nal_length_size: the size in bytes of the AVC nal length prefix.
+ * @nalu: The #GstH264NalUnit where to store parsed nal headers
+ *
+ * Parses @data and sets @nalu.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_identify_nalu_avc (GstH264NalParser * nalparser,
+    const guint8 * data, guint offset, gsize size, guint8 nal_length_size,
+    GstH264NalUnit * nalu)
+{
+  GstBitReader br;
+
+  if (size < offset + nal_length_size) {
+    GST_DEBUG ("Can't parse, buffer has too small size %" G_GSIZE_FORMAT
+        ", offset %u", size, offset);
+    return GST_H264_PARSER_ERROR;
+  }
+
+  size = size - offset;
+  gst_bit_reader_init (&br, data + offset, size);
+
+  nalu->size = gst_bit_reader_get_bits_uint32_unchecked (&br,
+      nal_length_size * 8);
+  nalu->sc_offset = offset;
+  nalu->offset = offset + nal_length_size;
+
+  if (size < nalu->size + nal_length_size) {
+    nalu->size = 0;
+
+    return GST_H264_PARSER_NO_NAL_END;
+  }
+
+  nalu->data = (guint8 *) data;
+
+  set_nalu_datas (nalu);
+
+  if (nalu->size < 2)
+    return GST_H264_PARSER_BROKEN_DATA;
+
+  nalu->valid = TRUE;
+
+  return GST_H264_PARSER_OK;
+}
+
+/**
+ * gst_h264_parser_parse_nal:
+ * @nalparser: a #GstH264NalParser
+ * @nalu: The #GstH264NalUnit to parse
+ *
+ * This function should be called in the case one doesn't need to
+ * parse a specific structure. It is necessary to do so to make
+ * sure @nalparser is up to date.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_parse_nal (GstH264NalParser * nalparser, GstH264NalUnit * nalu)
+{
+  GstH264SPS sps;
+  GstH264PPS pps;
+
+  switch (nalu->type) {
+    case GST_H264_NAL_SPS:
+      return gst_h264_parser_parse_sps (nalparser, nalu, &sps, FALSE);
+      break;
+    case GST_H264_NAL_PPS:
+      return gst_h264_parser_parse_pps (nalparser, nalu, &pps);
+  }
+
+  return GST_H264_PARSER_OK;
+}
+
+/**
+ * gst_h264_parser_parse_sps:
+ * @nalparser: a #GstH264NalParser
+ * @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
+ * @sps: The #GstH264SPS to fill.
+ * @parse_vui_params: Whether to parse the vui_params or not
+ *
+ * Parses @data, and fills the @sps structure.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_parse_sps (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
+    GstH264SPS * sps, gboolean parse_vui_params)
+{
+  GstH264ParserResult res = gst_h264_parse_sps (nalu, sps, parse_vui_params);
+
+  if (res == GST_H264_PARSER_OK) {
+    GST_DEBUG ("adding sequence parameter set with id: %d to array", sps->id);
+
+    nalparser->sps[sps->id] = *sps;
+    nalparser->last_sps = &nalparser->sps[sps->id];
+  }
+
+
+
+  return res;
+}
+
+/**
+ * gst_h264_parse_sps:
+ * @nalu: The #GST_H264_NAL_SPS #GstH264NalUnit to parse
+ * @sps: The #GstH264SPS to fill.
+ * @parse_vui_params: Whether to parse the vui_params or not
+ *
+ * Parses @data, and fills the @sps structure.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parse_sps (GstH264NalUnit * nalu, GstH264SPS * sps,
+    gboolean parse_vui_params)
+{
+  NalReader nr;
+  gint width, height;
+  guint8 frame_cropping_flag;
+  guint subwc[] = { 1, 2, 2, 1 };
+  guint subhc[] = { 1, 2, 1, 1 };
+  GstH264VUIParams *vui = NULL;
+
+  GST_DEBUG ("parsing SPS");
+  nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
+
+  /* set default values for fields that might not be present in the bitstream
+     and have valid defaults */
+  sps->chroma_format_idc = 1;
+  sps->separate_colour_plane_flag = 0;
+  sps->bit_depth_luma_minus8 = 0;
+  sps->bit_depth_chroma_minus8 = 0;
+  memset (sps->scaling_lists_4x4, 16, 96);
+  memset (sps->scaling_lists_8x8, 16, 384);
+  memset (&sps->vui_parameters, 0, sizeof (sps->vui_parameters));
+  sps->mb_adaptive_frame_field_flag = 0;
+  sps->frame_crop_left_offset = 0;
+  sps->frame_crop_right_offset = 0;
+  sps->frame_crop_top_offset = 0;
+  sps->frame_crop_bottom_offset = 0;
+  sps->delta_pic_order_always_zero_flag = 0;
+
+  READ_UINT8 (&nr, sps->profile_idc, 8);
+  READ_UINT8 (&nr, sps->constraint_set0_flag, 1);
+  READ_UINT8 (&nr, sps->constraint_set1_flag, 1);
+  READ_UINT8 (&nr, sps->constraint_set2_flag, 1);
+  READ_UINT8 (&nr, sps->constraint_set3_flag, 1);
+
+  /* skip reserved_zero_4bits */
+  if (!nal_reader_skip (&nr, 4))
+    goto error;
+
+  READ_UINT8 (&nr, sps->level_idc, 8);
+
+  READ_UE_ALLOWED (&nr, sps->id, 0, GST_H264_MAX_SPS_COUNT - 1);
+
+  if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
+      sps->profile_idc == 122 || sps->profile_idc == 244 ||
+      sps->profile_idc == 44 || sps->profile_idc == 83 ||
+      sps->profile_idc == 86) {
+    READ_UE_ALLOWED (&nr, sps->chroma_format_idc, 0, 3);
+    if (sps->chroma_format_idc == 3)
+      READ_UINT8 (&nr, sps->separate_colour_plane_flag, 1);
+
+    READ_UE_ALLOWED (&nr, sps->bit_depth_luma_minus8, 0, 6);
+    READ_UE_ALLOWED (&nr, sps->bit_depth_chroma_minus8, 0, 6);
+    READ_UINT8 (&nr, sps->qpprime_y_zero_transform_bypass_flag, 1);
+
+    READ_UINT8 (&nr, sps->scaling_matrix_present_flag, 1);
+    if (sps->scaling_matrix_present_flag) {
+      guint8 n_lists;
+
+      n_lists = (sps->chroma_format_idc != 3) ? 8 : 12;
+      if (!gst_h264_parser_parse_scaling_list (&nr,
+              sps->scaling_lists_4x4, sps->scaling_lists_8x8,
+              default_4x4_inter, default_4x4_intra,
+              default_8x8_inter, default_8x8_intra, n_lists))
+        goto error;
+    }
+  }
+
+  READ_UE_ALLOWED (&nr, sps->log2_max_frame_num_minus4, 0, 12);
+
+  sps->max_frame_num = 1 << (sps->log2_max_frame_num_minus4 + 4);
+
+  READ_UE_ALLOWED (&nr, sps->pic_order_cnt_type, 0, 2);
+  if (sps->pic_order_cnt_type == 0) {
+    READ_UE_ALLOWED (&nr, sps->log2_max_pic_order_cnt_lsb_minus4, 0, 12);
+  } else if (sps->pic_order_cnt_type == 1) {
+    guint i;
+
+    READ_UINT8 (&nr, sps->delta_pic_order_always_zero_flag, 1);
+    READ_SE (&nr, sps->offset_for_non_ref_pic);
+    READ_SE (&nr, sps->offset_for_top_to_bottom_field);
+    READ_UE_ALLOWED (&nr, sps->num_ref_frames_in_pic_order_cnt_cycle, 0, 255);
+
+    for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
+      READ_SE (&nr, sps->offset_for_ref_frame[i]);
+  }
+
+  READ_UE (&nr, sps->num_ref_frames);
+  READ_UINT8 (&nr, sps->gaps_in_frame_num_value_allowed_flag, 1);
+  READ_UE (&nr, sps->pic_width_in_mbs_minus1);
+  READ_UE (&nr, sps->pic_height_in_map_units_minus1);
+  READ_UINT8 (&nr, sps->frame_mbs_only_flag, 1);
+
+  if (!sps->frame_mbs_only_flag)
+    READ_UINT8 (&nr, sps->mb_adaptive_frame_field_flag, 1);
+
+  READ_UINT8 (&nr, sps->direct_8x8_inference_flag, 1);
+  READ_UINT8 (&nr, frame_cropping_flag, 1);
+  if (frame_cropping_flag) {
+    READ_UE (&nr, sps->frame_crop_left_offset);
+    READ_UE (&nr, sps->frame_crop_right_offset);
+    READ_UE (&nr, sps->frame_crop_top_offset);
+    READ_UE (&nr, sps->frame_crop_bottom_offset);
+  }
+
+  READ_UINT8 (&nr, sps->vui_parameters_present_flag, 1);
+  if (sps->vui_parameters_present_flag && parse_vui_params) {
+    if (!gst_h264_parse_vui_parameters (sps, &nr))
+      goto error;
+    vui = &sps->vui_parameters;
+  }
+
+  /* calculate ChromaArrayType */
+  if (sps->separate_colour_plane_flag)
+    sps->chroma_array_type = 0;
+  else
+    sps->chroma_array_type = sps->chroma_format_idc;
+
+  /* Calculate  width and height */
+  width = (sps->pic_width_in_mbs_minus1 + 1);
+  width *= 16;
+  height = (sps->pic_height_in_map_units_minus1 + 1);
+  height *= 16 * (2 - sps->frame_mbs_only_flag);
+  GST_LOG ("initial width=%d, height=%d", width, height);
+
+  width -= (sps->frame_crop_left_offset + sps->frame_crop_right_offset)
+      * subwc[sps->chroma_format_idc];
+  height -= (sps->frame_crop_top_offset + sps->frame_crop_bottom_offset
+      * subhc[sps->chroma_format_idc] * (2 - sps->frame_mbs_only_flag));
+  if (width < 0 || height < 0) {
+    GST_WARNING ("invalid width/height in SPS");
+    goto error;
+  }
+  GST_LOG ("final width=%u, height=%u", width, height);
+  sps->width = width;
+  sps->height = height;
+
+  sps->fps_num = 0;
+  sps->fps_den = 1;
+
+  if (vui && vui->timing_info_present_flag) {
+    /* derive framerate */
+    /* FIXME verify / also handle other cases */
+    GST_LOG ("Framerate: %u %u %u %u", parse_vui_params,
+        vui->fixed_frame_rate_flag, sps->frame_mbs_only_flag,
+        vui->pic_struct_present_flag);
+
+    if (parse_vui_params && vui->fixed_frame_rate_flag &&
+        sps->frame_mbs_only_flag && !vui->pic_struct_present_flag) {
+      sps->fps_num = vui->time_scale;
+      sps->fps_den = vui->num_units_in_tick;
+      /* picture is a frame = 2 fields */
+      sps->fps_den *= 2;
+      GST_LOG ("framerate %d/%d", sps->fps_num, sps->fps_den);
+    }
+  } else {
+    GST_LOG ("No VUI, unknown framerate");
+  }
+
+  sps->valid = TRUE;
+
+  return GST_H264_PARSER_OK;
+
+error:
+  GST_WARNING ("error parsing \"Sequence parameter set\"");
+  sps->valid = FALSE;
+  return GST_H264_PARSER_ERROR;
+}
+
+/**
+ * gst_h264_parse_pps:
+ * @nalparser: a #GstH264NalParser
+ * @nalu: The #GST_H264_NAL_PPS #GstH264NalUnit to parse
+ * @pps: The #GstH264PPS to fill.
+ *
+ * Parses @data, and fills the @pps structure.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parse_pps (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
+    GstH264PPS * pps)
+{
+  NalReader nr;
+  GstH264SPS *sps;
+  gint sps_id;
+  guint8 pic_scaling_matrix_present_flag;
+  gint qp_bd_offset;
+
+  GST_DEBUG ("parsing PPS");
+
+  nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
+
+  READ_UE_ALLOWED (&nr, pps->id, 0, GST_H264_MAX_PPS_COUNT - 1);
+  READ_UE_ALLOWED (&nr, sps_id, 0, GST_H264_MAX_SPS_COUNT - 1);
+
+  sps = gst_h264_parser_get_sps (nalparser, sps_id);
+  if (!sps) {
+    GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
+        sps_id);
+    return GST_H264_PARSER_BROKEN_LINK;
+  }
+  pps->sequence = sps;
+  qp_bd_offset = 6 * (sps->bit_depth_luma_minus8 +
+      sps->separate_colour_plane_flag);
+
+  /* set default values for fields that might not be present in the bitstream
+     and have valid defaults */
+  pps->slice_group_id = NULL;
+  pps->transform_8x8_mode_flag = 0;
+  memcpy (&pps->scaling_lists_4x4, &sps->scaling_lists_4x4, 96);
+  memcpy (&pps->scaling_lists_8x8, &sps->scaling_lists_8x8, 384);
+
+  READ_UINT8 (&nr, pps->entropy_coding_mode_flag, 1);
+  READ_UINT8 (&nr, pps->pic_order_present_flag, 1);
+  READ_UE_ALLOWED (&nr, pps->num_slice_groups_minus1, 0, 7);
+  if (pps->num_slice_groups_minus1 > 0) {
+    READ_UE_ALLOWED (&nr, pps->slice_group_map_type, 0, 6);
+
+    if (pps->slice_group_map_type == 0) {
+      gint i;
+
+      for (i = 0; i <= pps->num_slice_groups_minus1; i++)
+        READ_UE (&nr, pps->run_length_minus1[i]);
+    } else if (pps->slice_group_map_type == 2) {
+      gint i;
+
+      for (i = 0; i <= pps->num_slice_groups_minus1; i++) {
+        READ_UE (&nr, pps->top_left[i]);
+        READ_UE (&nr, pps->bottom_right[i]);
+      }
+    } else if (pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
+      READ_UINT8 (&nr, pps->slice_group_change_direction_flag, 1);
+      READ_UE (&nr, pps->slice_group_change_rate_minus1);
+    } else if (pps->slice_group_map_type == 6) {
+      gint bits;
+      gint i;
+
+      READ_UE (&nr, pps->pic_size_in_map_units_minus1);
+      bits = g_bit_storage (pps->num_slice_groups_minus1);
+
+      pps->slice_group_id =
+          g_new (guint8, pps->pic_size_in_map_units_minus1 + 1);
+      for (i = 0; i <= pps->pic_size_in_map_units_minus1; i++)
+        READ_UINT8 (&nr, pps->slice_group_id[i], bits);
+    }
+  }
+
+  READ_UE_ALLOWED (&nr, pps->num_ref_idx_l0_active_minus1, 0, 31);
+  READ_UE_ALLOWED (&nr, pps->num_ref_idx_l1_active_minus1, 0, 31);
+  READ_UINT8 (&nr, pps->weighted_pred_flag, 1);
+  READ_UINT8 (&nr, pps->weighted_bipred_idc, 2);
+  READ_SE_ALLOWED (&nr, pps->pic_init_qp_minus26, -(26 + qp_bd_offset), 25);
+  READ_SE_ALLOWED (&nr, pps->pic_init_qs_minus26, -26, 25);
+  READ_SE_ALLOWED (&nr, pps->chroma_qp_index_offset, -12, 12);
+  pps->second_chroma_qp_index_offset = pps->chroma_qp_index_offset;
+  READ_UINT8 (&nr, pps->deblocking_filter_control_present_flag, 1);
+  READ_UINT8 (&nr, pps->constrained_intra_pred_flag, 1);
+  READ_UINT8 (&nr, pps->redundant_pic_cnt_present_flag, 1);
+
+  if (!gst_h264_parser_more_data (&nr))
+    goto done;
+
+  READ_UINT8 (&nr, pps->transform_8x8_mode_flag, 1);
+
+  READ_UINT8 (&nr, pic_scaling_matrix_present_flag, 1);
+  if (pic_scaling_matrix_present_flag) {
+    guint8 n_lists;
+
+    n_lists = 6 + ((sps->chroma_format_idc != 3) ? 2 : 6) *
+        pps->transform_8x8_mode_flag;
+
+    if (sps->scaling_matrix_present_flag) {
+      if (!gst_h264_parser_parse_scaling_list (&nr,
+              pps->scaling_lists_4x4, pps->scaling_lists_8x8,
+              sps->scaling_lists_4x4[0], sps->scaling_lists_4x4[3],
+              sps->scaling_lists_8x8[0], sps->scaling_lists_8x8[3], n_lists))
+        goto error;
+    } else {
+      if (!gst_h264_parser_parse_scaling_list (&nr,
+              pps->scaling_lists_4x4, pps->scaling_lists_8x8,
+              default_4x4_inter, default_4x4_intra,
+              default_8x8_inter, default_8x8_intra, n_lists))
+        goto error;
+    }
+  }
+
+  READ_SE_ALLOWED (&nr, pps->second_chroma_qp_index_offset, -12, 12);
+
+done:
+  pps->valid = TRUE;
+  return GST_H264_PARSER_OK;
+
+error:
+  GST_WARNING ("error parsing \"Picture parameter set\"");
+  pps->valid = FALSE;
+  return GST_H264_PARSER_ERROR;
+}
+
+/**
+ * gst_h264_parser_parse_pps:
+ * @nalparser: a #GstH264NalParser
+ * @nalu: The #GST_H264_NAL_PPS #GstH264NalUnit to parse
+ * @pps: The #GstH264PPS to fill.
+ *
+ * Parses @data, and fills the @pps structure.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_parse_pps (GstH264NalParser * nalparser,
+    GstH264NalUnit * nalu, GstH264PPS * pps)
+{
+  GstH264ParserResult res = gst_h264_parse_pps (nalparser, nalu, pps);
+
+  if (res == GST_H264_PARSER_OK) {
+    GST_DEBUG ("adding picture parameter set with id: %d to array", pps->id);
+
+    nalparser->pps[pps->id] = *pps;
+    nalparser->last_pps = &nalparser->pps[pps->id];
+  }
+
+  return res;
+}
+
+/**
+ * gst_h264_parser_parse_slice_hdr:
+ * @nalparser: a #GstH264NalParser
+ * @nalu: The #GST_H264_NAL_SLICE #GstH264NalUnit to parse
+ * @slice: The #GstH264SliceHdr to fill.
+ * @parse_pred_weight_table: Whether to parse the pred_weight_table or not
+ * @parse_dec_ref_pic_marking: Whether to parse the dec_ref_pic_marking or not
+ *
+ * Parses @data, and fills the @slice structure.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_parse_slice_hdr (GstH264NalParser * nalparser,
+    GstH264NalUnit * nalu, GstH264SliceHdr * slice,
+    gboolean parse_pred_weight_table, gboolean parse_dec_ref_pic_marking)
+{
+  NalReader nr;
+  gint pps_id;
+  GstH264PPS *pps;
+  GstH264SPS *sps;
+
+  if (!nalu->size) {
+    GST_DEBUG ("Invalid Nal Unit");
+    return GST_H264_PARSER_ERROR;
+  }
+
+
+  nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
+
+  READ_UE (&nr, slice->first_mb_in_slice);
+  READ_UE (&nr, slice->type);
+
+  GST_DEBUG ("parsing \"Slice header\", slice type %u", slice->type);
+
+  READ_UE_ALLOWED (&nr, pps_id, 0, GST_H264_MAX_PPS_COUNT - 1);
+  pps = gst_h264_parser_get_pps (nalparser, pps_id);
+
+  if (!pps) {
+    GST_WARNING ("couldn't find associated picture parameter set with id: %d",
+        pps_id);
+
+    return GST_H264_PARSER_BROKEN_LINK;
+  }
+
+  slice->pps = pps;
+  sps = pps->sequence;
+  if (!sps) {
+    GST_WARNING ("couldn't find associated sequence parameter set with id: %d",
+        pps->id);
+    return GST_H264_PARSER_BROKEN_LINK;
+  }
+
+  /* set default values for fields that might not be present in the bitstream
+     and have valid defaults */
+  slice->field_pic_flag = 0;
+  slice->bottom_field_flag = 0;
+  slice->delta_pic_order_cnt_bottom = 0;
+  slice->delta_pic_order_cnt[0] = 0;
+  slice->delta_pic_order_cnt[1] = 0;
+  slice->redundant_pic_cnt = 0;
+  slice->num_ref_idx_l0_active_minus1 = pps->num_ref_idx_l0_active_minus1;
+  slice->num_ref_idx_l1_active_minus1 = pps->num_ref_idx_l1_active_minus1;
+  slice->disable_deblocking_filter_idc = 0;
+  slice->slice_alpha_c0_offset_div2 = 0;
+  slice->slice_beta_offset_div2 = 0;
+
+  if (sps->separate_colour_plane_flag)
+    READ_UINT8 (&nr, slice->colour_plane_id, 2);
+
+  READ_UINT16 (&nr, slice->frame_num, sps->log2_max_frame_num_minus4 + 4);
+
+  if (!sps->frame_mbs_only_flag) {
+    READ_UINT8 (&nr, slice->field_pic_flag, 1);
+    if (slice->field_pic_flag)
+      READ_UINT8 (&nr, slice->bottom_field_flag, 1);
+  }
+
+  /* calculate MaxPicNum */
+  if (slice->field_pic_flag)
+    slice->max_pic_num = sps->max_frame_num;
+  else
+    slice->max_pic_num = 2 * sps->max_frame_num;
+
+  if (nalu->type == 5)
+    READ_UE_ALLOWED (&nr, slice->idr_pic_id, 0, G_MAXUINT16);
+
+  if (sps->pic_order_cnt_type == 0) {
+    READ_UINT16 (&nr, slice->pic_order_cnt_lsb,
+        sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
+
+    if (pps->pic_order_present_flag && !slice->field_pic_flag)
+      READ_SE (&nr, slice->delta_pic_order_cnt_bottom);
+  }
+
+  if (sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag) {
+    READ_SE (&nr, slice->delta_pic_order_cnt[0]);
+    if (pps->pic_order_present_flag && !slice->field_pic_flag)
+      READ_SE (&nr, slice->delta_pic_order_cnt[1]);
+  }
+
+  if (pps->redundant_pic_cnt_present_flag)
+    READ_UE_ALLOWED (&nr, slice->redundant_pic_cnt, 0, G_MAXINT8);
+
+  if (GST_H264_IS_B_SLICE (slice))
+    READ_UINT8 (&nr, slice->direct_spatial_mv_pred_flag, 1);
+
+  if (GST_H264_IS_P_SLICE (slice) || GST_H264_IS_SP_SLICE (slice) ||
+      GST_H264_IS_B_SLICE (slice)) {
+    guint8 num_ref_idx_active_override_flag;
+
+    READ_UINT8 (&nr, num_ref_idx_active_override_flag, 1);
+    if (num_ref_idx_active_override_flag) {
+      READ_UE_ALLOWED (&nr, slice->num_ref_idx_l0_active_minus1, 0, 31);
+
+      if (GST_H264_IS_B_SLICE (slice))
+        READ_UE_ALLOWED (&nr, slice->num_ref_idx_l1_active_minus1, 0, 31);
+    }
+  }
+
+  if (!slice_parse_ref_pic_list_modification (slice, &nr))
+    goto error;
+
+  if ((pps->weighted_pred_flag && (GST_H264_IS_P_SLICE (slice)
+              || GST_H264_IS_SP_SLICE (slice)))
+      || (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE (slice))) {
+    if (!gst_h264_slice_parse_pred_weight_table (slice, &nr,
+            sps->chroma_array_type))
+      goto error;
+  }
+
+  if (nalu->ref_idc != 0) {
+    if (!gst_h264_slice_parse_dec_ref_pic_marking (slice, nalu, &nr))
+      goto error;
+  }
+
+  if (pps->entropy_coding_mode_flag && !GST_H264_IS_I_SLICE (slice) &&
+      !GST_H264_IS_SI_SLICE (slice))
+    READ_UE_ALLOWED (&nr, slice->cabac_init_idc, 0, 2);
+
+  READ_SE_ALLOWED (&nr, slice->slice_qp_delta, -87, 77);
+
+  if (GST_H264_IS_SP_SLICE (slice) || GST_H264_IS_SI_SLICE (slice)) {
+    guint8 sp_for_switch_flag;
+
+    if (GST_H264_IS_SP_SLICE (slice))
+      READ_UINT8 (&nr, sp_for_switch_flag, 1);
+    READ_SE_ALLOWED (&nr, slice->slice_qs_delta, -51, 51);
+  }
+
+  if (pps->deblocking_filter_control_present_flag) {
+    READ_UE_ALLOWED (&nr, slice->disable_deblocking_filter_idc, 0, 2);
+    if (slice->disable_deblocking_filter_idc != 1) {
+      READ_SE_ALLOWED (&nr, slice->slice_alpha_c0_offset_div2, -6, 6);
+      READ_SE_ALLOWED (&nr, slice->slice_beta_offset_div2, -6, 6);
+    }
+  }
+
+  if (pps->num_slice_groups_minus1 > 0 &&
+      pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5) {
+    /* Ceil(Log2(PicSizeInMapUnits / SliceGroupChangeRate + 1))  [7-33] */
+    guint32 PicWidthInMbs = sps->pic_width_in_mbs_minus1 + 1;
+    guint32 PicHeightInMapUnits = sps->pic_height_in_map_units_minus1 + 1;
+    guint32 PicSizeInMapUnits = PicWidthInMbs * PicHeightInMapUnits;
+    guint32 SliceGroupChangeRate = pps->slice_group_change_rate_minus1 + 1;
+    const guint n = ceil_log2 (PicSizeInMapUnits / SliceGroupChangeRate + 1);
+    READ_UINT16 (&nr, slice->slice_group_change_cycle, n);
+  }
+
+  slice->header_size = nal_reader_get_pos (&nr);
+  slice->n_emulation_prevention_bytes = nal_reader_get_epb_count (&nr);
+
+  return GST_H264_PARSER_OK;
+
+error:
+  GST_WARNING ("error parsing \"Slice header\"");
+  return GST_H264_PARSER_ERROR;
+}
+
+/**
+ * gst_h264_parser_parse_sei:
+ * @nalparser: a #GstH264NalParser
+ * @nalu: The #GST_H264_NAL_SEI #GstH264NalUnit to parse
+ * @sei: The #GstH264SEIMessage to fill.
+ *
+ * Parses @data, and fills the @sei structures.
+ *
+ * Returns: a #GstH264ParserResult
+ */
+GstH264ParserResult
+gst_h264_parser_parse_sei (GstH264NalParser * nalparser, GstH264NalUnit * nalu,
+    GstH264SEIMessage * sei)
+{
+  NalReader nr;
+
+  guint32 payloadSize;
+  guint8 payload_type_byte, payload_size_byte;
+  guint remaining, payload_size;
+  gboolean res;
+
+  GST_DEBUG ("parsing \"Sei message\"");
+
+  nal_reader_init (&nr, nalu->data + nalu->offset + 1, nalu->size - 1);
+
+  /* init */
+  memset (sei, 0, sizeof (*sei));
+
+  sei->payloadType = 0;
+  do {
+    READ_UINT8 (&nr, payload_type_byte, 8);
+    sei->payloadType += payload_type_byte;
+  } while (payload_type_byte == 0xff);
+
+  payloadSize = 0;
+  do {
+    READ_UINT8 (&nr, payload_size_byte, 8);
+    payloadSize += payload_size_byte;
+  }
+  while (payload_size_byte == 0xff);
+
+  remaining = nal_reader_get_remaining (&nr) * 8;
+  payload_size = payloadSize < remaining ? payloadSize : remaining;
+
+  GST_DEBUG ("SEI message received: payloadType  %u, payloadSize = %u bytes",
+      sei->payloadType, payload_size);
+
+  if (sei->payloadType == GST_H264_SEI_BUF_PERIOD) {
+    /* size not set; might depend on emulation_prevention_three_byte */
+    res = gst_h264_parser_parse_buffering_period (nalparser,
+        &sei->payload.buffering_period, &nr);
+  } else if (sei->payloadType == GST_H264_SEI_PIC_TIMING) {
+    /* size not set; might depend on emulation_prevention_three_byte */
+    res = gst_h264_parser_parse_pic_timing (nalparser,
+        &sei->payload.pic_timing, &nr);
+  } else
+    res = GST_H264_PARSER_OK;
+
+  return res;
+
+error:
+  GST_WARNING ("error parsing \"Sei message\"");
+  return GST_H264_PARSER_ERROR;
+}
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gsth264parser.h b/ext/codecparsers/gst-libs/gst/codecparsers/gsth264parser.h
new file mode 100644 (file)
index 0000000..7f8ce83
--- /dev/null
@@ -0,0 +1,723 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * Some bits C-c,C-v'ed and s/4/3 from h264parse and videoparsers/h264parse.c:
+ *    Copyright (C) <2010> Mark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
+ *    Copyright (C) <2010> Collabora Multimedia
+ *    Copyright (C) <2010> Nokia Corporation
+ *
+ *    (C) 2005 Michal Benes <michal.benes@itonis.tv>
+ *    (C) 2008 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_H264_PARSER_H__
+#define __GST_H264_PARSER_H__
+
+#ifndef GST_USE_UNSTABLE_API
+#warning "The H.264 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
+
+#define GST_H264_MAX_SPS_COUNT   32
+#define GST_H264_MAX_PPS_COUNT   256
+
+#define GST_H264_IS_P_SLICE(slice)  (((slice)->type % 5) == GST_H264_P_SLICE)
+#define GST_H264_IS_B_SLICE(slice)  (((slice)->type % 5) == GST_H264_B_SLICE)
+#define GST_H264_IS_I_SLICE(slice)  (((slice)->type % 5) == GST_H264_I_SLICE)
+#define GST_H264_IS_SP_SLICE(slice) (((slice)->type % 5) == GST_H264_SP_SLICE)
+#define GST_H264_IS_SI_SLICE(slice) (((slice)->type % 5) == GST_H264_SI_SLICE)
+
+/**
+ * GstH264NalUnitType:
+ * @GST_H264_NAL_UNKNOWN: Unknown nal type
+ * @GST_H264_NAL_SLICE: Slice nal
+ * @GST_H264_NAL_SLICE_DPA: DPA slice nal
+ * @GST_H264_NAL_SLICE_DPB: DPB slice nal
+ * @GST_H264_NAL_SLICE_DPC: DPC slice nal
+ * @GST_H264_NAL_SLICE_IDR: DPR slice nal
+ * @GST_H264_NAL_SEI: Supplemental enhancement information (SEI) nal unit
+ * @GST_H264_NAL_SPS: Sequence parameter set (SPS) nal unit
+ * @GST_H264_NAL_PPS: Picture parameter set (PPS) nal unit
+ * @GST_H264_NAL_AU_DELIMITER: Access unit (AU) delimiter nal unit
+ * @GST_H264_NAL_SEQ_END: End of sequence nal unit
+ * @GST_H264_NAL_STREAM_END: End of stream nal unit
+ * @GST_H264_NAL_FILLER_DATA: Filler data nal lunit
+ *
+ * Indicates the type of H264 Nal Units
+ */
+typedef enum
+{
+  GST_H264_NAL_UNKNOWN      = 0,
+  GST_H264_NAL_SLICE        = 1,
+  GST_H264_NAL_SLICE_DPA    = 2,
+  GST_H264_NAL_SLICE_DPB    = 3,
+  GST_H264_NAL_SLICE_DPC    = 4,
+  GST_H264_NAL_SLICE_IDR    = 5,
+  GST_H264_NAL_SEI          = 6,
+  GST_H264_NAL_SPS          = 7,
+  GST_H264_NAL_PPS          = 8,
+  GST_H264_NAL_AU_DELIMITER = 9,
+  GST_H264_NAL_SEQ_END      = 10,
+  GST_H264_NAL_STREAM_END   = 11,
+  GST_H264_NAL_FILLER_DATA  = 12
+} GstH264NalUnitType;
+
+/**
+ * GstH264ParserResult:
+ * @GST_H264_PARSER_OK: The parsing succeded
+ * @GST_H264_PARSER_BROKEN_DATA: The data to parse is broken
+ * @GST_H264_PARSER_BROKEN_LINK: The link to structure needed for the parsing couldn't be found
+ * @GST_H264_PARSER_ERROR: An error accured when parsing
+ * @GST_H264_PARSER_NO_NAL: No nal found during the parsing
+ * @GST_H264_PARSER_NO_NAL_END: Start of the nal found, but not the end.
+ *
+ * The result of parsing H264 data.
+ */
+typedef enum
+{
+  GST_H264_PARSER_OK,
+  GST_H264_PARSER_BROKEN_DATA,
+  GST_H264_PARSER_BROKEN_LINK,
+  GST_H264_PARSER_ERROR,
+  GST_H264_PARSER_NO_NAL,
+  GST_H264_PARSER_NO_NAL_END
+} GstH264ParserResult;
+
+/**
+ * GstH264SEIPayloadType:
+ * @GST_H264_SEI_BUF_PERIOD: Buffering Period SEI Message
+ * @GST_H264_SEI_PIC_TIMING: Picture Timing SEI Message
+ * ...
+ *
+ * The type of SEI message.
+ */
+typedef enum
+{
+  GST_H264_SEI_BUF_PERIOD = 0,
+  GST_H264_SEI_PIC_TIMING = 1
+      /* and more...  */
+} GstH264SEIPayloadType;
+
+/**
+ * GstH264SEIPicStructType:
+ * @GST_H264_SEI_PIC_STRUCT_FRAME: Picture is a frame
+ * @GST_H264_SEI_PIC_STRUCT_TOP_FIELD: Top field of frame
+ * @GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD: Botom field of frame
+ * @GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM: Top bottom field of frame
+ * @GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP: bottom top field of frame
+ * @GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP: top bottom top field of frame
+ * @GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: bottom top bottom field of frame
+ * @GST_H264_SEI_PIC_STRUCT_FRAME_DOUBLING: indicates that the frame should
+ *  be displayed two times consecutively
+ * @GST_H264_SEI_PIC_STRUCT_FRAME_TRIPLING: indicates that the frame should be
+ *  displayed three times consecutively
+ *
+ * SEI pic_struct type
+ */
+typedef enum
+{
+  GST_H264_SEI_PIC_STRUCT_FRAME             = 0,
+  GST_H264_SEI_PIC_STRUCT_TOP_FIELD         = 1,
+  GST_H264_SEI_PIC_STRUCT_BOTTOM_FIELD      = 2,
+  GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM        = 3,
+  GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP        = 4,
+  GST_H264_SEI_PIC_STRUCT_TOP_BOTTOM_TOP    = 5,
+  GST_H264_SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM = 6,
+  GST_H264_SEI_PIC_STRUCT_FRAME_DOUBLING    = 7,
+  GST_H264_SEI_PIC_STRUCT_FRAME_TRIPLING    = 8
+} GstH264SEIPicStructType;
+
+/**
+ * GstH264SliceType:
+ *
+ * Type of Picture slice
+ */
+
+typedef enum
+{
+  GST_H264_P_SLICE    = 0,
+  GST_H264_B_SLICE    = 1,
+  GST_H264_I_SLICE    = 2,
+  GST_H264_SP_SLICE   = 3,
+  GST_H264_SI_SLICE   = 4,
+  GST_H264_S_P_SLICE  = 5,
+  GST_H264_S_B_SLICE  = 6,
+  GST_H264_S_I_SLICE  = 7,
+  GST_H264_S_SP_SLICE = 8,
+  GST_H264_S_SI_SLICE = 9
+} GstH264SliceType;
+
+typedef struct _GstH264NalParser              GstH264NalParser;
+
+typedef struct _GstH264NalUnit                GstH264NalUnit;
+
+typedef struct _GstH264SPS                    GstH264SPS;
+typedef struct _GstH264PPS                    GstH264PPS;
+typedef struct _GstH264HRDParams              GstH264HRDParams;
+typedef struct _GstH264VUIParams              GstH264VUIParams;
+
+typedef struct _GstH264RefPicListModification GstH264RefPicListModification;
+typedef struct _GstH264DecRefPicMarking       GstH264DecRefPicMarking;
+typedef struct _GstH264RefPicMarking          GstH264RefPicMarking;
+typedef struct _GstH264PredWeightTable        GstH264PredWeightTable;
+typedef struct _GstH264SliceHdr               GstH264SliceHdr;
+
+typedef struct _GstH264ClockTimestamp         GstH264ClockTimestamp;
+typedef struct _GstH264PicTiming              GstH264PicTiming;
+typedef struct _GstH264BufferingPeriod        GstH264BufferingPeriod;
+typedef struct _GstH264SEIMessage             GstH264SEIMessage;
+
+/**
+ * GstH264NalUnit:
+ * @ref_idc: not equal to 0 specifies that the content of the NAL unit contains a sequence
+ *  parameter set, a sequence * parameter set extension, a subset sequence parameter set, a
+ *  picture parameter set, a slice of a reference picture, a slice data partition of a
+ *  reference picture, or a prefix NAL unit preceding a slice of a reference picture.
+ * @type: A #GstH264NalUnitType
+ * @idr_pic_flag: calculated idr_pic_flag
+ * @size: The size of the nal unit starting from @offset
+ * @offset: The offset of the actual start of the nal unit
+ * @sc_offset:The offset of the start code of the nal unit
+ * @valid: If the nal unit is valid, which mean it has
+ * already been parsed
+ * @data: The data from which the Nalu has been parsed
+ *
+ * Structure defining the Nal unit headers
+ */
+struct _GstH264NalUnit
+{
+  guint16 ref_idc;
+  guint16 type;
+
+  /* calculated values */
+  guint8 idr_pic_flag;
+  guint size;
+  guint offset;
+  guint sc_offset;
+  gboolean valid;
+
+  guint8 *data;
+};
+
+/**
+ * GstH264HRDParams:
+ * @cpb_cnt_minus1: plus 1 specifies the number of alternative
+ *    CPB specifications in the bitstream
+ * @bit_rate_scale: specifies the maximum input bit rate of the
+ * SchedSelIdx-th CPB
+ * @cpb_size_scale: specifies the CPB size of the SchedSelIdx-th CPB
+ * @guint32 bit_rate_value_minus1: specifies the maximum input bit rate for the
+ * SchedSelIdx-th CPB
+ * @cpb_size_value_minus1: is used together with cpb_size_scale to specify the
+ * SchedSelIdx-th CPB size
+ * @cbr_flag: Specifies if running in itermediate bitrate mode or constant
+ * @initial_cpb_removal_delay_length_minus1: specifies the length in bits of
+ * the cpb_removal_delay syntax element
+ * @cpb_removal_delay_length_minus1: specifies the length in bits of the
+ * dpb_output_delay syntax element
+ * @dpb_output_delay_length_minus1: >0 specifies the length in bits of the time_offset syntax element.
+ * =0 specifies that the time_offset syntax element is not present
+ * @time_offset_length: Length of the time offset
+ *
+ * Defines the HRD parameters
+ */
+struct _GstH264HRDParams
+{
+  guint8 cpb_cnt_minus1;
+  guint8 bit_rate_scale;
+  guint8 cpb_size_scale;
+
+  guint32 bit_rate_value_minus1[32];
+  guint32 cpb_size_value_minus1[32];
+  guint8 cbr_flag[32];
+
+  guint8 initial_cpb_removal_delay_length_minus1;
+  guint8 cpb_removal_delay_length_minus1;
+  guint8 dpb_output_delay_length_minus1;
+  guint8 time_offset_length;
+};
+
+/**
+ * GstH264VUIParams:
+ * @aspect_ratio_info_present_flag: %TRUE specifies that aspect_ratio_idc is present.
+ *  %FALSE specifies that aspect_ratio_idc is not present
+ * @aspect_ratio_idc specifies the value of the sample aspect ratio of the luma samples
+ * @sar_width indicates the horizontal size of the sample aspect ratio
+ * @sar_height indicates the vertical size of the sample aspect ratio
+ * @overscan_info_present_flag: %TRUE overscan_appropriate_flag is present %FALSE otherwize
+ * @overscan_appropriate_flag: %TRUE indicates that the cropped decoded pictures
+ *  output are suitable for display using overscan. %FALSE the cropped decoded pictures
+ *  output contain visually important information
+ * @video_signal_type_present_flag: %TRUE specifies that video_format, video_full_range_flag and
+ *  colour_description_present_flag are present.
+ * @video_format: indicates the representation of the picture
+ * @video_full_range_flag: indicates the black level and range of the luma and chroma signals
+ * @colour_description_present_flag: %TRUE specifies that colour_primaries,
+ *  transfer_characteristics and matrix_coefficients are present
+ * @colour_primaries: indicates the chromaticity coordinates of the source primaries
+ * @transfer_characteristics: indicates the opto-electronic transfer characteristic
+ * @matrix_coefficients: describes the matrix coefficients used in deriving luma and chroma signals
+ * @chroma_loc_info_present_flag: %TRUE specifies that chroma_sample_loc_type_top_field and
+ *  chroma_sample_loc_type_bottom_field are present, %FALSE otherwize
+ * @chroma_sample_loc_type_top_field: specify the location of chroma for top field
+ * @chroma_sample_loc_type_bottom_field specify the location of chroma for bottom field
+ * @timing_info_present_flag: %TRUE specifies that num_units_in_tick,
+ *  time_scale and fixed_frame_rate_flag are present in the bitstream
+ * @num_units_in_tick: is the number of time units of a clock operating at the frequency time_scale Hz
+ * time_scale: is the number of time units that pass in one second
+ * @fixed_frame_rate_flag: %TRUE indicates that the temporal distance between the HRD output times
+ *  of any two consecutive pictures in output order is constrained as specified in the spec, %FALSE
+ *  otherwize.
+ * @nal_hrd_parameters_present_flag: %TRUE if nal hrd parameters present in the bitstream
+ * @vcl_hrd_parameters_present_flag: %TRUE if nal vlc hrd parameters present in the bitstream
+ * @low_delay_hrd_flag: specifies the HRD operational mode
+ * @pic_struct_present_flag: %TRUE specifies that picture timing SEI messages are present or not
+ * @bitstream_restriction_flag: %TRUE specifies that the following coded video sequence bitstream restriction
+ * parameters are present
+ * @motion_vectors_over_pic_boundaries_flag: %FALSE indicates that no sample outside the
+ *  picture boundaries and no sample at a fractional sample position, %TRUE indicates that one or more
+ *  samples outside picture boundaries may be used in inter prediction
+ * @max_bytes_per_pic_denom: indicates a number of bytes not exceeded by the sum of the sizes of
+ *  the VCL NAL units associated with any coded picture in the coded video sequence.
+ * @max_bits_per_mb_denom: indicates the maximum number of coded bits of macroblock_layer
+ * @log2_max_mv_length_horizontal: indicate the maximum absolute value of a decoded horizontal
+ * motion vector component
+ * @log2_max_mv_length_vertical: indicate the maximum absolute value of a decoded vertical
+ *  motion vector component
+ * @num_reorder_frames: indicates the maximum number of frames, complementary field pairs,
+ *  or non-paired fields that precede any frame,
+ * @max_dec_frame_buffering: specifies the required size of the HRD decoded picture buffer in
+ *  units of frame buffers.
+ *
+ * The structure representing the VUI parameters.
+ */
+struct _GstH264VUIParams
+{
+  guint8 aspect_ratio_info_present_flag;
+  guint8 aspect_ratio_idc;
+  /* if aspect_ratio_idc == 255 */
+  guint16 sar_width;
+  guint16 sar_height;
+
+  guint8 overscan_info_present_flag;
+  /* if overscan_info_present_flag */
+  guint8 overscan_appropriate_flag;
+
+  guint8 video_signal_type_present_flag;
+  guint8 video_format;
+  guint8 video_full_range_flag;
+  guint8 colour_description_present_flag;
+  guint8 colour_primaries;
+  guint8 transfer_characteristics;
+  guint8 matrix_coefficients;
+
+  guint8 chroma_loc_info_present_flag;
+  guint8 chroma_sample_loc_type_top_field;
+  guint8 chroma_sample_loc_type_bottom_field;
+
+  guint8 timing_info_present_flag;
+  /* if timing_info_present_flag */
+  guint32 num_units_in_tick;
+  guint32 time_scale;
+  guint8 fixed_frame_rate_flag;
+
+  guint8 nal_hrd_parameters_present_flag;
+  /* if nal_hrd_parameters_present_flag */
+  GstH264HRDParams nal_hrd_parameters;
+
+  guint8 vcl_hrd_parameters_present_flag;
+  /* if nal_hrd_parameters_present_flag */
+  GstH264HRDParams vcl_hrd_parameters;
+
+  guint8 low_delay_hrd_flag;
+  guint8 pic_struct_present_flag;
+
+  guint8 bitstream_restriction_flag;
+  /*  if bitstream_restriction_flag */
+  guint8 motion_vectors_over_pic_boundaries_flag;
+  guint32 max_bytes_per_pic_denom;
+  guint32 max_bits_per_mb_denom;
+  guint32 log2_max_mv_length_horizontal;
+  guint32 log2_max_mv_length_vertical;
+  guint32 num_reorder_frames;
+  guint32 max_dec_frame_buffering;
+
+  /* calculated values */
+  guint par_n;
+  guint par_d;
+};
+
+/**
+ * GstH264SPS:
+ * @id: The ID of the sequence parameter set
+ * @profile_idc: indicate the profile to which the coded video sequence conforms
+ *
+ * H264 Sequence Parameter Set (SPS)
+ */
+struct _GstH264SPS
+{
+  gint id;
+
+  guint8 profile_idc;
+  guint8 constraint_set0_flag;
+  guint8 constraint_set1_flag;
+  guint8 constraint_set2_flag;
+  guint8 constraint_set3_flag;
+  guint8 level_idc;
+
+  guint8 chroma_format_idc;
+  guint8 separate_colour_plane_flag;
+  guint8 bit_depth_luma_minus8;
+  guint8 bit_depth_chroma_minus8;
+  guint8 qpprime_y_zero_transform_bypass_flag;
+
+  guint8 scaling_matrix_present_flag;
+  guint8 scaling_lists_4x4[6][16];
+  guint8 scaling_lists_8x8[6][64];
+
+  guint8 log2_max_frame_num_minus4;
+  guint8 pic_order_cnt_type;
+
+  /* if pic_order_cnt_type == 0 */
+  guint8 log2_max_pic_order_cnt_lsb_minus4;
+
+  /* else if pic_order_cnt_type == 1 */
+  guint8 delta_pic_order_always_zero_flag;
+  gint32 offset_for_non_ref_pic;
+  gint32 offset_for_top_to_bottom_field;
+  guint8 num_ref_frames_in_pic_order_cnt_cycle;
+  gint32 offset_for_ref_frame[255];
+
+  guint32 num_ref_frames;
+  guint8 gaps_in_frame_num_value_allowed_flag;
+  guint32 pic_width_in_mbs_minus1;
+  guint32 pic_height_in_map_units_minus1;
+  guint8 frame_mbs_only_flag;
+
+  guint8 mb_adaptive_frame_field_flag;
+
+  guint8 direct_8x8_inference_flag;
+
+  guint8 frame_cropping_flag;
+
+  /* if frame_cropping_flag */
+  guint32 frame_crop_left_offset;
+  guint32 frame_crop_right_offset;
+  guint32 frame_crop_top_offset;
+  guint32 frame_crop_bottom_offset;
+
+  guint8 vui_parameters_present_flag;
+  /* if vui_parameters_present_flag */
+ GstH264VUIParams vui_parameters;
+
+  /* calculated values */
+  guint8 chroma_array_type;
+  guint32 max_frame_num;
+  gint width, height;
+  gint fps_num, fps_den;
+  gboolean valid;
+};
+
+/**
+ * GstH264PPS:
+ *
+ * H264 Picture Parameter Set
+ */
+struct _GstH264PPS
+{
+  gint id;
+
+  GstH264SPS *sequence;
+
+  guint8 entropy_coding_mode_flag;
+  guint8 pic_order_present_flag;
+
+  guint32 num_slice_groups_minus1;
+
+  /* if num_slice_groups_minus1 > 0 */
+  guint8 slice_group_map_type;
+  /* and if slice_group_map_type == 0 */
+  guint32 run_length_minus1[8];
+  /* or if slice_group_map_type == 2 */
+  guint32 top_left[8];
+  guint32 bottom_right[8];
+  /* or if slice_group_map_type == (3, 4, 5) */
+  guint8 slice_group_change_direction_flag;
+  guint32 slice_group_change_rate_minus1;
+  /* or if slice_group_map_type == 6 */
+  guint32 pic_size_in_map_units_minus1;
+  guint8 *slice_group_id;
+
+  guint8 num_ref_idx_l0_active_minus1;
+  guint8 num_ref_idx_l1_active_minus1;
+  guint8 weighted_pred_flag;
+  guint8 weighted_bipred_idc;
+  gint8 pic_init_qp_minus26;
+  gint8 pic_init_qs_minus26;
+  gint8 chroma_qp_index_offset;
+  guint8 deblocking_filter_control_present_flag;
+  guint8 constrained_intra_pred_flag;
+  guint8 redundant_pic_cnt_present_flag;
+
+  guint8 transform_8x8_mode_flag;
+
+  guint8 scaling_lists_4x4[6][16];
+  guint8 scaling_lists_8x8[6][64];
+
+  guint8 second_chroma_qp_index_offset;
+
+  gboolean valid;
+};
+
+struct _GstH264RefPicListModification
+{
+  guint8 modification_of_pic_nums_idc;
+  union
+  {
+    /* if modification_of_pic_nums_idc == 0 || 1 */
+    guint32 abs_diff_pic_num_minus1;
+    /* if modification_of_pic_nums_idc == 2 */
+    guint32 long_term_pic_num;
+  } value;
+};
+
+struct _GstH264PredWeightTable
+{
+  guint8 luma_log2_weight_denom;
+  guint8 chroma_log2_weight_denom;
+
+  gint16 luma_weight_l0[32];
+  gint8 luma_offset_l0[32];
+
+  /* if seq->ChromaArrayType != 0 */
+  gint16 chroma_weight_l0[32][2];
+  gint8 chroma_offset_l0[32][2];
+
+  /* if slice->slice_type % 5 == 1 */
+  gint16 luma_weight_l1[32];
+  gint8 luma_offset_l1[32];
+
+  /* and if seq->ChromaArrayType != 0 */
+  gint16 chroma_weight_l1[32][2];
+  gint8 chroma_offset_l1[32][2];
+};
+
+struct _GstH264RefPicMarking
+{
+  guint8 memory_management_control_operation;
+
+  guint32 difference_of_pic_nums_minus1;
+  guint32 long_term_pic_num;
+  guint32 long_term_frame_idx;
+  guint32 max_long_term_frame_idx_plus1;
+};
+
+struct _GstH264DecRefPicMarking
+{
+  /* if slice->nal_unit.IdrPicFlag */
+  guint8 no_output_of_prior_pics_flag;
+  guint8 long_term_reference_flag;
+
+  guint8 adaptive_ref_pic_marking_mode_flag;
+  GstH264RefPicMarking ref_pic_marking[10];
+  guint8 n_ref_pic_marking;
+};
+
+
+struct _GstH264SliceHdr
+{
+  guint32 first_mb_in_slice;
+  guint32 type;
+  GstH264PPS *pps;
+
+  /* if seq->separate_colour_plane_flag */
+  guint8 colour_plane_id;
+
+  guint16 frame_num;
+
+  guint8 field_pic_flag;
+  guint8 bottom_field_flag;
+
+  /* if nal_unit.type == 5 */
+  guint16 idr_pic_id;
+
+  /* if seq->pic_order_cnt_type == 0 */
+  guint16 pic_order_cnt_lsb;
+  /* if seq->pic_order_present_flag && !field_pic_flag */
+  gint32 delta_pic_order_cnt_bottom;
+
+  gint32 delta_pic_order_cnt[2];
+  guint8 redundant_pic_cnt;
+
+  /* if slice_type == B_SLICE */
+  guint8 direct_spatial_mv_pred_flag;
+
+  guint8 num_ref_idx_l0_active_minus1;
+  guint8 num_ref_idx_l1_active_minus1;
+
+  guint8 ref_pic_list_modification_flag_l0;
+  guint8 n_ref_pic_list_modification_l0;
+  GstH264RefPicListModification ref_pic_list_modification_l0[32];
+  guint8 ref_pic_list_modification_flag_l1;
+  guint8 n_ref_pic_list_modification_l1;
+  GstH264RefPicListModification ref_pic_list_modification_l1[32];
+
+  GstH264PredWeightTable pred_weight_table;
+  /* if nal_unit.ref_idc != 0 */
+  GstH264DecRefPicMarking dec_ref_pic_marking;
+
+  guint8 cabac_init_idc;
+  gint8 slice_qp_delta;
+  gint8 slice_qs_delta;
+
+  guint8 disable_deblocking_filter_idc;
+  gint8 slice_alpha_c0_offset_div2;
+  gint8 slice_beta_offset_div2;
+
+  guint16 slice_group_change_cycle;
+
+  /* calculated values */
+  guint32 max_pic_num;
+  gboolean valid;
+
+  /* Size of the slice_header() in bits */
+  guint header_size;
+
+  /* Number of emulation prevention bytes (EPB) in this slice_header() */
+  guint n_emulation_prevention_bytes;
+};
+
+
+struct _GstH264ClockTimestamp
+{
+  guint8 ct_type;
+  guint8 nuit_field_based_flag;
+  guint8 counting_type;
+  guint8 discontinuity_flag;
+  guint8 cnt_dropped_flag;
+  guint8 n_frames;
+
+  guint8 seconds_flag;
+  guint8 seconds_value;
+
+  guint8 minutes_flag;
+  guint8 minutes_value;
+
+  guint8 hours_flag;
+  guint8 hours_value;
+
+  guint32 time_offset;
+};
+
+struct _GstH264PicTiming
+{
+  guint32 cpb_removal_delay;
+  guint32 dpb_output_delay;
+
+  guint8 pic_struct_present_flag;
+  /* if pic_struct_present_flag */
+  guint8 pic_struct;
+
+  guint8 clock_timestamp_flag[3];
+  GstH264ClockTimestamp clock_timestamp[3];
+};
+
+struct _GstH264BufferingPeriod
+{
+  GstH264SPS *sps;
+
+  /* seq->vui_parameters->nal_hrd_parameters_present_flag */
+  guint8 nal_initial_cpb_removal_delay[32];
+  guint8 nal_initial_cpb_removal_delay_offset[32];
+
+  /* seq->vui_parameters->vcl_hrd_parameters_present_flag */
+  guint8 vcl_initial_cpb_removal_delay[32];
+  guint8 vcl_initial_cpb_removal_delay_offset[32];
+};
+
+struct _GstH264SEIMessage
+{
+  GstH264SEIPayloadType payloadType;
+
+  union {
+    GstH264BufferingPeriod buffering_period;
+    GstH264PicTiming pic_timing;
+    /* ... could implement more */
+  } payload;
+};
+
+/**
+ * GstH264NalParser:
+ *
+ * H264 NAL Parser (opaque structure).
+ */
+struct _GstH264NalParser
+{
+  /*< private >*/
+  GstH264SPS sps[GST_H264_MAX_SPS_COUNT];
+  GstH264PPS pps[GST_H264_MAX_PPS_COUNT];
+  GstH264SPS *last_sps;
+  GstH264PPS *last_pps;
+};
+
+GstH264NalParser *gst_h264_nal_parser_new             (void);
+
+GstH264ParserResult gst_h264_parser_identify_nalu     (GstH264NalParser *nalparser,
+                                                       const guint8 *data, guint offset,
+                                                       gsize size, GstH264NalUnit *nalu);
+
+GstH264ParserResult gst_h264_parser_identify_nalu_unchecked (GstH264NalParser *nalparser,
+                                                       const guint8 *data, guint offset,
+                                                       gsize size, GstH264NalUnit *nalu);
+
+GstH264ParserResult gst_h264_parser_identify_nalu_avc (GstH264NalParser *nalparser, const guint8 *data,
+                                                       guint offset, gsize size, guint8 nal_length_size,
+                                                       GstH264NalUnit *nalu);
+
+GstH264ParserResult gst_h264_parser_parse_nal         (GstH264NalParser *nalparser,
+                                                       GstH264NalUnit *nalu);
+
+GstH264ParserResult gst_h264_parser_parse_slice_hdr   (GstH264NalParser *nalparser, GstH264NalUnit *nalu,
+                                                       GstH264SliceHdr *slice, gboolean parse_pred_weight_table,
+                                                       gboolean parse_dec_ref_pic_marking);
+
+GstH264ParserResult gst_h264_parser_parse_sps         (GstH264NalParser *nalparser, GstH264NalUnit *nalu,
+                                                       GstH264SPS *sps, gboolean parse_vui_params);
+
+GstH264ParserResult gst_h264_parser_parse_pps         (GstH264NalParser *nalparser,
+                                                       GstH264NalUnit *nalu, GstH264PPS *pps);
+
+GstH264ParserResult gst_h264_parser_parse_sei         (GstH264NalParser *nalparser,
+                                                       GstH264NalUnit *nalu, GstH264SEIMessage *sei);
+
+void gst_h264_nal_parser_free                         (GstH264NalParser *nalparser);
+
+GstH264ParserResult gst_h264_parse_sps                (GstH264NalUnit *nalu,
+                                                       GstH264SPS *sps, gboolean parse_vui_params);
+
+GstH264ParserResult gst_h264_parse_pps                (GstH264NalParser *nalparser,
+                                                       GstH264NalUnit *nalu, GstH264PPS *pps);
+
+G_END_DECLS
+#endif
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstjpegparser.c b/ext/codecparsers/gst-libs/gst/codecparsers/gstjpegparser.c
new file mode 100644 (file)
index 0000000..80de3ff
--- /dev/null
@@ -0,0 +1,611 @@
+/*
+ *  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 <stdlib.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;
+}
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstjpegparser.h b/ext/codecparsers/gst-libs/gst/codecparsers/gstjpegparser.h
new file mode 100644 (file)
index 0000000..7237584
--- /dev/null
@@ -0,0 +1,414 @@
+/*
+ *  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 */
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstmpeg4parser.c b/ext/codecparsers/gst-libs/gst/codecparsers/gstmpeg4parser.c
new file mode 100644 (file)
index 0000000..2af6914
--- /dev/null
@@ -0,0 +1,1749 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+/**
+ * SECTION:gstmpeg4parser
+ * @short_description: Convenience library for parsing mpeg4 part 2 video
+ * bitstream.
+ *
+ * For more details about the structures, you can refer to the
+ * specifications: ISO-IEC-14496-2_2004_MPEG4_VISUAL.pdf
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <gst/base/gstbytereader.h>
+
+
+#include "gstmpeg4parser.h"
+#include "parserutils.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_mpeg4", 0,
+        "GstMpeg4 codec parsing library");
+
+    g_once_init_leave (&cat_gonce, cat_done);
+  }
+
+  return (GstDebugCategory *) cat_gonce;
+}
+
+#else
+
+#define ensure_debug_category() /* NOOP */
+
+#endif /* GST_DISABLE_GST_DEBUG */
+
+#define CHECK_MARKER(br) G_STMT_START { \
+  guint8 marker;\
+  if (!gst_bit_reader_get_bits_uint8 (br, &marker, 1)) { \
+    GST_WARNING ("failed to read marker bit"); \
+    goto failed; \
+  } else if (!marker) {\
+    GST_WARNING ("Wrong marker bit"); \
+    goto failed;\
+  }\
+} G_STMT_END
+
+#define MARKER_UNCHECKED(br) G_STMT_START { \
+  if (!gst_bit_reader_get_bits_uint8_unchecked (br, 1)) { \
+    GST_WARNING ("Wrong marker bit"); \
+    goto failed; \
+  } \
+} G_STMT_END
+
+#define CHECK_REMAINING(br, needed) G_STMT_START { \
+  if (gst_bit_reader_get_remaining (br) < needed) \
+    goto failed; \
+} G_STMT_END
+
+static const guint8 default_intra_quant_mat[64] = {
+  8, 17, 18, 19, 21, 23, 25, 27,
+  17, 18, 19, 21, 23, 25, 27, 28,
+  20, 21, 22, 23, 24, 26, 28, 30,
+  21, 22, 23, 24, 26, 28, 30, 32,
+  22, 23, 24, 26, 28, 30, 32, 35,
+  23, 24, 26, 28, 30, 32, 35, 38,
+  25, 26, 28, 30, 32, 35, 38, 41,
+  27, 28, 30, 32, 35, 38, 41, 45
+};
+
+static const guint8 default_non_intra_quant_mat[64] = {
+  16, 17, 18, 19, 20, 21, 22, 23,
+  17, 18, 19, 20, 21, 22, 23, 24,
+  18, 19, 20, 21, 22, 23, 24, 25,
+  19, 20, 21, 22, 23, 24, 26, 27,
+  20, 21, 22, 23, 25, 26, 27, 28,
+  21, 22, 23, 24, 26, 27, 28, 30,
+  22, 23, 24, 26, 27, 28, 30, 31,
+  23, 24, 25, 27, 28, 30, 31, 33,
+};
+
+static const guint8 mpeg4_zigzag_8x8[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
+};
+
+static const VLCTable mpeg4_dmv_size_vlc_table[] = {
+  {0x00, 2, 0},
+  {0x02, 3, 1},
+  {0x03, 3, 2},
+  {0x04, 3, 3},
+  {0x05, 3, 4},
+  {0x06, 3, 5},
+  {0x0e, 4, 6},
+  {0x1e, 5, 7},
+  {0x3e, 6, 8},
+  {0x7e, 7, 9},
+  {0xfe, 8, 10},
+  {0x1fe, 9, 11},
+  {0x3fe, 10, 12},
+  {0x7fe, 11, 13},
+  {0xffe, 12, 14}
+};
+
+static void
+mpeg4_util_par_from_info (guint8 aspect_ratio_info, guint8 * par_width,
+    guint8 * par_height)
+{
+  switch (aspect_ratio_info) {
+    case 0x02:
+      *par_width = 12;
+      *par_height = 11;
+      break;
+    case 0x03:
+      *par_width = 10;
+      *par_height = 11;
+      break;
+    case 0x04:
+      *par_width = 16;
+      *par_height = 11;
+      break;
+    case 0x05:
+      *par_width = 40;
+      *par_height = 33;
+      break;
+
+    case 0x01:
+    default:
+      *par_width = 1;
+      *par_height = 1;
+  }
+}
+
+static gboolean
+parse_quant (GstBitReader * br, guint8 quant_mat[64],
+    const guint8 default_quant_mat[64], guint8 * load_quant_mat)
+{
+  READ_UINT8 (br, *load_quant_mat, 1);
+  if (*load_quant_mat) {
+    guint i;
+    guint8 val;
+
+    val = 1;
+    for (i = 0; i < 64; i++) {
+
+      if (val != 0)
+        READ_UINT8 (br, val, 8);
+
+      if (val == 0) {
+        if (i == 0)
+          goto invalid_quant_mat;
+        quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
+      } else
+        quant_mat[mpeg4_zigzag_8x8[i]] = val;
+    }
+  } else
+    memcpy (quant_mat, default_quant_mat, 64);
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("failed parsing quant matrix");
+  return FALSE;
+
+invalid_quant_mat:
+  GST_WARNING ("the first value should be non zero");
+  goto failed;
+}
+
+static gboolean
+parse_signal_type (GstBitReader * br, GstMpeg4VideoSignalType * signal_type)
+{
+  READ_UINT8 (br, signal_type->type, 1);
+
+  if (signal_type->type) {
+
+    READ_UINT8 (br, signal_type->format, 3);
+    READ_UINT8 (br, signal_type->range, 1);
+    READ_UINT8 (br, signal_type->color_description, 1);
+
+    if (signal_type->color_description) {
+      READ_UINT8 (br, signal_type->color_primaries, 8);
+      READ_UINT8 (br, signal_type->transfer_characteristics, 8);
+      READ_UINT8 (br, signal_type->matrix_coefficients, 8);
+    }
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("failed parsing \"Video Signal Type\"");
+
+  return FALSE;
+}
+
+static gboolean
+parse_sprite_trajectory (GstBitReader * br,
+    GstMpeg4SpriteTrajectory * sprite_traj, guint no_of_sprite_warping_points)
+{
+  guint i, length;
+
+  for (i = 0; i < no_of_sprite_warping_points; i++) {
+
+    if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
+            G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
+      goto failed;
+
+    if (length)
+      READ_UINT16 (br, sprite_traj->vop_ref_points[i], length);
+    CHECK_MARKER (br);
+
+    if (!decode_vlc (br, &length, mpeg4_dmv_size_vlc_table,
+            G_N_ELEMENTS (mpeg4_dmv_size_vlc_table)))
+      goto failed;
+
+    if (length)
+      READ_UINT16 (br, sprite_traj->sprite_ref_points[i], length);
+    CHECK_MARKER (br);
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("Could not parse the sprite trajectory");
+  return FALSE;
+}
+
+static guint
+find_psc (GstByteReader * br)
+{
+  guint psc_pos = -1, psc;
+
+  if (!gst_byte_reader_peek_uint24_be (br, &psc))
+    goto failed;
+
+  /* Scan for the picture start code (22 bits - 0x0020) */
+  while ((gst_byte_reader_get_remaining (br) >= 3)) {
+    if (gst_byte_reader_peek_uint24_be (br, &psc) &&
+        ((psc & 0xfffffc) == 0x000080)) {
+      psc_pos = gst_byte_reader_get_pos (br);
+      break;
+    } else
+      gst_byte_reader_skip_unchecked (br, 1);
+  }
+
+failed:
+
+  return psc_pos;
+}
+
+static inline guint8
+compute_resync_marker_size (const GstMpeg4VideoObjectPlane * vop,
+    guint32 * pattern, guint32 * mask)
+{
+  guint8 off;
+
+  /* FIXME handle the binary only shape case */
+  switch (vop->coding_type) {
+    case (GST_MPEG4_I_VOP):
+      off = 16;
+      break;
+    case (GST_MPEG4_S_VOP):
+    case (GST_MPEG4_P_VOP):
+      off = 15 + vop->fcode_forward;
+
+      break;
+    case (GST_MPEG4_B_VOP):
+      off = MAX (15 + MAX (vop->fcode_forward, vop->fcode_backward), 17);
+
+      break;
+    default:
+      return -1;
+  }
+
+  if (mask && pattern) {
+    switch (off) {
+      case 16:
+        *pattern = 0x00008000;
+        *mask = 0xffff8000;
+        break;
+      case 17:
+        *pattern = 0x00004000;
+        *mask = 0xffffc000;
+        break;
+      case 18:
+        *pattern = 0x00002000;
+        *mask = 0xffffe000;
+        break;
+      case 19:
+        *pattern = 0x00001000;
+        *mask = 0xfffff000;
+        break;
+      case 20:
+        *pattern = 0x00000800;
+        *mask = 0xfffff800;
+        break;
+      case 21:
+        *pattern = 0x00000400;
+        *mask = 0xfffffc00;
+        break;
+      case 22:
+        *pattern = 0x00000200;
+        *mask = 0xfffffe00;
+        break;
+      case 23:
+        *pattern = 0x00000100;
+        *mask = 0xffffff00;
+        break;
+    }
+  }
+
+  return off++;                 /* Take the following 1 into account */
+}
+
+/**
+ * gst_mpeg4_next_resync:
+ * @packet: The #GstMpeg4Packet to fill
+ * @vop: The previously parsed #GstMpeg4VideoObjectPlane
+ * @offset: offset from which to start the parsing
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data and fills @packet with the information of the next resync packet
+ * found.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+static GstMpeg4ParseResult
+gst_mpeg4_next_resync (GstMpeg4Packet * packet,
+    const GstMpeg4VideoObjectPlane * vop, const guint8 * data, gsize size,
+    gboolean first_resync_marker)
+{
+  guint markersize = 0, off1, off2;
+  guint32 mask = 0xff, pattern = 0xff;
+  GstByteReader br;
+
+  gst_byte_reader_init (&br, data, size);
+
+  g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
+  g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
+
+  markersize = compute_resync_marker_size (vop, &pattern, &mask);
+
+  if (first_resync_marker) {
+    off1 = 0;
+  } else {
+    off1 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern, 0, size);
+  }
+
+  if (off1 == -1)
+    return GST_MPEG4_PARSER_NO_PACKET;
+
+  GST_DEBUG ("Resync code found at %i", off1);
+
+  packet->offset = off1;
+  packet->type = GST_MPEG4_RESYNC;
+  packet->marker_size = markersize;
+
+  off2 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern,
+      off1 + 2, size - off1 - 2);
+
+  if (off2 == -1)
+    return GST_MPEG4_PARSER_NO_PACKET_END;
+
+  packet->size = off2 - off1;
+
+  return GST_MPEG4_PARSER_OK;
+}
+
+
+/********** API **********/
+
+/**
+ * gst_mpeg4_parse:
+ * @packet: The #GstMpeg4Packet to fill
+ * @skip_user_data: %TRUE to skip user data packet %FALSE otherwize
+ * @vop: The last parsed #GstMpeg4VideoObjectPlane or %NULL if you do
+ * not need to detect the resync codes.
+ * @offset: offset from which to start the parsing
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data and fills @packet with the information of the next packet
+ * found.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data,
+    GstMpeg4VideoObjectPlane * vop, const guint8 * data, guint offset,
+    gsize size)
+{
+  gint off1, off2;
+  GstByteReader br;
+  GstMpeg4ParseResult resync_res;
+  static guint first_resync_marker = TRUE;
+
+  gst_byte_reader_init (&br, data, size);
+
+  g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
+
+  if (size - offset <= 4) {
+    GST_DEBUG ("Can't parse, buffer is to small size %" G_GSSIZE_FORMAT
+        " at offset %d", size, offset);
+    return GST_MPEG4_PARSER_ERROR;
+  }
+
+  if (vop) {
+    resync_res =
+        gst_mpeg4_next_resync (packet, vop, data + offset, size - offset,
+        first_resync_marker);
+    first_resync_marker = FALSE;
+
+    /*  We found a complet slice */
+    if (resync_res == GST_MPEG4_PARSER_OK)
+      return resync_res;
+    else if (resync_res == GST_MPEG4_PARSER_NO_PACKET_END) {
+      /* It doesn't mean there is no standard packet end, look for it */
+      off1 = packet->offset;
+      goto find_end;
+    } else if (resync_res == GST_MPEG4_PARSER_NO_PACKET)
+      return resync_res;
+  } else {
+    first_resync_marker = TRUE;
+  }
+
+  off1 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
+      offset, size - offset);
+
+  if (off1 == -1) {
+    GST_DEBUG ("No start code prefix in this buffer");
+    return GST_MPEG4_PARSER_NO_PACKET;
+  }
+
+  /* Recursively skip user data if needed */
+  if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA)
+    /* If we are here, we know no resync code has been found the first time, so we
+     * don't look for it this time */
+    return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, size);
+
+  packet->offset = off1 + 3;
+  packet->data = data;
+  packet->type = (GstMpeg4StartCode) (data[off1 + 3]);
+
+find_end:
+  off2 = gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
+      off1 + 4, size - off1 - 4);
+
+  if (off2 == -1) {
+    GST_DEBUG ("Packet start %d, No end found", off1 + 4);
+
+    packet->size = G_MAXUINT;
+    return GST_MPEG4_PARSER_NO_PACKET_END;
+  }
+
+  if (packet->type == GST_MPEG4_RESYNC) {
+    packet->size = (gsize) off2 - off1;
+  } else {
+    packet->size = (gsize) off2 - off1 - 3;
+  }
+
+  GST_DEBUG ("Complete packet of type %x found at: %d, Size: %" G_GSSIZE_FORMAT,
+      packet->type, packet->offset, packet->size);
+  return GST_MPEG4_PARSER_OK;
+
+}
+
+/**
+ * gst_h263_parse:
+ * @packet: The #GstMpeg4Packet to fill
+ * @offset: offset from which to start the parsing
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data and fills @packet with the information of the next packet
+ * found.
+ *
+ * Note that the type of the packet is meaningless in this case.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_h263_parse (GstMpeg4Packet * packet,
+    const guint8 * data, guint offset, gsize size)
+{
+  gint off1, off2;
+  GstByteReader br;
+
+  gst_byte_reader_init (&br, data + offset, size - offset);
+
+  g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
+
+  if (size - offset < 3) {
+    GST_DEBUG ("Can't parse, buffer is to small size %" G_GSSIZE_FORMAT
+        " at offset %d", size, offset);
+    return GST_MPEG4_PARSER_ERROR;
+  }
+
+  off1 = find_psc (&br);
+
+  if (off1 == -1) {
+    GST_DEBUG ("No start code prefix in this buffer");
+    return GST_MPEG4_PARSER_NO_PACKET;
+  }
+
+  packet->offset = off1 + offset;
+  packet->data = data;
+
+  gst_byte_reader_skip_unchecked (&br, 3);
+  off2 = find_psc (&br);
+
+  if (off2 == -1) {
+    GST_DEBUG ("Packet start %d, No end found", off1);
+
+    packet->size = G_MAXUINT;
+    return GST_MPEG4_PARSER_NO_PACKET_END;
+  }
+
+  packet->size = (gsize) off2 - off1;
+
+  GST_DEBUG ("Complete packet found at: %d, Size: %" G_GSSIZE_FORMAT,
+      packet->offset, packet->size);
+
+  return GST_MPEG4_PARSER_OK;
+}
+
+/**
+ * gst_mpeg4_parse_visual_object_sequence:
+ * @vos: The #GstMpeg4VisualObjectSequence structure to fill
+ * @data: The data to parse, should contain the visual_object_sequence_start_code
+ * but not the start code prefix
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the visual object sequence packet, and fills
+ * the @vos structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence * vos,
+    const guint8 * data, gsize size)
+{
+  guint8 vos_start_code;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (vos != NULL, GST_MPEG4_PARSER_ERROR);
+
+  READ_UINT8 (&br, vos_start_code, 8);
+  if (vos_start_code != GST_MPEG4_VISUAL_OBJ_SEQ_START)
+    goto wrong_start_code;
+
+  READ_UINT8 (&br, vos->profile_and_level_indication, 8);
+
+  switch (vos->profile_and_level_indication) {
+    case 0x01:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x02:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x03:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0x08:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL0;
+      break;
+    case 0x10:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL0;
+      break;
+    case 0x11:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x12:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x21:
+      vos->profile = GST_MPEG4_PROFILE_CORE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x22:
+      vos->profile = GST_MPEG4_PROFILE_CORE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x32:
+      vos->profile = GST_MPEG4_PROFILE_MAIN;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x33:
+      vos->profile = GST_MPEG4_PROFILE_MAIN;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0x34:
+      vos->profile = GST_MPEG4_PROFILE_MAIN;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0x42:
+      vos->profile = GST_MPEG4_PROFILE_N_BIT;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x51:
+      vos->profile = GST_MPEG4_PROFILE_SCALABLE_TEXTURE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x61:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x62:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x63:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x64:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x71:
+      vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x72:
+      vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x81:
+      vos->profile = GST_MPEG4_PROFILE_HYBRID;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x82:
+      vos->profile = GST_MPEG4_PROFILE_HYBRID;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x91:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0x92:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0x93:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0x94:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0xa1:
+      vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xa2:
+      vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xa3:
+      vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xb1:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xb2:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xb3:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xb4:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0xc1:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xc2:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xc3:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xd1:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xd2:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xd3:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xe1:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xe2:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xe3:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xe4:
+      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0xe5:
+      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xe6:
+      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xe7:
+      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xe8:
+      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0xf0:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL0;
+      break;
+    case 0xf1:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xf2:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xf3:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xf4:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0xf5:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL5;
+      break;
+    case 0xf7:
+      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
+      vos->level = GST_MPEG4_LEVEL3b;
+      break;
+    case 0xf8:
+      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL0;
+      break;
+    case 0xf9:
+      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL1;
+      break;
+    case 0xfa:
+      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL2;
+      break;
+    case 0xfb:
+      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL3;
+      break;
+    case 0xfc:
+      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL4;
+      break;
+    case 0xfd:
+      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
+      vos->level = GST_MPEG4_LEVEL5;
+      break;
+    default:
+      vos->profile = GST_MPEG4_PROFILE_RESERVED;
+      vos->level = GST_MPEG4_LEVEL_RESERVED;
+      break;
+  }
+
+  return GST_MPEG4_PARSER_OK;
+
+wrong_start_code:
+  GST_WARNING ("got buffer with wrong start code");
+  return GST_MPEG4_PARSER_ERROR;
+
+failed:
+  GST_WARNING ("failed parsing \"Visual Object\"");
+  return GST_MPEG4_PARSER_ERROR;
+}
+
+/**
+ * gst_mpeg4_parse_visual_object:
+ * @vo: The #GstMpeg4VisualObject structure to fill
+ * @signal_type: The #GstMpeg4VideoSignalType to fill or %NULL
+ * @data: The data to parse, should contain the vo_start_code
+ * but not the start code prefix
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the visual object packet, and fills
+ * the @vo structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object (GstMpeg4VisualObject * vo,
+    GstMpeg4VideoSignalType * signal_type, const guint8 * data, gsize size)
+{
+  guint8 vo_start_code, type;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (vo != NULL, GST_MPEG4_PARSER_ERROR);
+
+  GST_DEBUG ("Parsing visual object");
+
+  READ_UINT8 (&br, vo_start_code, 8);
+  if (vo_start_code != GST_MPEG4_VISUAL_OBJ)
+    goto wrong_start_code;
+
+  /* set default values */
+  vo->verid = 0x1;
+  vo->priority = 1;
+
+  READ_UINT8 (&br, vo->is_identifier, 1);
+  if (vo->is_identifier) {
+    READ_UINT8 (&br, vo->verid, 4);
+    READ_UINT8 (&br, vo->priority, 3);
+  }
+
+  READ_UINT8 (&br, type, 4);
+  vo->type = type;
+
+  if ((type == GST_MPEG4_VIDEO_ID ||
+          type == GST_MPEG4_STILL_TEXTURE_ID) && signal_type) {
+
+    if (!parse_signal_type (&br, signal_type))
+      goto failed;
+
+  } else if (signal_type) {
+    signal_type->type = 0;
+  }
+
+  return GST_MPEG4_PARSER_OK;
+
+wrong_start_code:
+  GST_WARNING ("got buffer with wrong start code");
+  return GST_MPEG4_PARSER_ERROR;
+
+failed:
+  GST_WARNING ("failed parsing \"Visual Object\"");
+  return GST_MPEG4_PARSER_ERROR;
+}
+
+/**
+ * gst_mpeg4_parse_video_object_layer:
+ * @vol: The #GstMpeg4VideoObjectLayer structure to fill
+ * @vo: The #GstMpeg4VisualObject currently being parsed or %NULL
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the video object layer packet, and fills
+ * the @vol structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
+    GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
+{
+  guint8 video_object_layer_start_code;
+
+  /* Used for enums types */
+  guint8 tmp;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
+
+  GST_DEBUG ("Parsing video object layer");
+
+  READ_UINT8 (&br, video_object_layer_start_code, 8);
+  if (!(video_object_layer_start_code >= GST_MPEG4_VIDEO_LAYER_FIRST &&
+          video_object_layer_start_code <= GST_MPEG4_VIDEO_LAYER_LAST))
+    goto wrong_start_code;
+
+  /* set default values */
+  if (vo) {
+    vol->verid = vo->verid;
+    vol->priority = vo->priority;
+  } else {
+    vol->verid = 1;
+    vol->priority = 0;
+  }
+
+  vol->low_delay = FALSE;
+  vol->chroma_format = 1;
+  vol->vbv_parameters = FALSE;
+  vol->quant_precision = 5;
+  vol->bits_per_pixel = 8;
+  vol->quarter_sample = FALSE;
+  vol->newpred_enable = FALSE;
+  vol->interlaced = 0;
+  vol->width = 0;
+  vol->height = 0;
+
+  READ_UINT8 (&br, vol->random_accessible_vol, 1);
+  READ_UINT8 (&br, vol->video_object_type_indication, 8);
+
+  READ_UINT8 (&br, vol->is_object_layer_identifier, 1);
+  if (vol->is_object_layer_identifier) {
+    READ_UINT8 (&br, vol->verid, 4);
+    READ_UINT8 (&br, vol->priority, 3);
+  }
+
+  READ_UINT8 (&br, tmp, 4);
+  vol->aspect_ratio_info = tmp;
+  if (vol->aspect_ratio_info != GST_MPEG4_EXTENDED_PAR) {
+    mpeg4_util_par_from_info (vol->aspect_ratio_info, &vol->par_width,
+        &vol->par_height);
+
+  } else {
+    gint v;
+
+    READ_UINT8 (&br, vol->par_width, 8);
+    v = vol->par_width;
+    CHECK_ALLOWED (v, 1, 255);
+
+    READ_UINT8 (&br, vol->par_height, 8);
+    v = vol->par_height;
+    CHECK_ALLOWED (v, 1, 255);
+  }
+  GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);
+
+  READ_UINT8 (&br, vol->control_parameters, 1);
+  if (vol->control_parameters) {
+    guint8 chroma_format;
+
+    READ_UINT8 (&br, chroma_format, 2);
+    vol->chroma_format = chroma_format;
+    READ_UINT8 (&br, vol->low_delay, 1);
+
+    READ_UINT8 (&br, vol->vbv_parameters, 1);
+    if (vol->vbv_parameters) {
+      CHECK_REMAINING (&br, 79);
+
+      vol->first_half_bitrate =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+      MARKER_UNCHECKED (&br);
+
+      vol->latter_half_bitrate =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+      MARKER_UNCHECKED (&br);
+
+      vol->bit_rate =
+          (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;
+
+      vol->first_half_vbv_buffer_size =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+      MARKER_UNCHECKED (&br);
+
+      vol->latter_half_vbv_buffer_size =
+          gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
+
+      vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
+          vol->latter_half_vbv_buffer_size;
+
+      vol->first_half_vbv_occupancy =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
+      MARKER_UNCHECKED (&br);
+
+      vol->latter_half_vbv_occupancy =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
+      MARKER_UNCHECKED (&br);
+    }
+  }
+
+  READ_UINT8 (&br, tmp, 2);
+  vol->shape = tmp;
+
+  if (vol->shape == GST_MPEG4_GRAYSCALE) {
+    /* TODO support grayscale shapes, for now we just pass */
+
+    /* Something the standard starts to define... */
+    GST_WARNING ("Grayscale shaped not supported");
+    goto failed;
+  }
+
+  if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
+    READ_UINT8 (&br, vol->shape_extension, 4);
+
+  CHECK_REMAINING (&br, 19);
+
+  MARKER_UNCHECKED (&br);
+  vol->vop_time_increment_resolution =
+      gst_bit_reader_get_bits_uint16_unchecked (&br, 16);
+  if (vol->vop_time_increment_resolution < 1) {
+    GST_WARNING ("value not in allowed range. value: %d, range %d-%d",
+        vol->vop_time_increment_resolution, 1, G_MAXUINT16);
+    goto failed;
+  }
+  vol->vop_time_increment_bits =
+      g_bit_storage (vol->vop_time_increment_resolution);
+
+  MARKER_UNCHECKED (&br);
+  vol->fixed_vop_rate = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  if (vol->fixed_vop_rate)
+    READ_UINT16 (&br, vol->fixed_vop_time_increment,
+        vol->vop_time_increment_bits);
+
+  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+    if (vol->shape == GST_MPEG4_RECTANGULAR) {
+      CHECK_REMAINING (&br, 29);
+
+      MARKER_UNCHECKED (&br);
+      vol->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+      MARKER_UNCHECKED (&br);
+      vol->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+      MARKER_UNCHECKED (&br);
+    }
+
+    READ_UINT8 (&br, vol->interlaced, 1);
+    READ_UINT8 (&br, vol->obmc_disable, 1);
+
+    if (vol->verid == 0x1)
+      READ_UINT8 (&br, tmp, 1);
+    else
+      READ_UINT8 (&br, tmp, 2);
+    vol->sprite_enable = tmp;
+
+    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
+        vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {
+
+      if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
+        CHECK_REMAINING (&br, 9);
+      else {
+        CHECK_REMAINING (&br, 65);
+
+        vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+        MARKER_UNCHECKED (&br);
+
+        vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+        MARKER_UNCHECKED (&br);
+
+        vol->sprite_left_coordinate =
+            gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+        MARKER_UNCHECKED (&br);
+
+        vol->sprite_top_coordinate =
+            gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+        MARKER_UNCHECKED (&br);
+      }
+      vol->no_of_sprite_warping_points =
+          gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
+      vol->sprite_warping_accuracy =
+          gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+      vol->sprite_brightness_change =
+          gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+      if (vol->sprite_enable != GST_MPEG4_SPRITE_GMG)
+        vol->low_latency_sprite_enable =
+            gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+    }
+
+    if (vol->verid != 0x1 && vol->shape != GST_MPEG4_RECTANGULAR)
+      READ_UINT8 (&br, vol->sadct_disable, 1);
+
+    READ_UINT8 (&br, vol->not_8_bit, 1);
+    if (vol->not_8_bit) {
+      READ_UINT8 (&br, vol->quant_precision, 4);
+      CHECK_ALLOWED (vol->quant_precision, 3, 9);
+
+      READ_UINT8 (&br, vol->bits_per_pixel, 4);
+      CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
+    }
+
+    if (vol->shape == GST_MPEG4_GRAYSCALE) {
+      /* We don't actually support it */
+      READ_UINT8 (&br, vol->no_gray_quant_update, 1);
+      READ_UINT8 (&br, vol->composition_method, 1);
+      READ_UINT8 (&br, vol->linear_composition, 1);
+    }
+
+    READ_UINT8 (&br, vol->quant_type, 1);
+    if (vol->quant_type) {
+      if (!parse_quant (&br, vol->intra_quant_mat, default_intra_quant_mat,
+              &vol->load_intra_quant_mat))
+        goto failed;
+
+      if (!parse_quant (&br, vol->non_intra_quant_mat,
+              default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
+        goto failed;
+
+      if (vol->shape == GST_MPEG4_GRAYSCALE) {
+        /* Something the standard starts to define... */
+        GST_WARNING ("Grayscale shaped not supported");
+        goto failed;
+      }
+
+    } else {
+      memset (&vol->intra_quant_mat, 0, 64);
+      memset (&vol->non_intra_quant_mat, 0, 64);
+    }
+
+    if (vol->verid != 0x1)
+      READ_UINT8 (&br, vol->quarter_sample, 1);
+
+    READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
+    if (!vol->complexity_estimation_disable) {
+      guint8 estimation_method;
+      guint8 estimation_disable;
+
+      /* skip unneeded properties */
+      READ_UINT8 (&br, estimation_method, 2);
+      if (estimation_method < 2) {
+        READ_UINT8 (&br, estimation_disable, 1);
+        if (!estimation_disable)
+          SKIP (&br, 6);
+        READ_UINT8 (&br, estimation_disable, 1);
+        if (!estimation_disable)
+          SKIP (&br, 4);
+        CHECK_MARKER (&br);
+        READ_UINT8 (&br, estimation_disable, 1);
+        if (!estimation_disable)
+          SKIP (&br, 4);
+        READ_UINT8 (&br, estimation_disable, 1);
+        if (!estimation_disable)
+          SKIP (&br, 6);
+        CHECK_MARKER (&br);
+
+        if (estimation_method == 1) {
+          READ_UINT8 (&br, estimation_disable, 1);
+          if (!estimation_disable)
+            SKIP (&br, 2);
+        }
+      }
+    }
+
+    READ_UINT8 (&br, vol->resync_marker_disable, 1);
+    READ_UINT8 (&br, vol->data_partitioned, 1);
+
+    if (vol->data_partitioned)
+      READ_UINT8 (&br, vol->reversible_vlc, 1);
+
+    if (vol->verid != 0x01) {
+      READ_UINT8 (&br, vol->newpred_enable, 1);
+      if (vol->newpred_enable)
+        /* requested_upstream_message_type and newpred_segment_type */
+        SKIP (&br, 3);
+
+      READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
+    }
+
+    READ_UINT8 (&br, vol->scalability, 1);
+    if (vol->scalability) {
+      SKIP (&br, 26);           /* Few not needed props */
+      READ_UINT8 (&br, vol->enhancement_type, 1);
+    }
+
+    /* More unused infos */
+  } else if (vol->verid != 0x01) {
+    GST_WARNING ("Binary only shapes not fully supported");
+    goto failed;
+  }
+  /* ... */
+
+  return GST_MPEG4_PARSER_OK;
+
+failed:
+  GST_WARNING ("failed parsing \"Video Object Layer\"");
+  return GST_MPEG4_PARSER_ERROR;
+
+wrong_start_code:
+  GST_WARNING ("got buffer with wrong start code");
+  goto failed;
+}
+
+/**
+ * gst_mpeg4_parse_group_of_vop:
+ * @gov: The #GstMpeg4GroupOfVOP structure to fill
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the group of video object plane packet, and fills
+ * the @gov structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
+    gov, const guint8 * data, gsize size)
+{
+  guint8 gov_start_code;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);
+
+  READ_UINT8 (&br, gov_start_code, 8);
+  if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
+    goto wrong_start_code;
+
+  CHECK_REMAINING (&br, 65);
+
+  gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
+  gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
+  /* marker bit */
+  MARKER_UNCHECKED (&br);
+  gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
+
+  gov->closed = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  gov->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+  return GST_MPEG4_PARSER_OK;
+
+failed:
+  GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
+  return GST_MPEG4_PARSER_ERROR;
+
+wrong_start_code:
+  GST_WARNING ("got buffer with wrong start code");
+  goto failed;
+}
+
+/**
+ * gst_mpeg4_parse_video_object_plane:
+ * @vop: The #GstMpeg4VideoObjectPlane currently being parsed
+ * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
+ * @vol: The #GstMpeg4VideoObjectLayer structure to fill
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ *
+ * Parses @data containing the video object plane packet, and fills the @vol
+ * structure.
+ *
+ * Returns: a #GstMpeg4ParseResult
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
+    GstMpeg4SpriteTrajectory * sprite_trajectory,
+    GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
+{
+  guint8 vop_start_code, coding_type, modulo_time_base;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);
+
+  if (vol->shape == GST_MPEG4_BINARY_ONLY) {
+    /* TODO: implement binary only shapes */
+    GST_WARNING ("Binary only shapes not supported");
+    goto failed;
+  }
+
+  READ_UINT8 (&br, vop_start_code, 8);
+  if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
+    goto wrong_start_code;
+
+
+  /* set default values */
+  vop->modulo_time_base = 0;
+  vop->rounding_type = 0;
+  vop->top_field_first = 1;
+  vop->alternate_vertical_scan_flag = 0;
+  vop->fcode_forward = 1;
+  vop->fcode_backward = 1;
+
+  /*  Compute macroblock informations */
+  if (vol->interlaced)
+    vop->mb_height = (2 * (vol->height + 31) / 32);
+  else
+    vop->mb_height = (vol->height + 15) / 16;
+
+  vop->mb_width = (vol->width + 15) / 16;
+  vop->mb_num = vop->mb_height * vop->mb_width;
+
+  READ_UINT8 (&br, coding_type, 2);
+  vop->coding_type = coding_type;
+
+  READ_UINT8 (&br, modulo_time_base, 1);
+  while (modulo_time_base) {
+    vop->modulo_time_base++;
+
+    READ_UINT8 (&br, modulo_time_base, 1);
+  }
+
+  CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);
+
+  MARKER_UNCHECKED (&br);
+  vop->time_increment =
+      gst_bit_reader_get_bits_uint16_unchecked (&br,
+      vol->vop_time_increment_bits);
+  MARKER_UNCHECKED (&br);
+
+  vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  if (!vop->coded)
+    return GST_MPEG4_PARSER_OK;
+
+  if (vol->newpred_enable) {
+    guint16 nbbits =
+        vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;
+
+    READ_UINT16 (&br, vop->id, nbbits);
+    READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
+    if (vop->id_for_prediction_indication) {
+      /* Would be nice if the standard actually told us... */
+      READ_UINT16 (&br, vop->id, nbbits);
+      CHECK_MARKER (&br);
+    }
+  }
+
+  if (vol->shape != GST_MPEG4_BINARY_ONLY &&
+      (vop->coding_type == GST_MPEG4_P_VOP ||
+          (vop->coding_type == GST_MPEG4_S_VOP &&
+              vol->sprite_enable == GST_MPEG4_SPRITE_GMG)))
+    READ_UINT8 (&br, vop->rounding_type, 1);
+
+  if ((vol->reduced_resolution_vop_enable) &&
+      (vol->shape == GST_MPEG4_RECTANGULAR ||
+          (vop->coding_type = GST_MPEG4_P_VOP ||
+              vop->coding_type == GST_MPEG4_I_VOP)))
+    READ_UINT8 (&br, vop->reduced_resolution, 1);
+
+  if (vol->shape != GST_MPEG4_RECTANGULAR) {
+    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
+        vop->coding_type == GST_MPEG4_I_VOP) {
+      CHECK_REMAINING (&br, 55);
+
+      vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+      MARKER_UNCHECKED (&br);
+
+      vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+      MARKER_UNCHECKED (&br);
+
+      vop->horizontal_mc_spatial_ref =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+      MARKER_UNCHECKED (&br);
+
+      vop->vertical_mc_spatial_ref =
+          gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
+      MARKER_UNCHECKED (&br);
+
+      /* Recompute the Macroblock informations
+       * accordingly to the new values */
+      if (vol->interlaced)
+        vop->mb_height = (2 * (vol->height + 31) / 32);
+      else
+        vop->mb_height = (vol->height + 15) / 16;
+
+      vop->mb_width = (vol->width + 15) / 16;
+      vop->mb_num = vop->mb_height * vop->mb_width;
+    }
+
+    if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
+        vol->scalability && vol->enhancement_type)
+      READ_UINT8 (&br, vop->background_composition, 1);
+
+    READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
+
+    READ_UINT8 (&br, vop->constant_alpha, 1);
+    if (vop->constant_alpha)
+      READ_UINT8 (&br, vop->constant_alpha_value, 1);
+  }
+
+  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+    if (!vol->complexity_estimation_disable) {
+      GST_WARNING ("Complexity estimation not supported");
+      goto failed;
+    }
+
+    READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
+
+    if (vol->interlaced) {
+      READ_UINT8 (&br, vop->top_field_first, 1);
+      READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
+    }
+  }
+
+  if ((vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
+          vol->sprite_enable == GST_MPEG4_SPRITE_GMG) &&
+      vop->coding_type == GST_MPEG4_S_VOP) {
+
+    /* only if @sprite_trajectory is not NULL we parse it */
+    if (sprite_trajectory && vol->no_of_sprite_warping_points)
+      parse_sprite_trajectory (&br, sprite_trajectory,
+          vol->no_of_sprite_warping_points);
+
+    if (vol->sprite_brightness_change) {
+      GST_WARNING ("sprite_brightness_change not supported");
+      goto failed;
+    }
+
+    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
+      GST_WARNING ("sprite enable static not supported");
+      goto failed;
+    }
+  }
+
+  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+    READ_UINT16 (&br, vop->quant, vol->quant_precision);
+
+    if (vol->shape == GST_MPEG4_GRAYSCALE) {
+      /* TODO implement grayscale support */
+      GST_WARNING ("Grayscale shapes no supported");
+
+      /* TODO implement me */
+      goto failed;
+    }
+
+    if (vop->coding_type != GST_MPEG4_I_VOP) {
+      READ_UINT8 (&br, vop->fcode_forward, 3);
+      CHECK_ALLOWED (vop->fcode_forward, 1, 7);
+    }
+
+    if (vop->coding_type == GST_MPEG4_B_VOP) {
+      READ_UINT8 (&br, vop->fcode_backward, 3);
+      CHECK_ALLOWED (vop->fcode_backward, 1, 7);
+    }
+  }
+
+  if (!vol->scalability) {
+    if (vol->shape != GST_MPEG4_RECTANGULAR)
+      READ_UINT8 (&br, vop->shape_coding_type, 1);
+
+  } else {
+    if (vol->enhancement_type) {
+      READ_UINT8 (&br, vop->load_backward_shape, 1);
+
+      if (vop->load_backward_shape) {
+        GST_WARNING ("Load backward shape not supported");
+        goto failed;
+      }
+
+      READ_UINT8 (&br, vop->ref_select_code, 2);
+    }
+  }
+
+  vop->size = gst_bit_reader_get_pos (&br);
+  /* More things to possibly parse ... */
+
+  return GST_MPEG4_PARSER_OK;
+
+failed:
+  GST_WARNING ("failed parsing \"Video Object Plane\"");
+  return GST_MPEG4_PARSER_ERROR;
+
+wrong_start_code:
+  GST_WARNING ("got buffer with wrong start code");
+  goto failed;
+}
+
+/**
+ * gst_mpeg4_parse_video_plane_with_short_header:
+ * @shorthdr: The #GstMpeg4VideoPlaneShortHdr to parse
+ * @data: The data to parse
+ * @size: The size of the @data to parse
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
+    shorthdr, const guint8 * data, gsize size)
+{
+  guint8 zero_bits;
+
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);
+
+  if (gst_bit_reader_get_remaining (&br) < 48)
+    goto failed;
+
+  if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20)
+    goto failed;
+
+  shorthdr->temporal_reference =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
+  CHECK_MARKER (&br);
+  zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  if (zero_bits != 0x00)
+    goto failed;
+
+  shorthdr->split_screen_indicator =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  shorthdr->document_camera_indicator =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  shorthdr->full_picture_freeze_release =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  shorthdr->source_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
+
+  /* Set parameters/Table 6-25 */
+  switch (shorthdr->source_format) {
+    case 0x01:
+      shorthdr->vop_width = 128;
+      shorthdr->vop_height = 96;
+      shorthdr->num_macroblocks_in_gob = 8;
+      shorthdr->num_gobs_in_vop = 6;
+      break;
+    case 0x02:
+      shorthdr->vop_width = 176;
+      shorthdr->vop_height = 144;
+      shorthdr->num_macroblocks_in_gob = 11;
+      shorthdr->num_gobs_in_vop = 9;
+      break;
+    case 0x03:
+      shorthdr->vop_width = 352;
+      shorthdr->vop_height = 288;
+      shorthdr->num_macroblocks_in_gob = 22;
+      shorthdr->num_gobs_in_vop = 18;
+      break;
+    case 0x04:
+      shorthdr->vop_width = 704;
+      shorthdr->vop_height = 576;
+      shorthdr->num_macroblocks_in_gob = 88;
+      shorthdr->num_gobs_in_vop = 18;
+      break;
+    case 0x05:
+      shorthdr->vop_width = 1408;
+      shorthdr->vop_height = 1152;
+      shorthdr->num_macroblocks_in_gob = 352;
+      shorthdr->num_gobs_in_vop = 18;
+      break;
+    default:
+      shorthdr->vop_width = 0;
+      shorthdr->vop_height = 0;
+      shorthdr->num_macroblocks_in_gob = 0;
+      shorthdr->num_gobs_in_vop = 0;
+  }
+
+  shorthdr->picture_coding_type =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
+
+  if (zero_bits != 0x00)
+    goto failed;
+
+  shorthdr->vop_quant = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
+  zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+  if (zero_bits != 0x00)
+    goto failed;
+
+  do {
+    READ_UINT8 (&br, shorthdr->pei, 1);
+
+    if (shorthdr->pei == 1)
+      READ_UINT8 (&br, shorthdr->psupp, 8);
+
+  } while (shorthdr->pei == 1);
+
+  shorthdr->size = gst_bit_reader_get_pos (&br);
+
+  return GST_MPEG4_PARSER_OK;
+
+failed:
+  GST_WARNING ("Could not parse the Plane short header");
+
+  return GST_MPEG4_PARSER_ERROR;
+}
+
+/**
+ * gst_mpeg4_parse_video_packet_header:
+ * @videopackethdr: The #GstMpeg4VideoPacketHdr structure to fill
+ * @vol: The last parsed #GstMpeg4VideoObjectLayer, will be updated
+ * with the informations found during the parsing
+ * @vop: The last parsed #GstMpeg4VideoObjectPlane, will be updated
+ * with the informations found during the parsing
+ * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
+ * with the informations found during the parsing
+ * @data: The data to parse, should be set after the resync marker.
+ * @size: The size of the data to parse
+ *
+ * Parsers @data containing the video packet header
+ * and fills the @videopackethdr structure
+ */
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
+    GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
+    GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
+    gsize size)
+{
+  guint8 markersize;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
+  g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);
+
+  markersize = compute_resync_marker_size (vop, NULL, NULL);
+
+  CHECK_REMAINING (&br, markersize);
+
+  if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize + 1) != 0x01)
+    goto failed;
+
+  if (vol->shape != GST_MPEG4_RECTANGULAR) {
+    READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
+    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
+        vop->coding_type == GST_MPEG4_I_VOP) {
+
+      CHECK_REMAINING (&br, 56);
+
+      U_READ_UINT16 (&br, vop->width, 13);
+      CHECK_MARKER (&br);
+      U_READ_UINT16 (&br, vop->height, 13);
+      CHECK_MARKER (&br);
+      U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
+      CHECK_MARKER (&br);
+      U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
+      CHECK_MARKER (&br);
+
+      /* Update macroblock infirmations */
+      vop->mb_height = (vop->height + 15) / 16;
+      vop->mb_width = (vop->width + 15) / 16;
+      vop->mb_num = vop->mb_height * vop->mb_width;
+    }
+  }
+
+  READ_UINT16 (&br, videopackethdr->macroblock_number,
+      g_bit_storage (vop->mb_num - 1));
+
+  if (vol->shape != GST_MPEG4_BINARY_ONLY)
+    READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);
+
+  if (vol->shape == GST_MPEG4_RECTANGULAR)
+    READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
+
+  if (videopackethdr->header_extension_code) {
+    guint timeincr = 0;
+    guint8 bit = 0, coding_type;
+
+    do {
+      READ_UINT8 (&br, bit, 1);
+      timeincr++;
+    } while (bit);
+
+    vol->vop_time_increment_bits = timeincr;
+
+    CHECK_MARKER (&br);
+    READ_UINT16 (&br, vop->time_increment, timeincr);
+    CHECK_MARKER (&br);
+    READ_UINT8 (&br, coding_type, 2);
+    vop->coding_type = coding_type;
+
+    if (vol->shape != GST_MPEG4_RECTANGULAR) {
+      READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
+      if (vop->coding_type != GST_MPEG4_I_VOP)
+        READ_UINT8 (&br, vop->shape_coding_type, 1);
+    }
+
+    if (vol->shape != GST_MPEG4_BINARY_ONLY) {
+      READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);
+
+      if (sprite_trajectory && vol->sprite_enable == GST_MPEG4_SPRITE_GMG &&
+          vop->coding_type == GST_MPEG4_S_VOP &&
+          vol->no_of_sprite_warping_points > 0) {
+
+        parse_sprite_trajectory (&br, sprite_trajectory,
+            vol->no_of_sprite_warping_points);
+      }
+
+      if (vol->reduced_resolution_vop_enable &&
+          vol->shape == GST_MPEG4_RECTANGULAR &&
+          (vop->coding_type == GST_MPEG4_P_VOP ||
+              vop->coding_type == GST_MPEG4_I_VOP))
+        READ_UINT8 (&br, vop->reduced_resolution, 1);
+
+      if (vop->coding_type != GST_MPEG4_I_VOP) {
+        READ_UINT8 (&br, vop->fcode_forward, 3);
+        CHECK_ALLOWED (vop->fcode_forward, 1, 7);
+      }
+
+      if (vop->coding_type == GST_MPEG4_B_VOP) {
+        READ_UINT8 (&br, vop->fcode_backward, 3);
+        CHECK_ALLOWED (vop->fcode_backward, 1, 7);
+      }
+    }
+  }
+
+  if (vol->newpred_enable) {
+    guint16 nbbits =
+        vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;
+
+    READ_UINT16 (&br, vop->id, nbbits);
+    READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
+    if (vop->id_for_prediction_indication) {
+      /* Would be nice if the standard actually told us... */
+      READ_UINT16 (&br, vop->id, nbbits);
+      CHECK_MARKER (&br);
+    }
+  }
+
+  videopackethdr->size = gst_bit_reader_get_pos (&br);
+
+failed:
+  GST_DEBUG ("Failed to parse video packet header");
+
+  return GST_MPEG4_PARSER_NO_PACKET;
+}
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstmpeg4parser.h b/ext/codecparsers/gst-libs/gst/codecparsers/gstmpeg4parser.h
new file mode 100644 (file)
index 0000000..6864b06
--- /dev/null
@@ -0,0 +1,578 @@
+/*
+ * GStreamer
+ * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_MPEG4UTIL_H__
+#define __GST_MPEG4UTIL_H__
+
+#include <gst/gst.h>
+#include <gst/base/gstbitreader.h>
+
+typedef struct _GstMpeg4VisualObjectSequence    GstMpeg4VisualObjectSequence;
+typedef struct _GstMpeg4VisualObject            GstMpeg4VisualObject;
+typedef struct _GstMpeg4VideoObjectLayer        GstMpeg4VideoObjectLayer;
+typedef struct _GstMpeg4GroupOfVOP              GstMpeg4GroupOfVOP;
+typedef struct _GstMpeg4VideoObjectPlane        GstMpeg4VideoObjectPlane;
+typedef struct _GstMpeg4VideoSignalType         GstMpeg4VideoSignalType;
+typedef struct _GstMpeg4VideoPlaneShortHdr      GstMpeg4VideoPlaneShortHdr;
+typedef struct _GstMpeg4VideoPacketHdr          GstMpeg4VideoPacketHdr;
+
+typedef struct _GstMpeg4SpriteTrajectory        GstMpeg4SpriteTrajectory;
+
+typedef struct _GstMpeg4Packet                  GstMpeg4Packet;
+
+/**
+ * GstMpeg4StartCode:
+ *
+ * Defines the different startcodes present in the bitstream as
+ * defined in: Table 6-3 â€” Start code values
+ */
+typedef enum
+{
+  GST_MPEG4_VIDEO_OBJ_FIRST      = 0x00,
+  GST_MPEG4_VIDEO_OBJ_LAST       = 0x1f,
+  GST_MPEG4_VIDEO_LAYER_FIRST    = 0x20,
+  GST_MPEG4_VIDEO_LAYER_LAST     = 0x2f,
+  GST_MPEG4_VISUAL_OBJ_SEQ_START = 0xb0,
+  GST_MPEG4_VISUAL_OBJ_SEQ_END   = 0xb1,
+  GST_MPEG4_USER_DATA            = 0xb2,
+  GST_MPEG4_GROUP_OF_VOP         = 0xb3,
+  GST_MPEG4_VIDEO_SESSION_ERR    = 0xb4,
+  GST_MPEG4_VISUAL_OBJ           = 0xb5,
+  GST_MPEG4_VIDEO_OBJ_PLANE      = 0xb6,
+  GST_MPEG4_FBA                  = 0xba,
+  GST_MPEG4_FBA_PLAN             = 0xbb,
+  GST_MPEG4_MESH                 = 0xbc,
+  GST_MPEG4_MESH_PLAN            = 0xbd,
+  GST_MPEG4_STILL_TEXTURE_OBJ    = 0xbe,
+  GST_MPEG4_TEXTURE_SPATIAL      = 0xbf,
+  GST_MPEG4_TEXTURE_SNR_LAYER    = 0xc0,
+  GST_MPEG4_TEXTURE_TILE         = 0xc1,
+  GST_MPEG4_SHAPE_LAYER          = 0xc2,
+  GST_MPEG4_STUFFING             = 0xc3,
+  GST_MPEG4_SYSTEM_FIRST         = 0xc6,
+  GST_MPEG4_SYSTEM_LAST          = 0xff,
+  GST_MPEG4_RESYNC               = 0xfff
+} GstMpeg4StartCode;
+
+/**
+ * GstMpeg4VisualObjectType:
+ *
+ * Defines the different visual object types as
+ * defined in: Table 6-5 -- Meaning of visual object type
+ */
+typedef enum {
+  GST_MPEG4_VIDEO_ID         = 0x01,
+  GST_MPEG4_STILL_TEXTURE_ID = 0x02,
+  GST_MPEG4_STILL_MESH_ID    = 0x03,
+  GST_MPEG4_STILL_FBA_ID     = 0x04,
+  GST_MPEG4_STILL_3D_MESH_ID = 0x05,
+  /*... reserved */
+
+} GstMpeg4VisualObjectType;
+
+/**
+ * GstMpeg4AspectRatioInfo:
+ * @GST_MPEG4_SQUARE: 1:1 square
+ * @GST_MPEG4_625_TYPE_4_3: 12:11 (625-type for 4:3 picture)
+ * @GST_MPEG4_525_TYPE_4_3: 10:11 (525-type for 4:3 picture)
+ * @GST_MPEG4_625_TYPE_16_9: 16:11 (625-type stretched for 16:9 picture)
+ * @GST_MPEG4_525_TYPE_16_9: 40:33 (525-type stretched for 16:9 picture)
+ * @GST_MPEG4_EXTENDED_PAR: Extended par
+ *
+ * Defines the different pixel aspect ratios as
+ * defined in: Table 6-12 -- Meaning of pixel aspect ratio
+ */
+typedef enum {
+  GST_MPEG4_SQUARE        = 0x01,
+  GST_MPEG4_625_TYPE_4_3  = 0x02,
+  GST_MPEG4_525_TYPE_4_3  = 0x03,
+  GST_MPEG4_625_TYPE_16_9 = 0x04,
+  GST_MPEG4_525_TYPE_16_9 = 0x05,
+  GST_MPEG4_EXTENDED_PAR  = 0x0f,
+} GstMpeg4AspectRatioInfo;
+
+/**
+ * GstMpeg4ParseResult:
+ * @GST_MPEG4_PARSER_OK: The parsing went well
+ * @GST_MPEG4_PARSER_BROKEN_DATA: The bitstream was broken
+ * @GST_MPEG4_PARSER_NO_PACKET: There was no packet in the buffer
+ * @GST_MPEG4_PARSER_NO_PACKET_END: There was no packet end in the buffer
+ * @GST_MPEG4_PARSER_NO_PACKET_ERROR: An error accured durint the parsing
+ *
+ * Result type of any parsing function.
+ */
+typedef enum {
+  GST_MPEG4_PARSER_OK,
+  GST_MPEG4_PARSER_BROKEN_DATA,
+  GST_MPEG4_PARSER_NO_PACKET,
+  GST_MPEG4_PARSER_NO_PACKET_END,
+  GST_MPEG4_PARSER_ERROR,
+} GstMpeg4ParseResult;
+
+/**
+ * GstMpeg4VideoObjectCodingType:
+ * @GST_MPEG4_I_VOP: intra-coded (I)
+ * @GST_MPEG4_P_VOP: predictive-coded (P)
+ * @GST_MPEG4_B_VOP: bidirectionally-predictive-coded (B)
+ * @GST_MPEG4_S_VOP: sprite (S)
+ *
+ * The vop coding types as defined in:
+ * Table 6-20 -- Meaning of vop_coding_type
+ */
+typedef enum {
+  GST_MPEG4_I_VOP = 0x0,
+  GST_MPEG4_P_VOP = 0x1,
+  GST_MPEG4_B_VOP = 0x2,
+  GST_MPEG4_S_VOP = 0x3
+} GstMpeg4VideoObjectCodingType;
+
+/**
+ * GstMpeg4ChromaFormat
+ *
+ * The chroma format in use as
+ * defined in: Table 6-13 -- Meaning of chroma_format
+ */
+typedef enum {
+  /* Other value are reserved */
+  GST_MPEG4_CHROMA_4_2_0 = 0x01
+} GstMpeg4ChromaFormat;
+
+/**
+ * GstMpeg4VideoObjectLayerShape:
+ *
+ * The different video object layer shapes as defined in:
+ * Table 6-16 â€” Video Object Layer shape type
+ */
+typedef enum {
+  GST_MPEG4_RECTANGULAR,
+  GST_MPEG4_BINARY,
+  GST_MPEG4_BINARY_ONLY,
+  GST_MPEG4_GRAYSCALE
+} GstMpeg4VideoObjectLayerShape;
+
+/**
+ * GstMpeg4SpriteEnable:
+ *
+ * Indicates the usage of static sprite coding
+ * or global motion compensation (GMC) as defined in:
+ * Table V2 - 2 -- Meaning of sprite_enable codewords
+ */
+typedef enum {
+  GST_MPEG4_SPRITE_UNUSED,
+  GST_MPEG4_SPRITE_STATIC,
+  GST_MPEG4_SPRITE_GMG
+} GstMpeg4SpriteEnable;
+
+/**
+ * GstMpeg4Profile:
+ *
+ * Different defined profiles as defined in:
+ * 9- Profiles and levels
+ *
+ * It is computed using:
+ * Table G.1 â€” FLC table for profile_and_level_indication
+ */
+typedef enum {
+  GST_MPEG4_PROFILE_CORE,
+  GST_MPEG4_PROFILE_MAIN,
+  GST_MPEG4_PROFILE_N_BIT,
+  GST_MPEG4_PROFILE_SIMPLE,
+  GST_MPEG4_PROFILE_HYBRID,
+  GST_MPEG4_PROFILE_RESERVED,
+  GST_MPEG4_PROFILE_SIMPLE_FBA,
+  GST_MPEG4_PROFILE_CORE_STUDIO,
+  GST_MPEG4_PROFILE_SIMPLE_STUDIO,
+  GST_MPEG4_PROFILE_CORE_SCALABLE,
+  GST_MPEG4_PROFILE_ADVANCED_CORE,
+  GST_MPEG4_PROFILE_ADVANCED_SIMPLE,
+  GST_MPEG4_PROFILE_SIMPLE_SCALABLE,
+  GST_MPEG4_PROFILE_SCALABLE_TEXTURE,
+  GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION,
+  GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE,
+  GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE,
+  GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE,
+  GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE,
+  GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY
+} GstMpeg4Profile;
+
+/**
+ * GstMpeg4Level:
+ *
+ * Different levels as defined in:
+ * 9- Profiles and levels
+ *
+ * It is computed using:
+ * Table G.1 â€” FLC table for profile_and_level_indication
+ */
+typedef enum {
+  GST_MPEG4_LEVEL0,
+  GST_MPEG4_LEVEL1,
+  GST_MPEG4_LEVEL2,
+  GST_MPEG4_LEVEL3,
+  GST_MPEG4_LEVEL3b,
+  GST_MPEG4_LEVEL4,
+  GST_MPEG4_LEVEL5,
+  GST_MPEG4_LEVEL_RESERVED
+} GstMpeg4Level;
+
+/**
+ * GstMpeg4VisualObjectSequence:
+ *
+ * The visual object sequence structure as defined in:
+ * 6.2.2 Visual Object Sequence and Visual Object
+ */
+struct _GstMpeg4VisualObjectSequence {
+  guint8 profile_and_level_indication;
+
+  /* Computed according to:
+   * Table G.1 â€” FLC table for profile_and_level_indication */
+  GstMpeg4Level level;
+  GstMpeg4Profile profile;
+};
+
+/**
+ * The visual object structure as defined in:
+ * 6.2.2 Visual Object Sequence and Visual Object
+ */
+struct _GstMpeg4VisualObject {
+  guint8 is_identifier;
+  /* If is_identifier */
+  guint8 verid;
+  guint8 priority;
+
+  GstMpeg4VisualObjectType type;
+};
+
+/**
+ * GstMpeg4VideoSignalType:
+ *
+ * The video signal type structure as defined in:
+ * 6.2.2 Visual Object Sequence and Visual Object.
+ */
+struct _GstMpeg4VideoSignalType {
+  guint8 type;
+
+  guint8 format;
+  guint8 range;
+  guint8 color_description;
+  guint8 color_primaries;
+  guint8 transfer_characteristics;
+  guint8 matrix_coefficients;
+};
+
+/**
+ * GstMpeg4VideoPlaneShortHdr:
+ *
+ * The video plane short header structure as defined in:
+ * 6.2.5.2 Video Plane with Short Header
+ */
+struct _GstMpeg4VideoPlaneShortHdr {
+  guint8 temporal_reference;
+  guint8 split_screen_indicator;
+  guint8 document_camera_indicator;
+  guint8 full_picture_freeze_release;
+  guint8 source_format;
+  guint8 picture_coding_type;
+  guint8 vop_quant;
+  guint8 pei;
+  guint8 psupp;
+
+  /*  Gob layer specific fields */
+  guint8 gob_header_empty;
+  guint8 gob_number;
+  guint8 gob_frame_id;
+  guint8 quant_scale;
+
+  /* Computed
+   * If all the values are set to 0, then it is reserved
+   * Table 6-25 -- Parameters Defined by source_format Field
+   */
+  guint16 vop_width;
+  guint16 vop_height;
+  guint16 num_macroblocks_in_gob;
+  guint8 num_gobs_in_vop;
+
+  /* The size in bits */
+  guint size;
+};
+
+/**
+ * GstMpeg4VideoObjectLayer:
+ *
+ * The video object layer structure as defined in:
+ * 6.2.3 Video Object Layer
+ */
+struct _GstMpeg4VideoObjectLayer {
+  guint8 random_accessible_vol;
+  guint8 video_object_type_indication;
+
+  guint8 is_object_layer_identifier;
+  /* if is_object_layer_identifier */
+  guint8 verid;
+  guint8 priority;
+
+  GstMpeg4AspectRatioInfo aspect_ratio_info;
+  guint8 par_width;
+  guint8 par_height;
+
+  guint8 control_parameters;
+  /* if control_parameters */
+  GstMpeg4ChromaFormat chroma_format;
+  guint8 low_delay;
+  guint8 vbv_parameters;
+  /* if vbv_parameters */
+  guint16 first_half_bitrate;
+  guint16 latter_half_bitrate;
+  guint16 first_half_vbv_buffer_size;
+  guint16 latter_half_vbv_buffer_size;
+  guint16 first_half_vbv_occupancy;
+  guint16 latter_half_vbv_occupancy;
+
+  /* Computed values */
+  guint32 bit_rate;
+  guint32 vbv_buffer_size;
+
+  GstMpeg4VideoObjectLayerShape shape;
+  /* if shape == GST_MPEG4_GRAYSCALE && verid =! 1 */
+  guint8 shape_extension;
+
+  guint16 vop_time_increment_resolution;
+  guint8 vop_time_increment_bits;
+  guint8 fixed_vop_rate;
+  /* if fixed_vop_rate */
+  guint16 fixed_vop_time_increment;
+
+  guint16 width;
+  guint16 height;
+  guint8 interlaced;
+  guint8 obmc_disable;
+
+  GstMpeg4SpriteEnable sprite_enable;
+  /* if vol->sprite_enable == SPRITE_GMG or SPRITE_STATIC*/
+  /* if vol->sprite_enable != GST_MPEG4_SPRITE_GMG */
+  guint16 sprite_width;
+  guint16 sprite_height;
+  guint16 sprite_left_coordinate;
+  guint16 sprite_top_coordinate;
+
+  guint8 no_of_sprite_warping_points;
+  guint8 sprite_warping_accuracy;
+  guint8 sprite_brightness_change;
+  /* if vol->sprite_enable != GST_MPEG4_SPRITE_GMG */
+  guint8 low_latency_sprite_enable;
+
+  /* if shape != GST_MPEG4_RECTANGULAR */
+  guint8 sadct_disable;
+
+  guint8 not_8_bit;
+
+  /* if no_8_bit */
+  guint8 quant_precision;
+  guint8 bits_per_pixel;
+
+  /* if shape == GRAYSCALE */
+  guint8 no_gray_quant_update;
+  guint8 composition_method;
+  guint8 linear_composition;
+
+  guint8 quant_type;
+  /* if quant_type */
+  guint8 load_intra_quant_mat;
+  guint8 intra_quant_mat[64];
+  guint8 load_non_intra_quant_mat;
+  guint8 non_intra_quant_mat[64];
+
+  guint8 quarter_sample;
+  guint8 complexity_estimation_disable;
+  guint8 resync_marker_disable;
+  guint8 data_partitioned;
+  guint8 reversible_vlc;
+  guint8 newpred_enable;
+  guint8 reduced_resolution_vop_enable;
+  guint8 scalability;
+  guint8 enhancement_type;
+
+  GstMpeg4VideoPlaneShortHdr short_hdr;
+};
+
+/**
+ * GstMpeg4SpriteTrajectory:
+ *
+ * The sprite trajectory structure as defined in:
+ * 7.8.4 Sprite reference point decoding and
+ * 6.2.5.4 Sprite coding
+ */
+struct _GstMpeg4SpriteTrajectory {
+  guint16 vop_ref_points[63]; /* Defined as "du" in 6.2.5.4 */
+  guint16 sprite_ref_points[63]; /* Defined as "dv" in 6.2.5.4 */
+};
+
+/**
+ * GstMpeg4GroupOfVOP:
+ *
+ * The group of video object plane structure as defined in:
+ * 6.2.4 Group of Video Object Plane
+ */
+struct _GstMpeg4GroupOfVOP {
+  guint8 hours;
+  guint8 minutes;
+  guint8 seconds;
+
+  guint8 closed;
+  guint8 broken_link;
+};
+
+/**
+ * GstMpeg4VideoObjectPlane:
+ *
+ * The Video object plane structure as defined in:
+ * 6.2.5 Video Object Plane and Video Plane with Short Header
+ */
+struct _GstMpeg4VideoObjectPlane {
+  GstMpeg4VideoObjectCodingType coding_type;
+
+  guint8  modulo_time_base;
+  guint16 time_increment;
+
+  guint8  coded;
+  /* if newpred_enable */
+  guint16 id;
+  guint8  id_for_prediction_indication;
+  guint16 id_for_prediction;
+
+  guint16 width;
+  guint16 height;
+  guint16 horizontal_mc_spatial_ref;
+  guint16 vertical_mc_spatial_ref;
+
+  guint8  rounding_type;
+  /*if vol->shape != GST_MPEG4_RECTANGULAR */
+  guint8  background_composition;
+  guint8  change_conv_ratio_disable;
+  guint8  constant_alpha;
+  guint8  constant_alpha_value;
+  guint8  reduced_resolution;
+
+  guint8  intra_dc_vlc_thr;
+
+
+  guint8  top_field_first;
+  guint8  alternate_vertical_scan_flag;
+
+  guint16 quant;
+
+  guint8  fcode_forward;
+  guint8  fcode_backward;
+
+  guint8  shape_coding_type;
+  guint8  load_backward_shape;
+  guint8  ref_select_code;
+
+  /* Computed macroblock informations */
+  guint16 mb_height;
+  guint16 mb_width;
+  guint mb_num;
+
+  /* The size of the header */
+  guint    size;
+};
+
+/**
+ * GstMpeg4VideoPacketHdr:
+ * @size: Size of the header in bit.
+ *
+ * The video packet header structure as defined in:
+ * 6.2.5.2 Video Plane with Short Header
+ */
+struct _GstMpeg4VideoPacketHdr {
+  guint8  header_extension_code;
+  guint16 macroblock_number;
+  guint16 quant_scale;
+  guint   size;
+};
+
+/**
+ * GstMpeg4Packet:
+ * @type: the type of the packet that start at @offset
+ * @data: the data containing packet starting at @offset
+ * @offset: offset of the start of the packet (without the 3 bytes startcode), but
+ * including the #GstMpeg4StartCode byte.
+ * @size: The size in bytes of the packet or %G_MAXUINT if the end wasn't found.
+ * @marker_size: The size in bit of the resync marker.
+ *
+ * A structure that contains the type of a packet, its offset and its size
+ */
+struct _GstMpeg4Packet
+{
+  const guint8     *data;
+  guint             offset;
+  gsize             size;
+  guint             marker_size;
+
+  GstMpeg4StartCode type;
+};
+
+GstMpeg4ParseResult gst_h263_parse       (GstMpeg4Packet * packet,
+                                          const guint8 * data, guint offset,
+                                          gsize size);
+
+
+GstMpeg4ParseResult gst_mpeg4_parse      (GstMpeg4Packet * packet,
+                                          gboolean skip_user_data,
+                                          GstMpeg4VideoObjectPlane *vop,
+                                          const guint8 * data, guint offset,
+                                          gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_plane       (GstMpeg4VideoObjectPlane *vop,
+                                          GstMpeg4SpriteTrajectory *sprite_trajectory,
+                                          GstMpeg4VideoObjectLayer *vol,
+                                          const guint8 * data,
+                                          gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_group_of_vop             (GstMpeg4GroupOfVOP *gov,
+                                          const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_object_layer       (GstMpeg4VideoObjectLayer *vol,
+                                          GstMpeg4VisualObject *vo,
+                                          const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object            (GstMpeg4VisualObject *vo,
+                                          GstMpeg4VideoSignalType *signal_type,
+                                          const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_visual_object_sequence   (GstMpeg4VisualObjectSequence *vos,
+                                          const guint8 * data, gsize size);
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * shorthdr,
+                                          const guint8 * data, gsize size);
+
+GstMpeg4ParseResult
+gst_mpeg4_parse_video_packet_header      (GstMpeg4VideoPacketHdr * videopackethdr,
+                                          GstMpeg4VideoObjectLayer * vol,
+                                          GstMpeg4VideoObjectPlane * vop,
+                                          GstMpeg4SpriteTrajectory * sprite_trajectory,
+                                          const guint8 * data, gsize size);
+
+#endif /* __GST_MPEG4UTIL_H__ */
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstmpegvideoparser.c b/ext/codecparsers/gst-libs/gst/codecparsers/gstmpegvideoparser.c
new file mode 100644 (file)
index 0000000..905d53d
--- /dev/null
@@ -0,0 +1,871 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * From bad/sys/vdpau/mpeg/mpegutil.c:
+ *   Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com>
+ *   Copyright (C) <2009> Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+/**
+ * SECTION:gstmpegvideoparser
+ * @short_description: Convenience library for mpeg1 and 2 video
+ * bitstream parsing.
+ *
+ * <refsect2>
+ * <para>
+ * Provides useful functions for mpeg videos bitstream parsing.
+ * </para>
+ * </refsect2>
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "gstmpegvideoparser.h"
+#include "parserutils.h"
+
+#include <string.h>
+#include <gst/base/gstbitreader.h>
+#include <gst/base/gstbytereader.h>
+
+#define MARKER_BIT 0x1
+
+/* default intra quant matrix, in zig-zag order */
+static const guint8 default_intra_quantizer_matrix[64] = {
+  8,
+  16, 16,
+  19, 16, 19,
+  22, 22, 22, 22,
+  22, 22, 26, 24, 26,
+  27, 27, 27, 26, 26, 26,
+  26, 27, 27, 27, 29, 29, 29,
+  34, 34, 34, 29, 29, 29, 27, 27,
+  29, 29, 32, 32, 34, 34, 37,
+  38, 37, 35, 35, 34, 35,
+  38, 38, 40, 40, 40,
+  48, 48, 46, 46,
+  56, 56, 58,
+  69, 69,
+  83
+};
+
+static const guint8 mpeg_zigzag_8x8[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
+};
+
+GST_DEBUG_CATEGORY (mpegvideo_parser_debug);
+#define GST_CAT_DEFAULT mpegvideo_parser_debug
+
+static gboolean initialized = FALSE;
+
+static inline gboolean
+find_start_code (GstBitReader * b)
+{
+  guint32 bits;
+
+  /* 0 bits until byte aligned */
+  while (b->bit != 0) {
+    GET_BITS (b, 1, &bits);
+  }
+
+  /* 0 bytes until startcode */
+  while (gst_bit_reader_peek_bits_uint32 (b, &bits, 32)) {
+    if (bits >> 8 == 0x1) {
+      return TRUE;
+    } else if (gst_bit_reader_skip (b, 8) == FALSE)
+      break;
+  }
+
+  return FALSE;
+
+failed:
+  return FALSE;
+}
+
+/* Set the Pixel Aspect Ratio in our hdr from a ASR code in the data */
+static void
+set_par_from_asr_mpeg1 (GstMpegVideoSequenceHdr * seqhdr, guint8 asr_code)
+{
+  int ratios[16][2] = {
+    {0, 0},                     /* 0, Invalid */
+    {1, 1},                     /* 1, 1.0 */
+    {10000, 6735},              /* 2, 0.6735 */
+    {64, 45},                   /* 3, 0.7031 16:9 625 line */
+    {10000, 7615},              /* 4, 0.7615 */
+    {10000, 8055},              /* 5, 0.8055 */
+    {32, 27},                   /* 6, 0.8437 */
+    {10000, 8935},              /* 7, 0.8935 */
+    {10000, 9375},              /* 8, 0.9375 */
+    {10000, 9815},              /* 9, 0.9815 */
+    {10000, 10255},             /* 10, 1.0255 */
+    {10000, 10695},             /* 11, 1.0695 */
+    {8, 9},                     /* 12, 1.125 */
+    {10000, 11575},             /* 13, 1.1575 */
+    {10000, 12015},             /* 14, 1.2015 */
+    {0, 0},                     /* 15, invalid */
+  };
+  asr_code &= 0xf;
+
+  seqhdr->par_w = ratios[asr_code][0];
+  seqhdr->par_h = ratios[asr_code][1];
+}
+
+static void
+set_fps_from_code (GstMpegVideoSequenceHdr * seqhdr, guint8 fps_code)
+{
+  const gint framerates[][2] = {
+    {30, 1}, {24000, 1001}, {24, 1}, {25, 1},
+    {30000, 1001}, {30, 1}, {50, 1}, {60000, 1001},
+    {60, 1}, {30, 1}
+  };
+
+  if (fps_code && fps_code < 10) {
+    seqhdr->fps_n = framerates[fps_code][0];
+    seqhdr->fps_d = framerates[fps_code][1];
+  } else {
+    GST_DEBUG ("unknown/invalid frame_rate_code %d", fps_code);
+    /* Force a valid framerate */
+    /* FIXME or should this be kept unknown ?? */
+    seqhdr->fps_n = 30000;
+    seqhdr->fps_d = 1001;
+  }
+}
+
+/* @size and @offset are wrt current reader position */
+static inline guint
+scan_for_start_codes (const GstByteReader * reader, guint offset, guint size)
+{
+  const guint8 *data;
+  guint i = 0;
+
+  g_return_val_if_fail ((guint64) offset + size <= reader->size - reader->byte,
+      -1);
+
+  /* we can't find the pattern with less than 4 bytes */
+  if (G_UNLIKELY (size < 4))
+    return -1;
+
+  data = reader->data + reader->byte + offset;
+
+  while (i <= (size - 4)) {
+    if (data[i + 2] > 1) {
+      i += 3;
+    } else if (data[i + 1]) {
+      i += 2;
+    } else if (data[i] || data[i + 2] != 1) {
+      i++;
+    } else {
+      break;
+    }
+  }
+
+  if (i <= (size - 4))
+    return offset + i;
+
+  /* nothing found */
+  return -1;
+}
+
+/****** API *******/
+
+/**
+ * gst_mpeg_video_parse:
+ * @data: The data to parse
+ * @size: The size of @data
+ * @offset: The offset from which to start parsing
+ *
+ * Parses the MPEG 1/2 video bitstream contained in @data , and returns the
+ * detect packets as a list of #GstMpegVideoTypeOffsetSize.
+ *
+ * Returns: TRUE if a packet start code was found
+ */
+gboolean
+gst_mpeg_video_parse (GstMpegVideoPacket * packet,
+    const guint8 * data, gsize size, guint offset)
+{
+  gint off;
+  GstByteReader br;
+
+  if (!initialized) {
+    GST_DEBUG_CATEGORY_INIT (mpegvideo_parser_debug, "codecparsers_mpegvideo",
+        0, "Mpegvideo parser library");
+    initialized = TRUE;
+  }
+
+  if (size <= offset) {
+    GST_DEBUG ("Can't parse from offset %d, buffer is to small", offset);
+    return FALSE;
+  }
+
+  size -= offset;
+  gst_byte_reader_init (&br, &data[offset], size);
+
+  off = scan_for_start_codes (&br, 0, size);
+
+  if (off < 0) {
+    GST_DEBUG ("No start code prefix in this buffer");
+    return FALSE;
+  }
+
+  if (gst_byte_reader_skip (&br, off + 3) == FALSE)
+    goto failed;
+
+  if (gst_byte_reader_get_uint8 (&br, &packet->type) == FALSE)
+    goto failed;
+
+  packet->data = data;
+  packet->offset = offset + off + 4;
+  packet->size = -1;
+
+  /* try to find end of packet */
+  size -= off + 4;
+  off = scan_for_start_codes (&br, 0, size);
+
+  if (off > 0)
+    packet->size = off;
+
+  return TRUE;
+
+failed:
+  {
+    GST_WARNING ("Failed to parse");
+    return FALSE;
+  }
+}
+
+/**
+ * gst_mpeg_video_parse_sequence_header:
+ * @seqhdr: (out): The #GstMpegVideoSequenceHdr structure to fill
+ * @data: The data from which to parse the sequence header
+ * @size: The size of @data
+ * @offset: The offset in byte from which to start parsing @data
+ *
+ * Parses the @seqhdr Mpeg Video Sequence Header structure members from @data
+ *
+ * Returns: %TRUE if the seqhdr could be parsed correctly, %FALSE otherwize.
+ */
+gboolean
+gst_mpeg_video_parse_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
+    const guint8 * data, gsize size, guint offset)
+{
+  GstBitReader br;
+  guint8 bits;
+  guint8 load_intra_flag, load_non_intra_flag;
+
+  g_return_val_if_fail (seqhdr != NULL, FALSE);
+
+  size -= offset;
+
+  if (size < 4)
+    return FALSE;
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  /* Setting the height/width codes */
+  READ_UINT16 (&br, seqhdr->width, 12);
+  READ_UINT16 (&br, seqhdr->height, 12);
+
+  READ_UINT8 (&br, seqhdr->aspect_ratio_info, 4);
+  /* Interpret PAR according to MPEG-1. Needs to be reinterpreted
+   * later, if a sequence_display extension is seen */
+  set_par_from_asr_mpeg1 (seqhdr, seqhdr->aspect_ratio_info);
+
+  READ_UINT8 (&br, seqhdr->frame_rate_code, 4);
+  set_fps_from_code (seqhdr, seqhdr->frame_rate_code);
+
+  READ_UINT32 (&br, seqhdr->bitrate_value, 18);
+  if (seqhdr->bitrate_value == 0x3ffff) {
+    /* VBR stream */
+    seqhdr->bitrate = 0;
+  } else {
+    /* Value in header is in units of 400 bps */
+    seqhdr->bitrate *= 400;
+  }
+
+  READ_UINT8 (&br, bits, 1);
+  if (bits != MARKER_BIT)
+    goto failed;
+
+  /* VBV buffer size */
+  READ_UINT16 (&br, seqhdr->vbv_buffer_size_value, 10);
+
+  /* constrained_parameters_flag */
+  READ_UINT8 (&br, seqhdr->constrained_parameters_flag, 1);
+
+  /* load_intra_quantiser_matrix */
+  READ_UINT8 (&br, load_intra_flag, 1);
+  if (load_intra_flag) {
+    gint i;
+    for (i = 0; i < 64; i++)
+      READ_UINT8 (&br, seqhdr->intra_quantizer_matrix[i], 8);
+  } else
+    memcpy (seqhdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);
+
+  /* non intra quantizer matrix */
+  READ_UINT8 (&br, load_non_intra_flag, 1);
+  if (load_non_intra_flag) {
+    gint i;
+    for (i = 0; i < 64; i++)
+      READ_UINT8 (&br, seqhdr->non_intra_quantizer_matrix[i], 8);
+  } else
+    memset (seqhdr->non_intra_quantizer_matrix, 16, 64);
+
+  /* dump some info */
+  GST_LOG ("width x height: %d x %d", seqhdr->width, seqhdr->height);
+  GST_LOG ("fps: %d/%d", seqhdr->fps_n, seqhdr->fps_d);
+  GST_LOG ("par: %d/%d", seqhdr->par_w, seqhdr->par_h);
+  GST_LOG ("bitrate: %d", seqhdr->bitrate);
+
+  return TRUE;
+
+  /* ERRORS */
+failed:
+  {
+    GST_WARNING ("Failed to parse sequence header");
+    /* clear out stuff */
+    memset (seqhdr, 0, sizeof (*seqhdr));
+    return FALSE;
+  }
+}
+
+/**
+ * gst_mpeg_video_parse_sequence_extension:
+ * @seqext: (out): The #GstMpegVideoSequenceExt structure to fill
+ * @data: The data from which to parse the sequence extension
+ * @size: The size of @data
+ * @offset: The offset in byte from which to start parsing @data
+ *
+ * Parses the @seqext Mpeg Video Sequence Extension structure members from @data
+ *
+ * Returns: %TRUE if the seqext could be parsed correctly, %FALSE otherwize.
+ */
+gboolean
+gst_mpeg_video_parse_sequence_extension (GstMpegVideoSequenceExt * seqext,
+    const guint8 * data, gsize size, guint offset)
+{
+  GstBitReader br;
+
+  g_return_val_if_fail (seqext != NULL, FALSE);
+
+  size -= offset;
+
+  if (size < 6) {
+    GST_DEBUG ("not enough bytes to parse the extension");
+    return FALSE;
+  }
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
+      GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE) {
+    GST_DEBUG ("Not parsing a sequence extension");
+    return FALSE;
+  }
+
+  /* skip profile and level escape bit */
+  gst_bit_reader_skip_unchecked (&br, 1);
+
+  seqext->profile = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
+  seqext->level = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);
+
+  /* progressive */
+  seqext->progressive = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+  /* chroma format */
+  seqext->chroma_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+
+  /* resolution extension */
+  seqext->horiz_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+  seqext->vert_size_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+
+  seqext->bitrate_ext = gst_bit_reader_get_bits_uint16_unchecked (&br, 12);
+
+  /* skip marker bits */
+  gst_bit_reader_skip_unchecked (&br, 1);
+
+  seqext->vbv_buffer_size_extension =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
+  seqext->low_delay = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+  /* framerate extension */
+  seqext->fps_n_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+  seqext->fps_d_ext = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+
+  return TRUE;
+}
+
+gboolean
+gst_mpeg_video_parse_sequence_display_extension (GstMpegVideoSequenceDisplayExt
+    * seqdisplayext, const guint8 * data, gsize size, guint offset)
+{
+  GstBitReader br;
+
+  g_return_val_if_fail (seqdisplayext != NULL, FALSE);
+  if (offset > size)
+    return FALSE;
+
+  size -= offset;
+  if (size < 5) {
+    GST_DEBUG ("not enough bytes to parse the extension");
+    return FALSE;
+  }
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
+      GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY) {
+    GST_DEBUG ("Not parsing a sequence display extension");
+    return FALSE;
+  }
+
+  seqdisplayext->video_format =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 3);
+  seqdisplayext->colour_description_flag =
+      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+
+  if (seqdisplayext->colour_description_flag) {
+    seqdisplayext->colour_primaries =
+        gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
+    seqdisplayext->transfer_characteristics =
+        gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
+    seqdisplayext->matrix_coefficients =
+        gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
+  }
+
+  if (gst_bit_reader_get_remaining (&br) < 29) {
+    GST_DEBUG ("Not enough remaining bytes to parse the extension");
+    return FALSE;
+  }
+
+  seqdisplayext->display_horizontal_size =
+      gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
+  /* skip marker bit */
+  gst_bit_reader_skip_unchecked (&br, 1);
+  seqdisplayext->display_vertical_size =
+      gst_bit_reader_get_bits_uint16_unchecked (&br, 14);
+
+  return TRUE;
+}
+
+gboolean
+gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr * seqhdr,
+    GstMpegVideoSequenceExt * seqext,
+    GstMpegVideoSequenceDisplayExt * displayext)
+{
+  guint32 w;
+  guint32 h;
+
+  if (seqext) {
+    seqhdr->fps_n = seqhdr->fps_n * (seqext->fps_n_ext + 1);
+    seqhdr->fps_d = seqhdr->fps_d * (seqext->fps_d_ext + 1);
+    /* Extend width and height to 14 bits by adding the extension bits */
+    seqhdr->width |= (seqext->horiz_size_ext << 12);
+    seqhdr->height |= (seqext->vert_size_ext << 12);
+  }
+
+  w = seqhdr->width;
+  h = seqhdr->height;
+  if (displayext) {
+    /* Use the display size for calculating PAR when display ext present */
+    w = displayext->display_horizontal_size;
+    h = displayext->display_vertical_size;
+  }
+
+  /* Pixel_width = DAR_width * display_vertical_size */
+  /* Pixel_height = DAR_height * display_horizontal_size */
+  switch (seqhdr->aspect_ratio_info) {
+    case 0x01:                 /* Square pixels */
+      seqhdr->par_w = seqhdr->par_h = 1;
+      break;
+    case 0x02:                 /* 3:4 DAR = 4:3 pixels */
+      seqhdr->par_w = 4 * h;
+      seqhdr->par_h = 3 * w;
+      break;
+    case 0x03:                 /* 9:16 DAR */
+      seqhdr->par_w = 16 * h;
+      seqhdr->par_h = 9 * w;
+      break;
+    case 0x04:                 /* 1:2.21 DAR */
+      seqhdr->par_w = 221 * h;
+      seqhdr->par_h = 100 * w;
+      break;
+    default:
+      GST_DEBUG ("unknown/invalid aspect_ratio_information %d",
+          seqhdr->aspect_ratio_info);
+      break;
+  }
+
+  return TRUE;
+}
+
+/**
+ * gst_mpeg_video_parse_quant_matrix_extension:
+ * @quant: (out): The #GstMpegVideoQuantMatrixExt structure to fill
+ * @data: The data from which to parse the Quantization Matrix extension
+ * @size: The size of @data
+ * @offset: The offset in byte from which to start the parsing
+ *
+ * Parses the @quant Mpeg Video Quant Matrix Extension structure members from
+ * @data
+ *
+ * Returns: %TRUE if the quant matrix extension could be parsed correctly,
+ * %FALSE otherwize.
+ */
+gboolean
+gst_mpeg_video_parse_quant_matrix_extension (GstMpegVideoQuantMatrixExt * quant,
+    const guint8 * data, gsize size, guint offset)
+{
+  guint8 i;
+  GstBitReader br;
+
+  g_return_val_if_fail (quant != NULL, FALSE);
+
+  size -= offset;
+
+  if (size < 1) {
+    GST_DEBUG ("not enough bytes to parse the extension");
+    return FALSE;
+  }
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
+      GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX) {
+    GST_DEBUG ("Not parsing a quant matrix extension");
+    return FALSE;
+  }
+
+  READ_UINT8 (&br, quant->load_intra_quantiser_matrix, 1);
+  if (quant->load_intra_quantiser_matrix) {
+    for (i = 0; i < 64; i++) {
+      READ_UINT8 (&br, quant->intra_quantiser_matrix[i], 8);
+    }
+  }
+
+  READ_UINT8 (&br, quant->load_non_intra_quantiser_matrix, 1);
+  if (quant->load_non_intra_quantiser_matrix) {
+    for (i = 0; i < 64; i++) {
+      READ_UINT8 (&br, quant->non_intra_quantiser_matrix[i], 8);
+    }
+  }
+
+  READ_UINT8 (&br, quant->load_chroma_intra_quantiser_matrix, 1);
+  if (quant->load_chroma_intra_quantiser_matrix) {
+    for (i = 0; i < 64; i++) {
+      READ_UINT8 (&br, quant->chroma_intra_quantiser_matrix[i], 8);
+    }
+  }
+
+  READ_UINT8 (&br, quant->load_chroma_non_intra_quantiser_matrix, 1);
+  if (quant->load_chroma_non_intra_quantiser_matrix) {
+    for (i = 0; i < 64; i++) {
+      READ_UINT8 (&br, quant->chroma_non_intra_quantiser_matrix[i], 8);
+    }
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("error parsing \"Quant Matrix Extension\"");
+  return FALSE;
+}
+
+/**
+ * gst_mpeg_video_parse_picture_extension:
+ * @ext: (out): The #GstMpegVideoPictureExt structure to fill
+ * @data: The data from which to parse the picture extension
+ * @size: The size of @data
+ * @offset: The offset in byte from which to start the parsing
+ *
+ * Parse the @ext Mpeg Video Picture Extension structure members from @data
+ *
+ * Returns: %TRUE if the picture extension could be parsed correctly,
+ * %FALSE otherwize.
+ */
+gboolean
+gst_mpeg_video_parse_picture_extension (GstMpegVideoPictureExt * ext,
+    const guint8 * data, gsize size, guint offset)
+{
+  GstBitReader br;
+
+  g_return_val_if_fail (ext != NULL, FALSE);
+
+  size -= offset;
+
+  if (size < 4)
+    return FALSE;
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  if (gst_bit_reader_get_bits_uint8_unchecked (&br, 4) !=
+      GST_MPEG_VIDEO_PACKET_EXT_PICTURE) {
+    GST_DEBUG ("Not parsing a picture extension");
+    return FALSE;
+  }
+
+  /* f_code */
+  READ_UINT8 (&br, ext->f_code[0][0], 4);
+  READ_UINT8 (&br, ext->f_code[0][1], 4);
+  READ_UINT8 (&br, ext->f_code[1][0], 4);
+  READ_UINT8 (&br, ext->f_code[1][1], 4);
+
+  /* intra DC precision */
+  READ_UINT8 (&br, ext->intra_dc_precision, 2);
+
+  /* picture structure */
+  READ_UINT8 (&br, ext->picture_structure, 2);
+
+  /* top field first */
+  READ_UINT8 (&br, ext->top_field_first, 1);
+
+  /* frame pred frame dct */
+  READ_UINT8 (&br, ext->frame_pred_frame_dct, 1);
+
+  /* concealment motion vectors */
+  READ_UINT8 (&br, ext->concealment_motion_vectors, 1);
+
+  /* q scale type */
+  READ_UINT8 (&br, ext->q_scale_type, 1);
+
+  /* intra vlc format */
+  READ_UINT8 (&br, ext->intra_vlc_format, 1);
+
+  /* alternate scan */
+  READ_UINT8 (&br, ext->alternate_scan, 1);
+
+  /* repeat first field */
+  READ_UINT8 (&br, ext->repeat_first_field, 1);
+
+  /* chroma_420_type */
+  READ_UINT8 (&br, ext->chroma_420_type, 1);
+
+  /* progressive_frame */
+  READ_UINT8 (&br, ext->progressive_frame, 1);
+
+  /* composite display */
+  READ_UINT8 (&br, ext->composite_display, 1);
+
+  if (ext->composite_display) {
+
+    /* v axis */
+    READ_UINT8 (&br, ext->v_axis, 1);
+
+    /* field sequence */
+    READ_UINT8 (&br, ext->field_sequence, 3);
+
+    /* sub carrier */
+    READ_UINT8 (&br, ext->sub_carrier, 1);
+
+    /* burst amplitude */
+    READ_UINT8 (&br, ext->burst_amplitude, 7);
+
+    /* sub_carrier phase */
+    READ_UINT8 (&br, ext->sub_carrier_phase, 8);
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("error parsing \"Picture Coding Extension\"");
+  return FALSE;
+
+}
+
+/**
+ * gst_mpeg_video_parse_picture_header:
+ * @hdr: (out): The #GstMpegVideoPictureHdr structure to fill
+ * @data: The data from which to parse the picture header
+ * @size: The size of @data
+ * @offset: The offset in byte from which to start the parsing
+ *
+ * Parsers the @hdr Mpeg Video Picture Header structure members from @data
+ *
+ * Returns: %TRUE if the picture sequence could be parsed correctly, %FALSE
+ * otherwize.
+ */
+gboolean
+gst_mpeg_video_parse_picture_header (GstMpegVideoPictureHdr * hdr,
+    const guint8 * data, gsize size, guint offset)
+{
+  GstBitReader br;
+
+  size = size - offset;
+
+  if (size < 4)
+    goto failed;
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  /* temperal sequence number */
+  if (!gst_bit_reader_get_bits_uint16 (&br, &hdr->tsn, 10))
+    goto failed;
+
+
+  /* frame type */
+  if (!gst_bit_reader_get_bits_uint8 (&br, (guint8 *) & hdr->pic_type, 3))
+    goto failed;
+
+
+  if (hdr->pic_type == 0 || hdr->pic_type > 4)
+    goto failed;                /* Corrupted picture packet */
+
+  /* skip VBV delay */
+  if (!gst_bit_reader_skip (&br, 16))
+    goto failed;
+
+  if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_P
+      || hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
+
+    READ_UINT8 (&br, hdr->full_pel_forward_vector, 1);
+
+    READ_UINT8 (&br, hdr->f_code[0][0], 3);
+    hdr->f_code[0][1] = hdr->f_code[0][0];
+  } else {
+    hdr->full_pel_forward_vector = 0;
+    hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
+  }
+
+  if (hdr->pic_type == GST_MPEG_VIDEO_PICTURE_TYPE_B) {
+    READ_UINT8 (&br, hdr->full_pel_backward_vector, 1);
+
+    READ_UINT8 (&br, hdr->f_code[1][0], 3);
+    hdr->f_code[1][1] = hdr->f_code[1][0];
+  } else {
+    hdr->full_pel_backward_vector = 0;
+    hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
+  }
+
+  return TRUE;
+
+failed:
+  {
+    GST_WARNING ("Failed to parse picture header");
+    return FALSE;
+  }
+}
+
+/**
+ * gst_mpeg_video_parse_gop:
+ * @gop: (out): The #GstMpegVideoGop structure to fill
+ * @data: The data from which to parse the gop
+ * @size: The size of @data
+ * @offset: The offset in byte from which to start the parsing
+ *
+ * Parses the @gop Mpeg Video Group of Picture structure members from @data
+ *
+ * Returns: %TRUE if the gop could be parsed correctly, %FALSE otherwize.
+ */
+gboolean
+gst_mpeg_video_parse_gop (GstMpegVideoGop * gop, const guint8 * data,
+    gsize size, guint offset)
+{
+  GstBitReader br;
+
+  g_return_val_if_fail (gop != NULL, FALSE);
+
+  size -= offset;
+
+  if (size < 4)
+    return FALSE;
+
+  gst_bit_reader_init (&br, &data[offset], size);
+
+  READ_UINT8 (&br, gop->drop_frame_flag, 1);
+
+  READ_UINT8 (&br, gop->hour, 5);
+
+  READ_UINT8 (&br, gop->minute, 6);
+
+  /* skip unused bit */
+  if (!gst_bit_reader_skip (&br, 1))
+    return FALSE;
+
+  READ_UINT8 (&br, gop->second, 6);
+
+  READ_UINT8 (&br, gop->frame, 6);
+
+  READ_UINT8 (&br, gop->closed_gop, 1);
+
+  READ_UINT8 (&br, gop->broken_link, 1);
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("error parsing \"GOP\"");
+  return FALSE;
+}
+
+/**
+ * gst_mpeg_video_zigzag_to_raster_quant_matrix:
+ * @out_quant: (out): The resulting quantization matrix
+ * @quant: The source quantization matrix
+ *
+ * Converts quantization matrix @quant from zigzag scan order to
+ * raster scan order and store the resulting factors into @out_quant.
+ *
+ * Note: it is an error to pass the same table in both @quant and
+ * @out_quant arguments.
+ *
+ * Since: 1.2
+ */
+void
+gst_mpeg_video_zigzag_to_raster_quant_matrix (guint8 out_quant[64],
+    const guint8 quant[64])
+{
+  guint i;
+
+  g_return_if_fail (out_quant != quant);
+
+  for (i = 0; i < 64; i++)
+    out_quant[mpeg_zigzag_8x8[i]] = quant[i];
+}
+
+/**
+ * gst_mpeg_video_raster_to_zigzag_quant_matrix:
+ * @out_quant: (out): The resulting quantization matrix
+ * @quant: The source quantization matrix
+ *
+ * Converts quantization matrix @quant from raster scan order to
+ * zigzag scan order and store the resulting factors into @out_quant.
+ *
+ * Note: it is an error to pass the same table in both @quant and
+ * @out_quant arguments.
+ *
+ * Since: 1.2
+ */
+void
+gst_mpeg_video_raster_to_zigzag_quant_matrix (guint8 out_quant[64],
+    const guint8 quant[64])
+{
+  guint i;
+
+  g_return_if_fail (out_quant != quant);
+
+  for (i = 0; i < 64; i++)
+    out_quant[i] = quant[mpeg_zigzag_8x8[i]];
+}
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstmpegvideoparser.h b/ext/codecparsers/gst-libs/gst/codecparsers/gstmpegvideoparser.h
new file mode 100644 (file)
index 0000000..4dc3256
--- /dev/null
@@ -0,0 +1,439 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * From bad/sys/vdpau/mpeg/mpegutil.c:
+ *   Copyright (C) <2007> Jan Schmidt <thaytan@mad.scientist.com>
+ *   Copyright (C) <2009> Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_MPEG_VIDEO_UTILS_H__
+#define __GST_MPEG_VIDEO_UTILS_H__
+
+#ifndef GST_USE_UNSTABLE_API
+#warning "The Mpeg video 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
+
+/**
+ * GstMpegVideoPacketTypeCode:
+ * @GST_MPEG_VIDEO_PACKET_PICTURE: Picture packet starting code
+ * @GST_MPEG_VIDEO_PACKET_SLICE_MIN: Slice min packet starting code
+ * @GST_MPEG_VIDEO_PACKET_SLICE_MAX: Slice max packet starting code
+ * @GST_MPEG_VIDEO_PACKET_USER_DATA: User data packet starting code
+ * @GST_MPEG_VIDEO_PACKET_SEQUENCE : Sequence packet starting code
+ * @GST_MPEG_VIDEO_PACKET_EXTENSION: Extension packet starting code
+ * @GST_MPEG_VIDEO_PACKET_SEQUENCE_END: Sequence end packet code
+ * @GST_MPEG_VIDEO_PACKET_GOP: Group of Picture packet starting code
+ * @GST_MPEG_VIDEO_PACKET_NONE: None packet code
+ *
+ * Indicates the type of MPEG packet
+ */
+typedef enum {
+  GST_MPEG_VIDEO_PACKET_PICTURE      = 0x00,
+  GST_MPEG_VIDEO_PACKET_SLICE_MIN    = 0x01,
+  GST_MPEG_VIDEO_PACKET_SLICE_MAX    = 0xaf,
+  GST_MPEG_VIDEO_PACKET_USER_DATA    = 0xb2,
+  GST_MPEG_VIDEO_PACKET_SEQUENCE     = 0xb3,
+  GST_MPEG_VIDEO_PACKET_EXTENSION    = 0xb5,
+  GST_MPEG_VIDEO_PACKET_SEQUENCE_END = 0xb7,
+  GST_MPEG_VIDEO_PACKET_GOP          = 0xb8,
+  GST_MPEG_VIDEO_PACKET_NONE         = 0xff
+} GstMpegVideoPacketTypeCode;
+
+/**
+ * GST_MPEG_VIDEO_PACKET_IS_SLICE:
+ * @typecode: The MPEG video packet type code
+ *
+ * Checks whether a packet type code is a slice.
+ *
+ * Returns: %TRUE if the packet type code corresponds to a slice,
+ * else %FALSE.
+ */
+#define GST_MPEG_VIDEO_PACKET_IS_SLICE(typecode) ((typecode) >= GST_MPEG_VIDEO_PACKET_SLICE_MIN && \
+                                                 (typecode) <= GST_MPEG_VIDEO_PACKET_SLICE_MAX)
+
+/**
+ * GstMpegVideoPacketExtensionCode:
+ * @GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE: Sequence extension code
+ * @GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY: Sequence Display extension code
+ * @GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX: Quantization Matrix extension code
+ * @GST_MPEG_VIDEO_PACKET_EXT_PICTURE: Picture coding extension
+ *
+ * Indicates what type of packets are in this block, some are mutually
+ * exclusive though - ie, sequence packs are accumulated separately. GOP &
+ * Picture may occur together or separately.
+ */
+typedef enum {
+  GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE         = 0x01,
+  GST_MPEG_VIDEO_PACKET_EXT_SEQUENCE_DISPLAY = 0x02,
+  GST_MPEG_VIDEO_PACKET_EXT_QUANT_MATRIX     = 0x03,
+  GST_MPEG_VIDEO_PACKET_EXT_PICTURE          = 0x08
+} GstMpegVideoPacketExtensionCode;
+
+/**
+ * GstMpegVideoLevel:
+ * @GST_MPEG_VIDEO_LEVEL_LOW: Low level (LL)
+ * @GST_MPEG_VIDEO_LEVEL_MAIN: Main level (ML)
+ * @GST_MPEG_VIDEO_LEVEL_HIGH_1440: High 1440 level (H-14)
+ * @GST_MPEG_VIDEO_LEVEL_HIGH: High level (HL)
+ *
+ * Mpeg-2 Levels.
+ **/
+typedef enum {
+ GST_MPEG_VIDEO_LEVEL_HIGH      = 0x04,
+ GST_MPEG_VIDEO_LEVEL_HIGH_1440 = 0x06,
+ GST_MPEG_VIDEO_LEVEL_MAIN      = 0x08,
+ GST_MPEG_VIDEO_LEVEL_LOW       = 0x0a
+} GstMpegVideoLevel;
+
+/**
+ * GstMpegVideoProfile:
+ * @GST_MPEG_VIDEO_PROFILE_422: 4:2:2 profile (422)
+ * @GST_MPEG_VIDEO_PROFILE_HIGH: High profile (HP)
+ * @GST_MPEG_VIDEO_PROFILE_SPATIALLY_SCALABLE: Spatially Scalable profile (Spatial)
+ * @GST_MPEG_VIDEO_PROFILE_SNR_SCALABLE: SNR Scalable profile (SNR)
+ * @GST_MPEG_VIDEO_PROFILE_MAIN: Main profile (MP)
+ * @GST_MPEG_VIDEO_PROFILE_SIMPLE: Simple profile (SP)
+ *
+ * Mpeg-2 Profiles.
+ **/
+typedef enum {
+  GST_MPEG_VIDEO_PROFILE_422                 = 0x00,
+  GST_MPEG_VIDEO_PROFILE_HIGH                = 0x01,
+  GST_MPEG_VIDEO_PROFILE_SPATIALLY_SCALABLE  = 0x02,
+  GST_MPEG_VIDEO_PROFILE_SNR_SCALABLE        = 0x03,
+  GST_MPEG_VIDEO_PROFILE_MAIN                = 0x04,
+  GST_MPEG_VIDEO_PROFILE_SIMPLE              = 0x05
+} GstMpegVideoProfile;
+
+/**
+ * GstMpegVideoChromaFormat:
+ * @GST_MPEG_VIDEO_CHROMA_RES: Invalid (reserved for future use)
+ * @GST_MPEG_VIDEO_CHROMA_420: 4:2:0 subsampling
+ * @GST_MPEG_VIDEO_CHROMA_422: 4:2:2 subsampling
+ * @GST_MPEG_VIDEO_CHROMA_444: 4:4:4 (non-subsampled)
+ *
+ * Chroma subsampling type.
+ */
+typedef enum {
+  GST_MPEG_VIDEO_CHROMA_RES = 0x00,
+  GST_MPEG_VIDEO_CHROMA_420 = 0x01,
+  GST_MPEG_VIDEO_CHROMA_422 = 0x02,
+  GST_MPEG_VIDEO_CHROMA_444 = 0x03,
+} GstMpegVideoChromaFormat;
+
+/**
+ * GstMpegVideoPictureType:
+ * @GST_MPEG_VIDEO_PICTURE_TYPE_I: Intra-coded (I) frame
+ * @GST_MPEG_VIDEO_PICTURE_TYPE_P: Predictive-codec (P) frame
+ * @GST_MPEG_VIDEO_PICTURE_TYPE_B: Bidirectionally predictive-coded (B) frame
+ * @GST_MPEG_VIDEO_PICTURE_TYPE_D: D frame
+ *
+ * Picture type.
+ */
+typedef enum {
+  GST_MPEG_VIDEO_PICTURE_TYPE_I = 0x01,
+  GST_MPEG_VIDEO_PICTURE_TYPE_P = 0x02,
+  GST_MPEG_VIDEO_PICTURE_TYPE_B = 0x03,
+  GST_MPEG_VIDEO_PICTURE_TYPE_D = 0x04
+} GstMpegVideoPictureType;
+
+/**
+ * GstMpegVideoPictureStructure:
+ * @GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD: Top field
+ * @GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD: Bottom field
+ * @GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME: Frame picture
+ *
+ * Picture structure type.
+ */
+typedef enum {
+    GST_MPEG_VIDEO_PICTURE_STRUCTURE_TOP_FIELD    = 0x01,
+    GST_MPEG_VIDEO_PICTURE_STRUCTURE_BOTTOM_FIELD = 0x02,
+    GST_MPEG_VIDEO_PICTURE_STRUCTURE_FRAME        = 0x03
+} GstMpegVideoPictureStructure;
+
+typedef struct _GstMpegVideoSequenceHdr     GstMpegVideoSequenceHdr;
+typedef struct _GstMpegVideoSequenceExt     GstMpegVideoSequenceExt;
+typedef struct _GstMpegVideoSequenceDisplayExt GstMpegVideoSequenceDisplayExt;
+typedef struct _GstMpegVideoPictureHdr      GstMpegVideoPictureHdr;
+typedef struct _GstMpegVideoGop             GstMpegVideoGop;
+typedef struct _GstMpegVideoPictureExt      GstMpegVideoPictureExt;
+typedef struct _GstMpegVideoQuantMatrixExt  GstMpegVideoQuantMatrixExt;
+typedef struct _GstMpegVideoPacket          GstMpegVideoPacket;
+
+/**
+ * GstMpegVideoSequenceHdr:
+ * @width: Width of each frame
+ * @height: Height of each frame
+ * @par_w: Calculated Pixel Aspect Ratio width
+ * @par_h: Calculated Pixel Aspect Ratio height
+ * @fps_n: Calculated Framrate nominator
+ * @fps_d: Calculated Framerate denominator
+ * @bitrate_value: Value of the bitrate as is in the stream (400bps unit)
+ * @bitrate: the real bitrate of the Mpeg video stream in bits per second, 0 if VBR stream
+ * @constrained_parameters_flag: %TRUE if this stream uses contrained parameters.
+ * @intra_quantizer_matrix: intra-quantization table, in zigzag scan order
+ * @non_intra_quantizer_matrix: non-intra quantization table, in zigzag scan order
+ *
+ * The Mpeg2 Video Sequence Header structure.
+ */
+struct _GstMpegVideoSequenceHdr
+{
+  guint16 width, height;
+  guint8  aspect_ratio_info;
+  guint8  frame_rate_code;
+  guint32 bitrate_value;
+  guint16 vbv_buffer_size_value;
+
+  guint8  constrained_parameters_flag;
+
+  guint8  intra_quantizer_matrix[64];
+  guint8  non_intra_quantizer_matrix[64];
+
+  /* Calculated values */
+  guint   par_w, par_h;
+  guint   fps_n, fps_d;
+  guint   bitrate;
+};
+
+/**
+ * GstMpegVideoSequenceExt:
+ * @profile: mpeg2 decoder profile
+ * @level: mpeg2 decoder level
+ * @progressive: %TRUE if the frames are progressive %FALSE otherwise
+ * @chroma_format: indicates the chrominance format
+ * @horiz_size_ext: Horizontal size
+ * @vert_size_ext: Vertical size
+ * @bitrate_ext: The bitrate
+ * @vbv_buffer_size_extension: VBV vuffer size
+ * @low_delay: %TRUE if the sequence doesn't contain any B-pictures, %FALSE
+ * otherwise
+ * @fps_n_ext: Framerate nominator code
+ * @fps_d_ext: Framerate denominator code
+ *
+ * The Mpeg2 Video Sequence Extension structure.
+ **/
+struct _GstMpegVideoSequenceExt
+{
+  /* mpeg2 decoder profile */
+  guint8 profile;
+  /* mpeg2 decoder level */
+  guint8 level;
+
+  guint8 progressive;
+  guint8 chroma_format;
+
+  guint8 horiz_size_ext, vert_size_ext;
+
+  guint16 bitrate_ext;
+  guint8 vbv_buffer_size_extension;
+  guint8 low_delay;
+  guint8 fps_n_ext, fps_d_ext;
+
+};
+
+/**
+ * GstMpegVideoSequenceDisplayExt:
+ * @profile: mpeg2 decoder profil
+
+ */
+struct _GstMpegVideoSequenceDisplayExt
+{
+  guint8 video_format;
+  guint8 colour_description_flag;
+
+  /* if colour_description_flag: */
+    guint8 colour_primaries;
+    guint8 transfer_characteristics;
+    guint8 matrix_coefficients;
+
+  guint16 display_horizontal_size;
+  guint16 display_vertical_size;
+};
+
+/**
+ * GstMpegVideoQuantMatrixExt:
+ * @load_intra_quantiser_matrix:
+ * @intra_quantiser_matrix:
+ * @load_non_intra_quantiser_matrix:
+ * @non_intra_quantiser_matrix:
+ * @load_chroma_intra_quantiser_matrix:
+ * @chroma_intra_quantiser_matrix:
+ * @load_chroma_non_intra_quantiser_matrix:
+ * @chroma_non_intra_quantiser_matrix:
+ *
+ * The Quant Matrix Extension structure that exposes quantization
+ * matrices in zigzag scan order. i.e. the original encoded scan
+ * order.
+ */
+struct _GstMpegVideoQuantMatrixExt
+{
+ guint8 load_intra_quantiser_matrix;
+ guint8 intra_quantiser_matrix[64];
+ guint8 load_non_intra_quantiser_matrix;
+ guint8 non_intra_quantiser_matrix[64];
+ guint8 load_chroma_intra_quantiser_matrix;
+ guint8 chroma_intra_quantiser_matrix[64];
+ guint8 load_chroma_non_intra_quantiser_matrix;
+ guint8 chroma_non_intra_quantiser_matrix[64];
+};
+
+/**
+ * GstMpegVideoPictureHdr:
+ * @tsn: Temporal Sequence Number
+ * @pic_type: Type of the frame
+ * @full_pel_forward_vector: the full pel forward flag of
+ *  the frame: 0 or 1.
+ * @full_pel_backward_vector: the full pel backward flag
+ *  of the frame: 0 or 1.
+ * @f_code: F code
+ *
+ * The Mpeg2 Video Picture Header structure.
+ */
+struct _GstMpegVideoPictureHdr
+{
+  guint16 tsn;
+  guint8 pic_type;
+
+  guint8 full_pel_forward_vector, full_pel_backward_vector;
+
+  guint8 f_code[2][2];
+};
+
+/**
+ * GstMpegVideoPictureExt:
+ * @intra_dc_precision: Intra DC precision
+ * @picture_structure: Structure of the picture
+ * @top_field_first: Top field first
+ * @frame_pred_frame_dct: Frame
+ * @concealment_motion_vectors: Concealment Motion Vectors
+ * @q_scale_type: Q Scale Type
+ * @intra_vlc_format: Intra Vlc Format
+ * @alternate_scan: Alternate Scan
+ * @repeat_first_field: Repeat First Field
+ * @chroma_420_type: Chroma 420 Type
+ * @progressive_frame: %TRUE if the frame is progressive %FALSE otherwize
+ *
+ * The Mpeg2 Video Picture Extension structure.
+ */
+struct _GstMpegVideoPictureExt
+{
+  guint8 f_code[2][2];
+
+  guint8 intra_dc_precision;
+  guint8 picture_structure;
+  guint8 top_field_first;
+  guint8 frame_pred_frame_dct;
+  guint8 concealment_motion_vectors;
+  guint8 q_scale_type;
+  guint8 intra_vlc_format;
+  guint8 alternate_scan;
+  guint8 repeat_first_field;
+  guint8 chroma_420_type;
+  guint8 progressive_frame;
+  guint8 composite_display;
+  guint8 v_axis;
+  guint8 field_sequence;
+  guint8 sub_carrier;
+  guint8 burst_amplitude;
+  guint8 sub_carrier_phase;
+};
+
+/**
+ * GstMpegVideoGop:
+ * @drop_frame_flag: Drop Frame Flag
+ * @hour: Hour (0-23)
+ * @minute: Minute (O-59)
+ * @second: Second (0-59)
+ * @frame: Frame (0-59)
+ * @closed_gop: Closed Gop
+ * @broken_link: Broken link
+ *
+ * The Mpeg Video Group of Picture structure.
+ */
+struct _GstMpegVideoGop
+{
+  guint8 drop_frame_flag;
+
+  guint8 hour, minute, second, frame;
+
+  guint8 closed_gop;
+  guint8 broken_link;
+};
+
+/**
+ * GstMpegVideoTypeOffsetSize:
+ *
+ * @type: the type of the packet that start at @offset
+ * @data: the data containing the packet starting at @offset
+ * @offset: the offset of the packet start in bytes, it is the exact, start of the packet, no sync code included
+ * @size: The size in bytes of the packet or -1 if the end wasn't found. It is the exact size of the packet, no sync code included
+ *
+ * A structure that contains the type of a packet, its offset and its size
+ */
+struct _GstMpegVideoPacket
+{
+  const guint8 *data;
+  guint8 type;
+  guint  offset;
+  gint   size;
+};
+
+gboolean gst_mpeg_video_parse                         (GstMpegVideoPacket * packet,
+                                                       const guint8 * data, gsize size, guint offset);
+
+gboolean gst_mpeg_video_parse_sequence_header         (GstMpegVideoSequenceHdr * params,
+                                                       const guint8 * data, gsize size, guint offset);
+
+/* seqext and displayext may be NULL if not received */
+gboolean gst_mpeg_video_finalise_mpeg2_sequence_header (GstMpegVideoSequenceHdr *hdr,
+   GstMpegVideoSequenceExt *seqext, GstMpegVideoSequenceDisplayExt *displayext);
+
+gboolean gst_mpeg_video_parse_picture_header          (GstMpegVideoPictureHdr* hdr,
+                                                       const guint8 * data, gsize size, guint offset);
+
+gboolean gst_mpeg_video_parse_picture_extension       (GstMpegVideoPictureExt *ext,
+                                                       const guint8 * data, gsize size, guint offset);
+
+gboolean gst_mpeg_video_parse_gop                     (GstMpegVideoGop * gop,
+                                                       const guint8 * data, gsize size, guint offset);
+
+gboolean gst_mpeg_video_parse_sequence_extension      (GstMpegVideoSequenceExt * seqext,
+                                                       const guint8 * data, gsize size, guint offset);
+
+gboolean gst_mpeg_video_parse_sequence_display_extension (GstMpegVideoSequenceDisplayExt * seqdisplayext,
+                                                       const guint8 * data, gsize size, guint offset);
+
+gboolean gst_mpeg_video_parse_quant_matrix_extension  (GstMpegVideoQuantMatrixExt * quant,
+                                                       const guint8 * data, gsize size, guint offset);
+
+void     gst_mpeg_video_zigzag_to_raster_quant_matrix (guint8 out_quant[64],
+                                                       const guint8 quant[64]);
+
+void     gst_mpeg_video_raster_to_zigzag_quant_matrix (guint8 out_quant[64],
+                                                       const guint8 quant[64]);
+
+G_END_DECLS
+
+#endif
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstvc1parser.c b/ext/codecparsers/gst-libs/gst/codecparsers/gstvc1parser.c
new file mode 100644 (file)
index 0000000..a7ab430
--- /dev/null
@@ -0,0 +1,2192 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+/**
+ * SECTION:gstvc1parser
+ * @short_description: Convenience library for parsing vc1 video
+ * bitstream.
+ *
+ * For more details about the structures, look at the
+ * smpte specifications (S421m-2006.pdf).
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include "config.h"
+#endif
+
+#include "gstvc1parser.h"
+#include "parserutils.h"
+#include <gst/base/gstbytereader.h>
+#include <gst/base/gstbitreader.h>
+#include <string.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_vc1", 0,
+        "VC1 codec parsing library");
+
+    g_once_init_leave (&cat_gonce, cat_done);
+  }
+
+  return (GstDebugCategory *) cat_gonce;
+}
+
+#else
+
+#define ensure_debug_category() /* NOOP */
+
+#endif /* GST_DISABLE_GST_DEBUG */
+
+static const guint8 vc1_pquant_table[3][32] = {
+  {                             /* Implicit quantizer */
+        0, 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12,
+      13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 29, 31},
+  {                             /* Explicit quantizer, pquantizer uniform */
+        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+      16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31},
+  {                             /* Explicit quantizer, pquantizer non-uniform */
+        0, 1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
+      14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 29, 31}
+};
+
+static const guint8 vc1_mvmode_table[2][5] = {
+  /* Table 47: P Picture High rate (PQUANT <= 12) MVMODE code table */
+  {
+        GST_VC1_MVMODE_1MV,
+        GST_VC1_MVMODE_MIXED_MV,
+        GST_VC1_MVMODE_1MV_HPEL,
+        GST_VC1_MVMODE_INTENSITY_COMP,
+      GST_VC1_MVMODE_1MV_HPEL_BILINEAR},
+  /* Table 46: P Picture Low rate (PQUANT > 12) MVMODE code table */
+  {
+        GST_VC1_MVMODE_1MV_HPEL_BILINEAR,
+        GST_VC1_MVMODE_1MV,
+        GST_VC1_MVMODE_1MV_HPEL,
+        GST_VC1_MVMODE_INTENSITY_COMP,
+      GST_VC1_MVMODE_MIXED_MV}
+};
+
+static const guint8 vc1_mvmode2_table[2][4] = {
+  /* Table 50: P Picture High rate (PQUANT <= 12) MVMODE2 code table */
+  {
+        GST_VC1_MVMODE_1MV,
+        GST_VC1_MVMODE_MIXED_MV,
+        GST_VC1_MVMODE_1MV_HPEL,
+      GST_VC1_MVMODE_1MV_HPEL_BILINEAR},
+  /* Table 49: P Picture Low rate (PQUANT > 12) MVMODE2 code table */
+  {
+        GST_VC1_MVMODE_1MV_HPEL_BILINEAR,
+        GST_VC1_MVMODE_1MV,
+        GST_VC1_MVMODE_1MV_HPEL,
+      GST_VC1_MVMODE_MIXED_MV}
+};
+
+/* Table 40: BFRACTION VLC Table */
+static const VLCTable vc1_bfraction_vlc_table[] = {
+  {GST_VC1_BFRACTION_BASIS / 2, 0x00, 3},
+  {GST_VC1_BFRACTION_BASIS / 3, 0x01, 3},
+  {(GST_VC1_BFRACTION_BASIS * 2) / 3, 0x02, 3},
+  {GST_VC1_BFRACTION_BASIS / 4, 0x02, 3},
+  {(GST_VC1_BFRACTION_BASIS * 3) / 4, 0x04, 3},
+  {GST_VC1_BFRACTION_BASIS / 5, 0x05, 3},
+  {(GST_VC1_BFRACTION_BASIS * 2) / 5, 0x06, 3},
+  {(GST_VC1_BFRACTION_BASIS * 3) / 5, 0x70, 7},
+  {(GST_VC1_BFRACTION_BASIS * 4) / 5, 0x71, 7},
+  {GST_VC1_BFRACTION_BASIS / 6, 0x72, 7},
+  {(GST_VC1_BFRACTION_BASIS * 5) / 6, 0x73, 7},
+  {GST_VC1_BFRACTION_BASIS / 7, 0x74, 7},
+  {(GST_VC1_BFRACTION_BASIS * 2) / 7, 0x75, 7},
+  {(GST_VC1_BFRACTION_BASIS * 3) / 7, 0x76, 7},
+  {(GST_VC1_BFRACTION_BASIS * 4) / 7, 0x77, 7},
+  {(GST_VC1_BFRACTION_BASIS * 5) / 7, 0x78, 7},
+  {(GST_VC1_BFRACTION_BASIS * 6) / 7, 0x79, 7},
+  {GST_VC1_BFRACTION_BASIS / 8, 0x7a, 7},
+  {(GST_VC1_BFRACTION_BASIS * 3) / 8, 0x7b, 7},
+  {(GST_VC1_BFRACTION_BASIS * 5) / 8, 0x7c, 7},
+  {(GST_VC1_BFRACTION_BASIS * 7) / 8, 0x7d, 7},
+  {GST_VC1_BFRACTION_RESERVED, 0x7e, 7},
+  {GST_VC1_BFRACTION_PTYPE_BI, 0x7f, 7}
+};
+
+/* Imode types */
+enum
+{
+  IMODE_RAW,
+  IMODE_NORM2,
+  IMODE_DIFF2,
+  IMODE_NORM6,
+  IMODE_DIFF6,
+  IMODE_ROWSKIP,
+  IMODE_COLSKIP
+};
+
+/* Table 69: IMODE VLC Codetable */
+static const VLCTable vc1_imode_vlc_table[] = {
+  {IMODE_NORM2, 0x02, 2},
+  {IMODE_NORM6, 0x03, 2},
+  {IMODE_ROWSKIP, 0x02, 3},
+  {IMODE_COLSKIP, 0x03, 3},
+  {IMODE_DIFF2, 0x01, 3},
+  {IMODE_DIFF6, 0x01, 4},
+  {IMODE_RAW, 0x00, 4}
+};
+
+/* Table 80: Norm-2/Diff-2 Code Table */
+static const VLCTable vc1_norm2_vlc_table[4] = {
+  {0, 0, 1},
+  {2, 4, 3},
+  {1, 5, 3},
+  {3, 3, 2}
+};
+
+/* Table 81: Code table for 3x2 and 2x3 tiles */
+static const VLCTable vc1_norm6_vlc_table[64] = {
+  {0, 1, 1},
+  {1, 2, 4},
+  {2, 3, 4},
+  {3, 0, 8},
+  {4, 4, 4},
+  {5, 1, 8},
+  {6, 2, 8},
+  {7, (2 << 5) | 7, 10},
+  {8, 5, 4},
+  {9, 3, 8},
+  {10, 4, 8},
+  {11, (2 << 5) | 11, 10},
+  {12, 5, 8},
+  {13, (2 << 5) | 13, 10},
+  {14, (2 << 5) | 14, 10},
+  {15, (3 << 8) | 14, 13},
+  {16, 6, 4},
+  {17, 6, 8},
+  {18, 7, 8},
+  {19, (2 << 5) | 19, 10},
+  {20, 8, 8},
+  {21, (2 << 5) | 21, 10},
+  {22, (2 << 5) | 22, 10},
+  {23, (3 << 8) | 13, 13},
+  {24, 9, 8},
+  {25, (2 << 5) | 25, 10},
+  {26, (2 << 5) | 26, 10},
+  {27, (3 << 8) | 12, 13},
+  {28, (2 << 5) | 28, 10},
+  {29, (3 << 8) | 11, 13},
+  {30, (3 << 8) | 10, 13},
+  {31, (3 << 4) | 7, 9},
+  {32, 7, 4},
+  {33, 10, 8},
+  {34, 11, 8},
+  {35, (2 << 5) | 3, 10},
+  {36, 12, 8},
+  {37, (2 << 5) | 5, 10},
+  {38, (2 << 5) | 6, 10},
+  {39, (3 << 8) | 9, 13},
+  {40, 13, 8},
+  {41, (2 << 5) | 9, 10},
+  {42, (2 << 5) | 10, 10},
+  {43, (3 << 8) | 8, 13},
+  {44, (2 << 5) | 12, 10},
+  {45, (3 << 8) | 7, 13},
+  {46, (3 << 8) | 6, 13},
+  {47, (3 << 4) | 6, 9},
+  {48, 14, 8},
+  {49, (2 << 5) | 17, 10},
+  {50, (2 << 5) | 18, 10},
+  {51, (3 << 8) | 5, 13},
+  {52, (2 << 5) | 20, 10},
+  {53, (3 << 8) | 4, 13},
+  {54, (3 << 8) | 3, 13},
+  {55, (3 << 4) | 5, 9},
+  {56, (2 << 5) | 24, 10},
+  {57, (3 << 8) | 2, 13},
+  {58, (3 << 8) | 1, 13},
+  {59, (3 << 4) | 4, 9},
+  {60, (3 << 8) | 0, 13},
+  {61, (3 << 4) | 3, 9},
+  {62, (3 << 4) | 2, 9},
+  {63, (3 << 1) | 1, 6}
+};
+
+/* SMPTE 421M Table 7 */
+typedef struct
+{
+  gint par_n, par_d;
+} PAR;
+
+static PAR aspect_ratios[] = {
+  {0, 0},
+  {1, 1},
+  {12, 11},
+  {10, 11},
+  {16, 11},
+  {40, 33},
+  {24, 11},
+  {20, 11},
+  {32, 11},
+  {80, 33},
+  {18, 11},
+  {15, 11},
+  {64, 33},
+  {160, 99},
+  {0, 0},
+  {0, 0}
+};
+
+/* SMPTE 421M Table 8 */
+static const guint framerates_n[] = {
+  0,
+  24 * 1000,
+  25 * 1000,
+  30 * 1000,
+  50 * 1000,
+  60 * 1000,
+  48 * 1000,
+  72 * 1000
+};
+
+/* SMPTE 421M Table 9 */
+static const guint framerates_d[] = {
+  0,
+  1000,
+  1001
+};
+
+
+static inline gboolean
+decode_colskip (GstBitReader * br, guint8 * data, guint width, guint height,
+    guint stride, guint invert)
+{
+  guint x, y;
+  guint8 colskip, v;
+
+  GST_DEBUG ("Parsing colskip");
+
+  invert &= 1;
+  for (x = 0; x < width; x++) {
+    READ_UINT8 (br, colskip, 1);
+
+    if (data) {
+      if (colskip) {
+        for (y = 0; y < height; y++) {
+          READ_UINT8 (br, v, 1);
+          data[y * stride] = v ^ invert;
+        }
+      } else {
+        for (y = 0; y < height; y++)
+          data[y * stride] = invert;
+      }
+      data++;
+    } else if (colskip)
+      SKIP (br, height);
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("Failed to parse colskip");
+
+  return FALSE;
+}
+
+static inline gboolean
+decode_rowskip (GstBitReader * br, guint8 * data, guint width, guint height,
+    guint stride, guint invert)
+{
+  guint x, y;
+  guint8 rowskip, v;
+
+  GST_DEBUG ("Parsing rowskip");
+
+  invert &= 1;
+  for (y = 0; y < height; y++) {
+    READ_UINT8 (br, rowskip, 1);
+
+    if (data) {
+      if (!rowskip)
+        memset (data, invert, width);
+      else {
+        for (x = 0; x < width; x++) {
+          READ_UINT8 (br, v, 1);
+          data[x] = v ^ invert;
+        }
+      }
+      data += stride;
+    } else if (rowskip)
+      SKIP (br, width);
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("Failed to parse rowskip");
+
+  return FALSE;
+}
+
+static inline gint8
+decode012 (GstBitReader * br)
+{
+  guint8 n;
+
+  READ_UINT8 (br, n, 1);
+
+  if (n == 0)
+    return 0;
+
+  READ_UINT8 (br, n, 1);
+
+  return n + 1;
+
+failed:
+  GST_WARNING ("Could not decode 0 1 2 returning -1");
+
+  return -1;
+}
+
+static inline guint
+calculate_nb_pan_scan_win (GstVC1AdvancedSeqHdr * advseqhdr,
+    GstVC1PicAdvanced * pic)
+{
+  if (advseqhdr->interlace && !advseqhdr->psf) {
+    if (advseqhdr->pulldown)
+      return pic->rff + 2;
+
+    return 2;
+
+  } else {
+    if (advseqhdr->pulldown)
+      return pic->rptfrm + 1;
+
+    return 1;
+  }
+}
+
+static gboolean
+decode_refdist (GstBitReader * br, guint16 * value)
+{
+  guint16 tmp;
+  gint i = 2;
+
+  if (!gst_bit_reader_peek_bits_uint16 (br, &tmp, i))
+    goto failed;
+
+  if (tmp < 0x03) {
+    READ_UINT16 (br, *value, i);
+
+    return TRUE;
+  }
+
+  do {
+    i++;
+
+    if (!gst_bit_reader_peek_bits_uint16 (br, &tmp, i))
+      goto failed;
+
+    if (!(tmp >> i)) {
+      READ_UINT16 (br, *value, i);
+
+      return TRUE;
+    }
+  } while (i < 16);
+
+
+failed:
+  {
+    GST_WARNING ("Could not decode end 0 returning");
+
+    return FALSE;
+  }
+}
+
+/*** bitplanes decoding ***/
+static gboolean
+bitplane_decoding (GstBitReader * br, guint8 * data,
+    GstVC1SeqHdr * seqhdr, guint8 * is_raw)
+{
+  const guint width = seqhdr->mb_width;
+  const guint height = seqhdr->mb_height;
+  const guint stride = seqhdr->mb_stride;
+  guint imode, invert, invert_mask;
+  guint x, y, v, o;
+  guint8 *pdata = data;
+
+  *is_raw = FALSE;
+
+  GET_BITS (br, 1, &invert);
+  invert_mask = -invert;
+
+  if (!decode_vlc (br, &imode, vc1_imode_vlc_table,
+          G_N_ELEMENTS (vc1_imode_vlc_table)))
+    goto failed;
+
+  switch (imode) {
+    case IMODE_RAW:
+
+      GST_DEBUG ("Parsing IMODE_RAW");
+
+      *is_raw = TRUE;
+      return TRUE;
+
+    case IMODE_DIFF2:
+      invert_mask = 0;
+      /* fall-through */
+    case IMODE_NORM2:
+      invert_mask &= 3;
+
+      GST_DEBUG ("Parsing IMODE_DIFF2 or IMODE_NORM2 biplane");
+
+      x = 0;
+      o = (height * width) & 1;
+      if (o) {
+        GET_BITS (br, 1, &v);
+        if (pdata) {
+          *pdata++ = (v ^ invert_mask) & 1;
+          if (++x == width) {
+            x = 0;
+            pdata += stride - width;
+          }
+        }
+      }
+
+      for (y = o; y < height * width; y += 2) {
+        if (!decode_vlc (br, &v, vc1_norm2_vlc_table,
+                G_N_ELEMENTS (vc1_norm2_vlc_table)))
+          goto failed;
+        if (pdata) {
+          v ^= invert_mask;
+          *pdata++ = v >> 1;
+          if (++x == width) {
+            x = 0;
+            pdata += stride - width;
+          }
+          *pdata++ = v & 1;
+          if (++x == width) {
+            x = 0;
+            pdata += stride - width;
+          }
+        }
+      }
+      break;
+
+    case IMODE_DIFF6:
+      invert_mask = 0;
+      /* fall-through */
+    case IMODE_NORM6:
+
+      GST_DEBUG ("Parsing IMODE_DIFF6 or IMODE_NORM6 biplane");
+
+      if (!(height % 3) && (width % 3)) {       /* decode 2x3 "vertical" tiles */
+        for (y = 0; y < height; y += 3) {
+          for (x = width & 1; x < width; x += 2) {
+            if (!decode_vlc (br, &v, vc1_norm6_vlc_table,
+                    G_N_ELEMENTS (vc1_norm6_vlc_table)))
+              goto failed;
+
+            if (pdata) {
+              v ^= invert_mask;
+              pdata[x + 0] = v & 1;
+              pdata[x + 1] = (v >> 1) & 1;
+              pdata[x + 0 + stride] = (v >> 2) & 1;
+              pdata[x + 1 + stride] = (v >> 3) & 1;
+              pdata[x + 0 + stride * 2] = (v >> 4) & 1;
+              pdata[x + 1 + stride * 2] = (v >> 5) & 1;
+            }
+          }
+          if (pdata)
+            pdata += 3 * stride;
+        }
+
+        x = width & 1;
+        y = 0;
+      } else {                  /* decode 3x2 "horizontal" tiles */
+
+        if (pdata)
+          pdata += (height & 1) * stride;
+        for (y = height & 1; y < height; y += 2) {
+          for (x = width % 3; x < width; x += 3) {
+            if (!decode_vlc (br, &v, vc1_norm6_vlc_table,
+                    G_N_ELEMENTS (vc1_norm6_vlc_table)))
+              goto failed;
+
+            if (pdata) {
+              v ^= invert_mask;
+              pdata[x + 0] = v & 1;
+              pdata[x + 1] = (v >> 1) & 1;
+              pdata[x + 2] = (v >> 2) & 1;
+              pdata[x + 0 + stride] = (v >> 3) & 1;
+              pdata[x + 1 + stride] = (v >> 4) & 1;
+              pdata[x + 2 + stride] = (v >> 5) & 1;
+            }
+          }
+          if (pdata)
+            pdata += 2 * stride;
+        }
+
+        x = width % 3;
+        y = height & 1;
+      }
+
+      if (x) {
+        if (data)
+          pdata = data;
+        if (!decode_colskip (br, pdata, x, height, stride, invert_mask))
+          goto failed;
+      }
+
+      if (y) {
+        if (data)
+          pdata = data + x;
+        if (!decode_rowskip (br, pdata, width - x, y, stride, invert_mask))
+          goto failed;
+      }
+      break;
+    case IMODE_ROWSKIP:
+
+      GST_DEBUG ("Parsing IMODE_ROWSKIP biplane");
+
+      if (!decode_rowskip (br, data, width, height, stride, invert_mask))
+        goto failed;
+      break;
+    case IMODE_COLSKIP:
+
+      GST_DEBUG ("Parsing IMODE_COLSKIP biplane");
+
+      if (!decode_colskip (br, data, width, height, stride, invert_mask))
+        goto failed;
+      break;
+  }
+
+  if (!data)
+    return TRUE;
+
+  /* Applying diff operator */
+  if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6) {
+    pdata = data;
+    pdata[0] ^= invert;
+
+    for (x = 1; x < width; x++)
+      pdata[x] ^= pdata[x - 1];
+
+    for (y = 1; y < height; y++) {
+      pdata[stride] ^= pdata[0];
+
+      for (x = 1; x < width; x++) {
+        if (pdata[stride + x - 1] != pdata[x])
+          pdata[stride + x] ^= invert;
+        else
+          pdata[stride + x] ^= pdata[stride + x - 1];
+      }
+      pdata += stride;
+    }
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("Failed to decode bitplane");
+
+  return FALSE;
+}
+
+static gboolean
+parse_vopdquant (GstBitReader * br, GstVC1FrameHdr * framehdr, guint8 dquant)
+{
+  GstVC1VopDquant *vopdquant = &framehdr->vopdquant;
+
+  GST_DEBUG ("Parsing vopdquant");
+
+  vopdquant->dqbilevel = 0;
+
+  if (dquant == 2) {
+    vopdquant->dquantfrm = 0;
+
+    READ_UINT8 (br, vopdquant->pqdiff, 3);
+
+    if (vopdquant->pqdiff != 7)
+      vopdquant->altpquant = framehdr->pquant + vopdquant->pqdiff + 1;
+    else {
+      READ_UINT8 (br, vopdquant->abspq, 5);
+      vopdquant->altpquant = vopdquant->abspq;
+    }
+  } else {
+    READ_UINT8 (br, vopdquant->dquantfrm, 1);
+    GST_DEBUG (" %u DquantFrm %u", gst_bit_reader_get_pos (br),
+        vopdquant->dquantfrm);
+
+    if (vopdquant->dquantfrm) {
+      READ_UINT8 (br, vopdquant->dqprofile, 2);
+
+      switch (vopdquant->dqprofile) {
+        case GST_VC1_DQPROFILE_SINGLE_EDGE:
+        case GST_VC1_DQPROFILE_DOUBLE_EDGES:
+          READ_UINT8 (br, vopdquant->dqbedge, 2);
+          break;
+
+        case GST_VC1_DQPROFILE_ALL_MBS:
+          READ_UINT8 (br, vopdquant->dqbilevel, 1);
+          break;
+      }
+
+      if (vopdquant->dqbilevel
+          || vopdquant->dqprofile != GST_VC1_DQPROFILE_ALL_MBS) {
+        {
+          READ_UINT8 (br, vopdquant->pqdiff, 3);
+
+          if (vopdquant->pqdiff != 7)
+            vopdquant->altpquant = framehdr->pquant + vopdquant->pqdiff + 1;
+          else {
+            READ_UINT8 (br, vopdquant->abspq, 5);
+            vopdquant->altpquant = vopdquant->abspq;
+          }
+        }
+      }
+    }
+  }
+
+  return TRUE;
+
+failed:
+  GST_WARNING ("Failed to parse vopdquant");
+
+  return FALSE;
+}
+
+static inline gint
+scan_for_start_codes (const guint8 * data, guint size)
+{
+  GstByteReader br;
+  gst_byte_reader_init (&br, data, size);
+
+  /* NALU not empty, so we can at least expect 1 (even 2) bytes following sc */
+  return gst_byte_reader_masked_scan_uint32 (&br, 0xffffff00, 0x00000100,
+      0, size);
+}
+
+static inline gint
+get_unary (GstBitReader * br, gint stop, gint len)
+{
+  int i;
+  guint8 current = 0xff;
+
+  for (i = 0; i < len; i++) {
+    current = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+    if (current == stop)
+      return i;
+  }
+
+  return i;
+}
+
+static inline void
+calculate_framerate_bitrate (guint8 frmrtq_postproc, guint8 bitrtq_postproc,
+    guint * framerate, guint * bitrate)
+{
+  if (frmrtq_postproc == 0 && bitrtq_postproc == 31) {
+    *framerate = 0;
+    *bitrate = 0;
+  } else if (frmrtq_postproc == 0 && bitrtq_postproc == 30) {
+    *framerate = 2;
+    *bitrate = 1952;
+  } else if (frmrtq_postproc == 1 && bitrtq_postproc == 31) {
+    *framerate = 6;
+    *bitrate = 2016;
+  } else {
+    if (frmrtq_postproc == 7) {
+      *framerate = 30;
+    } else {
+      *framerate = 2 + (frmrtq_postproc * 4);
+    }
+    if (bitrtq_postproc == 31) {
+      *bitrate = 2016;
+    } else {
+      *bitrate = 32 + (bitrtq_postproc * 64);
+    }
+  }
+}
+
+static inline void
+calculate_mb_size (GstVC1SeqHdr * seqhdr, guint width, guint height)
+{
+  seqhdr->mb_width = (width + 15) >> 4;
+  seqhdr->mb_height = (height + 15) >> 4;
+  seqhdr->mb_stride = seqhdr->mb_width + 1;
+}
+
+static GstVC1ParserResult
+parse_hrd_param_flag (GstBitReader * br, GstVC1HrdParam * hrd_param)
+{
+  guint i;
+
+  GST_DEBUG ("Parsing Hrd param flag");
+
+
+  if (gst_bit_reader_get_remaining (br) < 13)
+    goto failed;
+
+  hrd_param->hrd_num_leaky_buckets =
+      gst_bit_reader_get_bits_uint8_unchecked (br, 5);
+  hrd_param->bit_rate_exponent =
+      gst_bit_reader_get_bits_uint8_unchecked (br, 4);
+  hrd_param->buffer_size_exponent =
+      gst_bit_reader_get_bits_uint8_unchecked (br, 4);
+
+  if (gst_bit_reader_get_remaining (br) <
+      (32 * hrd_param->hrd_num_leaky_buckets))
+    goto failed;
+
+  for (i = 0; i < hrd_param->hrd_num_leaky_buckets; i++) {
+    hrd_param->hrd_rate[i] = gst_bit_reader_get_bits_uint16_unchecked (br, 16);
+    hrd_param->hrd_buffer[i] =
+        gst_bit_reader_get_bits_uint16_unchecked (br, 16);
+  }
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse hrd param flag");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+static GstVC1ParserResult
+parse_sequence_header_advanced (GstVC1SeqHdr * seqhdr, GstBitReader * br)
+{
+  GstVC1AdvancedSeqHdr *advanced = &seqhdr->advanced;
+  guint8 tmp;
+
+  GST_DEBUG ("Parsing sequence header in advanced mode");
+
+  READ_UINT8 (br, tmp, 3);
+  advanced->level = tmp;
+  advanced->par_n = 0;
+  advanced->par_d = 0;
+  advanced->fps_n = 0;
+  advanced->fps_d = 0;
+
+  READ_UINT8 (br, advanced->colordiff_format, 2);
+  READ_UINT8 (br, advanced->frmrtq_postproc, 3);
+  READ_UINT8 (br, advanced->bitrtq_postproc, 5);
+
+  calculate_framerate_bitrate (advanced->frmrtq_postproc,
+      advanced->bitrtq_postproc, &advanced->framerate, &advanced->bitrate);
+
+  GST_DEBUG ("level %u, colordiff_format %u , frmrtq_postproc %u,"
+      " bitrtq_postproc %u", advanced->level, advanced->colordiff_format,
+      advanced->frmrtq_postproc, advanced->bitrtq_postproc);
+
+  if (gst_bit_reader_get_remaining (br) < 32)
+    goto failed;
+
+  advanced->postprocflag = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  advanced->max_coded_width = gst_bit_reader_get_bits_uint16_unchecked (br, 12);
+  advanced->max_coded_height =
+      gst_bit_reader_get_bits_uint16_unchecked (br, 12);
+  advanced->max_coded_width = (advanced->max_coded_width + 1) << 1;
+  advanced->max_coded_height = (advanced->max_coded_height + 1) << 1;
+  calculate_mb_size (seqhdr, advanced->max_coded_width,
+      advanced->max_coded_height);
+  advanced->pulldown = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  advanced->interlace = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  advanced->tfcntrflag = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  advanced->finterpflag = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+  GST_DEBUG ("postprocflag %u, max_coded_width %u, max_coded_height %u,"
+      "pulldown %u, interlace %u, tfcntrflag %u, finterpflag %u",
+      advanced->postprocflag, advanced->max_coded_width,
+      advanced->max_coded_height, advanced->pulldown,
+      advanced->interlace, advanced->tfcntrflag, advanced->finterpflag);
+
+  /* Skipping reserved bit */
+  gst_bit_reader_skip_unchecked (br, 1);
+
+  advanced->psf = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  advanced->display_ext = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  if (advanced->display_ext) {
+    READ_UINT16 (br, advanced->disp_horiz_size, 14);
+    READ_UINT16 (br, advanced->disp_vert_size, 14);
+
+    advanced->disp_horiz_size++;
+    advanced->disp_vert_size++;
+
+    READ_UINT8 (br, advanced->aspect_ratio_flag, 1);
+
+    if (advanced->aspect_ratio_flag) {
+      READ_UINT8 (br, advanced->aspect_ratio, 4);
+
+      if (advanced->aspect_ratio == 15) {
+        /* Aspect Width (6.1.14.3.2) and Aspect Height (6.1.14.3.3)
+         * syntax elements hold a binary encoding of sizes ranging
+         * from 1 to 256 */
+        READ_UINT8 (br, advanced->aspect_horiz_size, 8);
+        READ_UINT8 (br, advanced->aspect_vert_size, 8);
+        advanced->par_n = 1 + advanced->aspect_horiz_size;
+        advanced->par_d = 1 + advanced->aspect_vert_size;
+      } else {
+        advanced->par_n = aspect_ratios[advanced->aspect_ratio].par_n;
+        advanced->par_d = aspect_ratios[advanced->aspect_ratio].par_d;
+      }
+    }
+    READ_UINT8 (br, advanced->framerate_flag, 1);
+    if (advanced->framerate_flag) {
+      READ_UINT8 (br, advanced->framerateind, 1);
+
+      if (!advanced->framerateind) {
+        READ_UINT8 (br, advanced->frameratenr, 8);
+        READ_UINT8 (br, advanced->frameratedr, 4);
+      } else {
+        READ_UINT16 (br, advanced->framerateexp, 16);
+      }
+      if (advanced->frameratenr > 0 &&
+          advanced->frameratenr < 8 &&
+          advanced->frameratedr > 0 && advanced->frameratedr < 3) {
+        advanced->fps_n = framerates_n[advanced->frameratenr];
+        advanced->fps_d = framerates_d[advanced->frameratedr];
+      } else {
+        advanced->fps_n = advanced->framerateexp + 1;
+        advanced->fps_d = 32;
+      }
+    }
+    READ_UINT8 (br, advanced->color_format_flag, 1);
+
+    if (advanced->color_format_flag) {
+      if (gst_bit_reader_get_remaining (br) < 24)
+        goto failed;
+
+      advanced->color_prim = gst_bit_reader_get_bits_uint8_unchecked (br, 8);
+      advanced->transfer_char = gst_bit_reader_get_bits_uint8_unchecked (br, 8);
+      advanced->matrix_coef = gst_bit_reader_get_bits_uint8_unchecked (br, 8);
+    }
+  }
+  READ_UINT8 (br, advanced->hrd_param_flag, 1);
+  if (advanced->hrd_param_flag)
+    return parse_hrd_param_flag (br, &advanced->hrd_param);
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse advanced headers");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+static GstVC1ParserResult
+parse_frame_header_advanced (GstBitReader * br, GstVC1FrameHdr * framehdr,
+    GstVC1SeqHdr * seqhdr, GstVC1BitPlanes * bitplanes, gboolean field2)
+{
+  GstVC1AdvancedSeqHdr *advhdr = &seqhdr->advanced;
+  GstVC1PicAdvanced *pic = &framehdr->pic.advanced;
+  GstVC1EntryPointHdr *entrypthdr = &advhdr->entrypoint;
+  guint8 mvmodeidx;
+
+  GST_DEBUG ("Parsing Frame header advanced %u", advhdr->interlace);
+
+  /* Set the conveninence fields */
+  framehdr->profile = seqhdr->profile;
+  framehdr->dquant = entrypthdr->dquant;
+
+  if (advhdr->interlace) {
+    gint8 fcm = decode012 (br);
+
+    if (fcm < 0)
+      goto failed;
+
+    pic->fcm = (guint8) fcm;
+  } else
+    pic->fcm = GST_VC1_FRAME_PROGRESSIVE;
+
+  if (pic->fcm == GST_VC1_FIELD_INTERLACE) {
+    READ_UINT8 (br, pic->fptype, 3);
+    if (field2) {
+      switch (pic->fptype) {
+        case 0x00:
+        case 0x02:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_I;
+          break;
+        case 0x01:
+        case 0x03:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_P;
+          break;
+        case 0x04:
+        case 0x06:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_B;
+          break;
+        case 0x05:
+        case 0x07:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
+          break;
+      }
+    } else {
+      switch (pic->fptype) {
+        case 0x00:
+        case 0x01:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_I;
+          break;
+        case 0x02:
+        case 0x03:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_P;
+          break;
+        case 0x04:
+        case 0x05:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_B;
+          break;
+        case 0x06:
+        case 0x07:
+          framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
+          break;
+      }
+    }
+  } else
+    framehdr->ptype = (guint8) get_unary (br, 0, 4);
+
+  if (advhdr->tfcntrflag) {
+    READ_UINT8 (br, pic->tfcntr, 8);
+    GST_DEBUG ("tfcntr %u", pic->tfcntr);
+  }
+
+  if (advhdr->pulldown) {
+    if (!advhdr->interlace || advhdr->psf) {
+
+      READ_UINT8 (br, pic->rptfrm, 2);
+      GST_DEBUG ("rptfrm %u", pic->rptfrm);
+
+    } else {
+
+      READ_UINT8 (br, pic->tff, 1);
+      READ_UINT8 (br, pic->rff, 1);
+      GST_DEBUG ("tff %u, rff %u", pic->tff, pic->rff);
+    }
+  }
+
+  if (entrypthdr->panscan_flag) {
+    READ_UINT8 (br, pic->ps_present, 1);
+
+    if (pic->ps_present) {
+      guint i, nb_pan_scan_win = calculate_nb_pan_scan_win (advhdr, pic);
+
+      if (gst_bit_reader_get_remaining (br) < 64 * nb_pan_scan_win)
+        goto failed;
+
+      for (i = 0; i < nb_pan_scan_win; i++) {
+        pic->ps_hoffset = gst_bit_reader_get_bits_uint32_unchecked (br, 18);
+        pic->ps_voffset = gst_bit_reader_get_bits_uint32_unchecked (br, 18);
+        pic->ps_width = gst_bit_reader_get_bits_uint16_unchecked (br, 14);
+        pic->ps_height = gst_bit_reader_get_bits_uint16_unchecked (br, 14);
+      }
+    }
+  }
+
+  if (framehdr->ptype == GST_VC1_PICTURE_TYPE_SKIPPED)
+    return GST_VC1_PARSER_OK;
+
+  READ_UINT8 (br, pic->rndctrl, 1);
+
+  if (advhdr->interlace) {
+    READ_UINT8 (br, pic->uvsamp, 1);
+    GST_DEBUG ("uvsamp %u", pic->uvsamp);
+    if (pic->fcm == GST_VC1_FIELD_INTERLACE && entrypthdr->refdist_flag &&
+        pic->fptype < 4)
+      decode_refdist (br, &pic->refdist);
+    else
+      pic->refdist = 0;
+  }
+
+  if (advhdr->finterpflag) {
+    READ_UINT8 (br, framehdr->interpfrm, 1);
+    GST_DEBUG ("interpfrm %u", framehdr->interpfrm);
+  }
+
+  if ((pic->fcm != GST_VC1_FIELD_INTERLACE &&
+          framehdr->ptype == GST_VC1_PICTURE_TYPE_B) ||
+      (pic->fcm == GST_VC1_FIELD_INTERLACE && (pic->fptype > 4))) {
+
+    guint bfraction;
+
+    if (!decode_vlc (br, &bfraction, vc1_bfraction_vlc_table,
+            G_N_ELEMENTS (vc1_bfraction_vlc_table)))
+      goto failed;
+
+    pic->bfraction = bfraction;
+    GST_DEBUG ("bfraction %u", pic->bfraction);
+
+    if (pic->bfraction == GST_VC1_BFRACTION_PTYPE_BI) {
+      framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
+    }
+
+  }
+
+  READ_UINT8 (br, framehdr->pqindex, 5);
+  if (!framehdr->pqindex)
+    goto failed;
+
+  /* compute pquant */
+  if (entrypthdr->quantizer == GST_VC1_QUANTIZER_IMPLICITLY)
+    framehdr->pquant = vc1_pquant_table[0][framehdr->pqindex];
+  else
+    framehdr->pquant = vc1_pquant_table[1][framehdr->pqindex];
+
+  framehdr->pquantizer = 1;
+  if (entrypthdr->quantizer == GST_VC1_QUANTIZER_IMPLICITLY)
+    framehdr->pquantizer = framehdr->pqindex < 9;
+  if (entrypthdr->quantizer == GST_VC1_QUANTIZER_NON_UNIFORM)
+    framehdr->pquantizer = 0;
+
+  if (framehdr->pqindex <= 8)
+    READ_UINT8 (br, framehdr->halfqp, 1);
+  else
+    framehdr->halfqp = 0;
+
+  if (entrypthdr->quantizer == GST_VC1_QUANTIZER_EXPLICITLY) {
+    READ_UINT8 (br, framehdr->pquantizer, 1);
+  }
+
+  if (advhdr->postprocflag)
+    READ_UINT8 (br, pic->postproc, 2);
+
+  GST_DEBUG ("Parsing %u picture, pqindex %u, pquant %u pquantizer %u"
+      "halfqp %u", framehdr->ptype, framehdr->pqindex, framehdr->pquant,
+      framehdr->pquantizer, framehdr->halfqp);
+
+  switch (framehdr->ptype) {
+    case GST_VC1_PICTURE_TYPE_I:
+    case GST_VC1_PICTURE_TYPE_BI:
+      if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+        if (!bitplane_decoding (br, bitplanes ? bitplanes->fieldtx : NULL,
+                seqhdr, &pic->fieldtx))
+          goto failed;
+      }
+
+      if (!bitplane_decoding (br, bitplanes ? bitplanes->acpred : NULL,
+              seqhdr, &pic->acpred))
+        goto failed;
+
+      if (entrypthdr->overlap && framehdr->pquant <= 8) {
+        pic->condover = decode012 (br);
+
+        if (pic->condover == (guint8) - 1)
+          goto failed;
+
+        else if (pic->condover == GST_VC1_CONDOVER_SELECT) {
+          if (!bitplane_decoding (br, bitplanes ? bitplanes->overflags : NULL,
+                  seqhdr, &pic->overflags))
+            goto failed;
+
+          GST_DEBUG ("overflags %u", pic->overflags);
+        }
+      }
+
+      framehdr->transacfrm = get_unary (br, 0, 2);
+      pic->transacfrm2 = get_unary (br, 0, 2);
+      READ_UINT8 (br, framehdr->transdctab, 1);
+
+      if (framehdr->dquant)
+        parse_vopdquant (br, framehdr, framehdr->dquant);
+
+      GST_DEBUG
+          ("acpred %u, condover %u, transacfrm %u, transacfrm2 %u, transdctab %u",
+          pic->acpred, pic->condover, framehdr->transacfrm, pic->transacfrm2,
+          framehdr->transdctab);
+      break;
+
+    case GST_VC1_PICTURE_TYPE_B:
+      if (entrypthdr->extended_mv)
+        pic->mvrange = get_unary (br, 0, 3);
+      else
+        pic->mvrange = 0;
+
+      if (pic->fcm != GST_VC1_FRAME_PROGRESSIVE) {
+        if (entrypthdr->extended_dmv)
+          pic->dmvrange = get_unary (br, 0, 3);
+      }
+
+      if (pic->fcm == GST_VC1_FRAME_INTERLACE)
+        READ_UINT8 (br, pic->intcomp, 1);
+      else
+        READ_UINT8 (br, pic->mvmode, 1);
+
+      if (pic->fcm == GST_VC1_FIELD_INTERLACE) {
+
+        if (!bitplane_decoding (br, bitplanes ? bitplanes->forwardmb : NULL,
+                seqhdr, &pic->forwardmb))
+          goto failed;
+
+      } else {
+        if (!bitplane_decoding (br, bitplanes ? bitplanes->directmb : NULL,
+                seqhdr, &pic->directmb))
+          goto failed;
+
+        if (!bitplane_decoding (br, bitplanes ? bitplanes->skipmb : NULL,
+                seqhdr, &pic->skipmb))
+          goto failed;
+      }
+
+      if (pic->fcm != GST_VC1_FRAME_PROGRESSIVE) {
+        if (gst_bit_reader_get_remaining (br) < 7)
+          goto failed;
+
+        pic->mbmodetab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+        pic->imvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+        pic->icbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+
+        if (pic->fcm == GST_VC1_FRAME_INTERLACE)
+          READ_UINT8 (br, pic->mvbptab2, 2);
+
+        if (pic->fcm == GST_VC1_FRAME_INTERLACE ||
+            (pic->fcm == GST_VC1_FIELD_INTERLACE
+                && pic->mvmode == GST_VC1_MVMODE_MIXED_MV))
+          READ_UINT8 (br, pic->mvbptab4, 2);
+
+      } else {
+        READ_UINT8 (br, pic->mvtab, 2);
+        READ_UINT8 (br, pic->cbptab, 2);
+      }
+
+      if (framehdr->dquant) {
+        parse_vopdquant (br, framehdr, framehdr->dquant);
+      }
+
+      if (entrypthdr->vstransform) {
+        READ_UINT8 (br, pic->ttmbf, 1);
+
+        if (pic->ttmbf) {
+          READ_UINT8 (br, pic->ttfrm, 2);
+        }
+      }
+
+      framehdr->transacfrm = get_unary (br, 0, 2);
+      READ_UINT8 (br, framehdr->transdctab, 1);
+
+      GST_DEBUG ("transacfrm %u transdctab %u mvmode %u mvtab %u,"
+          "cbptab %u directmb %u skipmb %u", framehdr->transacfrm,
+          framehdr->transdctab, pic->mvmode, pic->mvtab, pic->cbptab,
+          pic->directmb, pic->skipmb);
+
+      break;
+    case GST_VC1_PICTURE_TYPE_P:
+      if (pic->fcm == GST_VC1_FIELD_INTERLACE) {
+        READ_UINT8 (br, pic->numref, 1);
+
+        if (pic->numref)
+          READ_UINT8 (br, pic->reffield, 1);
+      }
+
+      if (entrypthdr->extended_mv)
+        pic->mvrange = get_unary (br, 0, 3);
+      else
+        pic->mvrange = 0;
+
+      if (pic->fcm != GST_VC1_FRAME_PROGRESSIVE) {
+        if (entrypthdr->extended_dmv)
+          pic->dmvrange = get_unary (br, 0, 3);
+      }
+
+      if (pic->fcm == GST_VC1_FRAME_INTERLACE) {
+        READ_UINT8 (br, pic->mvswitch4, 1);
+        READ_UINT8 (br, pic->intcomp, 1);
+
+        if (pic->intcomp) {
+          READ_UINT8 (br, pic->lumscale, 6);
+          READ_UINT8 (br, pic->lumshift, 6);
+        }
+      } else {
+
+        mvmodeidx = framehdr->pquant > 12;
+        pic->mvmode = vc1_mvmode_table[mvmodeidx][get_unary (br, 1, 4)];
+
+        if (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP) {
+          pic->mvmode2 = vc1_mvmode2_table[mvmodeidx][get_unary (br, 1, 3)];
+
+          if (pic->fcm == GST_VC1_FIELD_INTERLACE)
+            pic->intcompfield = decode012 (br);
+
+          READ_UINT8 (br, pic->lumscale, 6);
+          READ_UINT8 (br, pic->lumshift, 6);
+          GST_DEBUG ("lumscale %u lumshift %u", pic->lumscale, pic->lumshift);
+
+          if (pic->fcm == GST_VC1_FIELD_INTERLACE && pic->intcompfield) {
+            READ_UINT8 (br, pic->lumscale2, 6);
+            READ_UINT8 (br, pic->lumshift2, 6);
+          }
+        }
+
+        if (pic->fcm == GST_VC1_FRAME_PROGRESSIVE) {
+          if (pic->mvmode == GST_VC1_MVMODE_MIXED_MV ||
+              (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
+                  pic->mvmode2 == GST_VC1_MVMODE_MIXED_MV)) {
+
+            if (!bitplane_decoding (br, bitplanes ? bitplanes->mvtypemb : NULL,
+                    seqhdr, &pic->mvtypemb))
+              goto failed;
+
+            GST_DEBUG ("mvtypemb %u", pic->mvtypemb);
+          }
+        }
+      }
+
+      if (pic->fcm != GST_VC1_FIELD_INTERLACE) {
+        if (!bitplane_decoding (br, bitplanes ? bitplanes->skipmb : NULL,
+                seqhdr, &pic->skipmb))
+          goto failed;
+      }
+
+      if (pic->fcm != GST_VC1_FRAME_PROGRESSIVE) {
+        if (gst_bit_reader_get_remaining (br) < 7)
+          goto failed;
+
+        pic->mbmodetab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+        pic->imvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+        pic->icbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+
+        if (pic->fcm != GST_VC1_FIELD_INTERLACE) {
+          READ_UINT8 (br, pic->mvbptab2, 2);
+
+          if (pic->mvswitch4)
+            READ_UINT8 (br, pic->mvbptab4, 2);
+
+        } else if (pic->mvmode == GST_VC1_MVMODE_MIXED_MV)
+          READ_UINT8 (br, pic->mvbptab4, 2);
+
+      } else {
+        if (gst_bit_reader_get_remaining (br) < 4)
+          goto failed;
+        pic->mvtab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+        pic->cbptab = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+      }
+
+      if (framehdr->dquant) {
+        parse_vopdquant (br, framehdr, framehdr->dquant);
+      }
+
+      if (entrypthdr->vstransform) {
+        READ_UINT8 (br, pic->ttmbf, 1);
+
+        if (pic->ttmbf) {
+          READ_UINT8 (br, pic->ttfrm, 2);
+        }
+      }
+
+      framehdr->transacfrm = get_unary (br, 0, 2);
+      READ_UINT8 (br, framehdr->transdctab, 1);
+
+      GST_DEBUG ("transacfrm %u transdctab %u mvmode %u mvtab %u,"
+          "cbptab %u skipmb %u", framehdr->transacfrm, framehdr->transdctab,
+          pic->mvmode, pic->mvtab, pic->cbptab, pic->skipmb);
+
+      break;
+
+    default:
+      goto failed;
+      break;
+  }
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse frame header");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+static GstVC1ParserResult
+parse_frame_header (GstBitReader * br, GstVC1FrameHdr * framehdr,
+    GstVC1SeqHdr * seqhdr, GstVC1BitPlanes * bitplanes)
+{
+  guint8 mvmodeidx, tmp;
+  GstVC1PicSimpleMain *pic = &framehdr->pic.simple;
+  GstVC1SeqStructC *structc = &seqhdr->struct_c;
+
+  GST_DEBUG ("Parsing frame header in simple or main mode");
+
+  /* Set the conveninence fields */
+  framehdr->profile = seqhdr->profile;
+  framehdr->dquant = structc->dquant;
+
+  framehdr->interpfrm = 0;
+  if (structc->finterpflag)
+    READ_UINT8 (br, framehdr->interpfrm, 1);
+
+  READ_UINT8 (br, pic->frmcnt, 2);
+
+  pic->rangeredfrm = 0;
+  if (structc->rangered) {
+    READ_UINT8 (br, pic->rangeredfrm, 1);
+  }
+
+  /*  Figuring out the picture type */
+  READ_UINT8 (br, tmp, 1);
+  framehdr->ptype = tmp;
+
+  if (structc->maxbframes) {
+    if (!framehdr->ptype) {
+      READ_UINT8 (br, tmp, 1);
+
+      if (tmp)
+        framehdr->ptype = GST_VC1_PICTURE_TYPE_I;
+      else
+        framehdr->ptype = GST_VC1_PICTURE_TYPE_B;
+
+    } else
+      framehdr->ptype = GST_VC1_PICTURE_TYPE_P;
+
+  } else {
+    if (framehdr->ptype)
+      framehdr->ptype = GST_VC1_PICTURE_TYPE_P;
+    else
+      framehdr->ptype = GST_VC1_PICTURE_TYPE_I;
+  }
+
+
+  if (framehdr->ptype == GST_VC1_PICTURE_TYPE_B) {
+    guint bfraction;
+    if (!decode_vlc (br, &bfraction, vc1_bfraction_vlc_table,
+            G_N_ELEMENTS (vc1_bfraction_vlc_table)))
+      goto failed;
+
+    pic->bfraction = bfraction;
+    GST_DEBUG ("bfraction %d", pic->bfraction);
+
+    if (pic->bfraction == GST_VC1_BFRACTION_PTYPE_BI) {
+      framehdr->ptype = GST_VC1_PICTURE_TYPE_BI;
+    }
+  }
+
+  if (framehdr->ptype == GST_VC1_PICTURE_TYPE_I ||
+      framehdr->ptype == GST_VC1_PICTURE_TYPE_BI)
+    READ_UINT8 (br, pic->bf, 7);
+
+  READ_UINT8 (br, framehdr->pqindex, 5);
+  if (!framehdr->pqindex)
+    return GST_VC1_PARSER_ERROR;
+
+  GST_DEBUG ("pqindex %u", framehdr->pqindex);
+
+  /* compute pquant */
+  if (structc->quantizer == GST_VC1_QUANTIZER_IMPLICITLY)
+    framehdr->pquant = vc1_pquant_table[0][framehdr->pqindex];
+  else
+    framehdr->pquant = vc1_pquant_table[1][framehdr->pqindex];
+
+  GST_DEBUG ("pquant %u", framehdr->pquant);
+
+  if (framehdr->pqindex <= 8)
+    READ_UINT8 (br, framehdr->halfqp, 1);
+  else
+    framehdr->halfqp = 0;
+
+  /* Set pquantizer */
+  framehdr->pquantizer = 1;
+  if (structc->quantizer == GST_VC1_QUANTIZER_IMPLICITLY)
+    framehdr->pquantizer = framehdr->pqindex < 9;
+  else if (structc->quantizer == GST_VC1_QUANTIZER_NON_UNIFORM)
+    framehdr->pquantizer = 0;
+
+  if (structc->quantizer == GST_VC1_QUANTIZER_EXPLICITLY)
+    READ_UINT8 (br, framehdr->pquantizer, 1);
+
+  if (structc->extended_mv == 1) {
+    pic->mvrange = get_unary (br, 0, 3);
+    GST_DEBUG ("mvrange %u", pic->mvrange);
+  }
+
+  if (structc->multires && (framehdr->ptype == GST_VC1_PICTURE_TYPE_P ||
+          framehdr->ptype == GST_VC1_PICTURE_TYPE_I)) {
+    READ_UINT8 (br, pic->respic, 2);
+    GST_DEBUG ("Respic %u", pic->respic);
+  }
+
+  GST_DEBUG ("Parsing %u Frame, pquantizer %u, halfqp %u, rangeredfrm %u, "
+      "interpfrm %u", framehdr->ptype, framehdr->pquantizer, framehdr->halfqp,
+      pic->rangeredfrm, framehdr->interpfrm);
+
+  switch (framehdr->ptype) {
+    case GST_VC1_PICTURE_TYPE_I:
+    case GST_VC1_PICTURE_TYPE_BI:
+      framehdr->transacfrm = get_unary (br, 0, 2);
+      pic->transacfrm2 = get_unary (br, 0, 2);
+      READ_UINT8 (br, framehdr->transdctab, 1);
+
+      GST_DEBUG ("transacfrm %u, transacfrm2 %u, transdctab %u",
+          framehdr->transacfrm, pic->transacfrm2, framehdr->transdctab);
+      break;
+
+    case GST_VC1_PICTURE_TYPE_P:
+      mvmodeidx = framehdr->pquant > 12;
+      pic->mvmode = vc1_mvmode_table[mvmodeidx][get_unary (br, 1, 4)];
+
+      if (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP) {
+        pic->mvmode2 = vc1_mvmode2_table[mvmodeidx][get_unary (br, 1, 3)];
+        READ_UINT8 (br, pic->lumscale, 6);
+        READ_UINT8 (br, pic->lumshift, 6);
+        GST_DEBUG ("lumscale %u lumshift %u", pic->lumscale, pic->lumshift);
+      }
+
+      if (pic->mvmode == GST_VC1_MVMODE_MIXED_MV ||
+          (pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
+              pic->mvmode2 == GST_VC1_MVMODE_MIXED_MV)) {
+        if (!bitplane_decoding (br, bitplanes ? bitplanes->mvtypemb : NULL,
+                seqhdr, &pic->mvtypemb))
+          goto failed;
+        GST_DEBUG ("mvtypemb %u", pic->mvtypemb);
+      }
+      if (!bitplane_decoding (br, bitplanes ? bitplanes->skipmb : NULL,
+              seqhdr, &pic->skipmb))
+        goto failed;
+
+      READ_UINT8 (br, pic->mvtab, 2);
+      READ_UINT8 (br, pic->cbptab, 2);
+
+      if (framehdr->dquant) {
+        parse_vopdquant (br, framehdr, framehdr->dquant);
+      }
+
+      if (structc->vstransform) {
+        READ_UINT8 (br, pic->ttmbf, 1);
+        GST_DEBUG ("ttmbf %u", pic->ttmbf);
+
+        if (pic->ttmbf) {
+          READ_UINT8 (br, pic->ttfrm, 2);
+          GST_DEBUG ("ttfrm %u", pic->ttfrm);
+        }
+      }
+
+      framehdr->transacfrm = get_unary (br, 0, 2);
+      READ_UINT8 (br, framehdr->transdctab, 1);
+
+      GST_DEBUG ("transacfrm %u transdctab %u mvmode %u mvtab %u,"
+          "cbptab %u skipmb %u", framehdr->transacfrm, framehdr->transdctab,
+          pic->mvmode, pic->mvtab, pic->cbptab, pic->skipmb);
+      break;
+
+    case GST_VC1_PICTURE_TYPE_B:
+      READ_UINT8 (br, pic->mvmode, 1);
+      if (!bitplane_decoding (br, bitplanes ? bitplanes->directmb : NULL,
+              seqhdr, &pic->directmb))
+        goto failed;
+
+      if (!bitplane_decoding (br, bitplanes ? bitplanes->skipmb : NULL,
+              seqhdr, &pic->skipmb))
+        goto failed;
+
+      READ_UINT8 (br, pic->mvtab, 2);
+      READ_UINT8 (br, pic->cbptab, 2);
+
+      if (framehdr->dquant)
+        parse_vopdquant (br, framehdr, framehdr->dquant);
+
+      if (structc->vstransform) {
+        READ_UINT8 (br, pic->ttmbf, 1);
+
+        if (pic->ttmbf) {
+          READ_UINT8 (br, pic->ttfrm, 2);
+        }
+      }
+
+      framehdr->transacfrm = get_unary (br, 0, 2);
+      READ_UINT8 (br, framehdr->transdctab, 1);
+
+      GST_DEBUG ("transacfrm %u transdctab %u mvmode %u mvtab %u,"
+          "cbptab %u directmb %u skipmb %u", framehdr->transacfrm,
+          framehdr->transdctab, pic->mvmode, pic->mvtab, pic->cbptab,
+          pic->directmb, pic->skipmb);
+
+      break;
+
+    default:
+      goto failed;
+      break;
+  }
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse Simple picture header");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+static GstVC1ParserResult
+parse_sequence_header_struct_a (GstBitReader * br, GstVC1SeqStructA * structa)
+{
+  if (gst_bit_reader_get_remaining (br) < 64) {
+    GST_WARNING ("Failed to parse struct A");
+
+    return GST_VC1_PARSER_ERROR;
+  }
+
+  structa->vert_size = gst_bit_reader_get_bits_uint32_unchecked (br, 32);
+  structa->horiz_size = gst_bit_reader_get_bits_uint32_unchecked (br, 32);
+
+  return GST_VC1_PARSER_OK;
+}
+
+static GstVC1ParserResult
+parse_sequence_header_struct_b (GstBitReader * br, GstVC1SeqStructB * structb)
+{
+  if (gst_bit_reader_get_remaining (br) < 96) {
+    GST_WARNING ("Failed to parse sequence header");
+
+    return GST_VC1_PARSER_ERROR;
+  }
+
+  structb->level = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+  structb->cbr = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+  /* res4 */
+  gst_bit_reader_skip_unchecked (br, 4);
+
+  structb->hrd_buffer = gst_bit_reader_get_bits_uint32_unchecked (br, 24);
+  structb->hrd_rate = gst_bit_reader_get_bits_uint32_unchecked (br, 32);
+  structb->framerate = gst_bit_reader_get_bits_uint32_unchecked (br, 32);
+
+  return GST_VC1_PARSER_OK;
+}
+
+static GstVC1ParserResult
+parse_sequence_header_struct_c (GstBitReader * br, GstVC1SeqStructC * structc)
+{
+  guint8 old_interlaced_mode, tmp;
+
+  READ_UINT8 (br, tmp, 2);
+  structc->profile = tmp;
+
+  if (structc->profile == GST_VC1_PROFILE_ADVANCED)
+    return GST_VC1_PARSER_OK;
+
+  GST_DEBUG ("Parsing sequence header in simple or main mode");
+
+  if (gst_bit_reader_get_remaining (br) < 29)
+    goto failed;
+
+  /* Reserved bits */
+  old_interlaced_mode = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  if (old_interlaced_mode)
+    GST_WARNING ("Old interlaced mode used");
+
+  structc->wmvp = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  if (structc->wmvp)
+    GST_DEBUG ("WMVP mode");
+
+  structc->frmrtq_postproc = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+  structc->bitrtq_postproc = gst_bit_reader_get_bits_uint8_unchecked (br, 5);
+  structc->loop_filter = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+  calculate_framerate_bitrate (structc->frmrtq_postproc,
+      structc->bitrtq_postproc, &structc->framerate, &structc->bitrate);
+
+  /* Skipping reserved3 bit */
+  gst_bit_reader_skip_unchecked (br, 1);
+
+  structc->multires = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+  /* Skipping reserved4 bit */
+  gst_bit_reader_skip_unchecked (br, 1);
+
+  structc->fastuvmc = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  structc->extended_mv = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  structc->dquant = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+  structc->vstransform = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+  /* Skipping reserved5 bit */
+  gst_bit_reader_skip_unchecked (br, 1);
+
+  structc->overlap = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  structc->syncmarker = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  structc->rangered = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+  structc->maxbframes = gst_bit_reader_get_bits_uint8_unchecked (br, 3);
+  structc->quantizer = gst_bit_reader_get_bits_uint8_unchecked (br, 2);
+  structc->finterpflag = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+  GST_DEBUG ("frmrtq_postproc %u, bitrtq_postproc %u, loop_filter %u, "
+      "multires %u, fastuvmc %u, extended_mv %u, dquant %u, vstransform %u, "
+      "overlap %u, syncmarker %u, rangered %u, maxbframes %u, quantizer %u, "
+      "finterpflag %u", structc->frmrtq_postproc, structc->bitrtq_postproc,
+      structc->loop_filter, structc->multires, structc->fastuvmc,
+      structc->extended_mv, structc->dquant, structc->vstransform,
+      structc->overlap, structc->syncmarker, structc->rangered,
+      structc->maxbframes, structc->quantizer, structc->finterpflag);
+
+  if (structc->wmvp) {
+    if (gst_bit_reader_get_remaining (br) < 29)
+      goto failed;
+
+    structc->coded_width = gst_bit_reader_get_bits_uint16_unchecked (br, 11);
+    structc->coded_height = gst_bit_reader_get_bits_uint16_unchecked (br, 11);
+    structc->framerate = gst_bit_reader_get_bits_uint8_unchecked (br, 5);
+    gst_bit_reader_skip_unchecked (br, 1);
+    structc->slice_code = gst_bit_reader_get_bits_uint8_unchecked (br, 1);
+
+    GST_DEBUG ("coded_width %u, coded_height %u, framerate %u slice_code %u",
+        structc->coded_width, structc->coded_height, structc->framerate,
+        structc->slice_code);
+  }
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to struct C");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+/**** API ****/
+/**
+ * gst_vc1_identify_next_bdu:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @bdu: (out): The #GstVC1BDU where to store parsed bdu headers
+ *
+ * Parses @data and fills @bdu fields
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_identify_next_bdu (const guint8 * data, gsize size, GstVC1BDU * bdu)
+{
+  gint off1, off2;
+
+  g_return_val_if_fail (bdu != NULL, GST_VC1_PARSER_ERROR);
+
+  if (size < 4) {
+    GST_DEBUG ("Can't parse, buffer has too small size %" G_GSSIZE_FORMAT,
+        size);
+    return GST_VC1_PARSER_ERROR;
+  }
+
+  off1 = scan_for_start_codes (data, size);
+
+  if (off1 < 0) {
+    GST_DEBUG ("No start code prefix in this buffer");
+    return GST_VC1_PARSER_NO_BDU;
+  }
+
+  bdu->sc_offset = off1;
+
+  bdu->offset = off1 + 4;
+  bdu->data = (guint8 *) data;
+  bdu->type = (GstVC1StartCode) (data[bdu->offset - 1]);
+
+  if (bdu->type == GST_VC1_END_OF_SEQ) {
+    GST_DEBUG ("End-of-Seq BDU found");
+    bdu->size = 0;
+    return GST_VC1_PARSER_OK;
+  }
+
+  off2 = scan_for_start_codes (data + bdu->offset, size - bdu->offset);
+  if (off2 < 0) {
+    GST_DEBUG ("Bdu start %d, No end found", bdu->offset);
+
+    return GST_VC1_PARSER_NO_BDU_END;
+  }
+
+  if (off2 > 0 && data[bdu->offset + off2 - 1] == 00)
+    off2--;
+
+  bdu->size = off2;
+
+  GST_DEBUG ("Complete bdu found. Off: %d, Size: %d", bdu->offset, bdu->size);
+  return GST_VC1_PARSER_OK;
+}
+
+/**
+ * gst_vc1_parse_sequence_layer:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @structa: The #GstVC1SeqLayer to set.
+ *
+ * Parses @data, and fills @seqlayer fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_sequence_layer (const guint8 * data, gsize size,
+    GstVC1SeqLayer * seqlayer)
+{
+  guint32 tmp;
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (seqlayer != NULL, GST_VC1_PARSER_ERROR);
+
+  READ_UINT32 (&br, tmp, 8);
+  if (tmp != 0xC5)
+    goto failed;
+
+  READ_UINT32 (&br, seqlayer->numframes, 24);
+
+  READ_UINT32 (&br, tmp, 32);
+  if (tmp != 0x04)
+    goto failed;
+
+  if (parse_sequence_header_struct_c (&br, &seqlayer->struct_c) ==
+      GST_VC1_PARSER_ERROR)
+    goto failed;
+
+  if (parse_sequence_header_struct_a (&br, &seqlayer->struct_a) ==
+      GST_VC1_PARSER_ERROR)
+    goto failed;
+
+  READ_UINT32 (&br, tmp, 32);
+  if (tmp != 0x0C)
+    goto failed;
+
+  if (parse_sequence_header_struct_b (&br, &seqlayer->struct_b) ==
+      GST_VC1_PARSER_ERROR)
+    goto failed;
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse sequence layer");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+/**
+ * gst_vc1_parse_sequence_header_struct_a:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @structa: The #GstVC1SeqStructA to set.
+ *
+ * Parses @data, and fills @structa fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_sequence_header_struct_a (const guint8 * data,
+    gsize size, GstVC1SeqStructA * structa)
+{
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (structa != NULL, GST_VC1_PARSER_ERROR);
+
+  return parse_sequence_header_struct_a (&br, structa);
+}
+
+/**
+ * gst_vc1_parse_sequence_header_struct_b:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @structa: The #GstVC1SeqStructB to set.
+ *
+ * Parses @data, and fills @structb fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_sequence_header_struct_b (const guint8 * data,
+    gsize size, GstVC1SeqStructB * structb)
+{
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (structb != NULL, GST_VC1_PARSER_ERROR);
+
+  return parse_sequence_header_struct_b (&br, structb);
+}
+
+/**
+ * gst_vc1_parse_sequence_header_struct_c:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @structc: The #GstVC1SeqStructC to set.
+ *
+ * Parses @data, and fills @structc fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_sequence_header_struct_c (const guint8 * data, gsize size,
+    GstVC1SeqStructC * structc)
+{
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (structc != NULL, GST_VC1_PARSER_ERROR);
+
+  return parse_sequence_header_struct_c (&br, structc);
+}
+
+/**
+* gst_vc1_parse_sequence_header:
+* @data: The data to parse
+* @size: the size of @data
+* @seqhdr: The #GstVC1SeqHdr to set.
+ *
+ * Parses @data, and fills @seqhdr fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_sequence_header (const guint8 * data, gsize size,
+    GstVC1SeqHdr * seqhdr)
+{
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  g_return_val_if_fail (seqhdr != NULL, GST_VC1_PARSER_ERROR);
+
+  if (parse_sequence_header_struct_c (&br, &seqhdr->struct_c) ==
+      GST_VC1_PARSER_ERROR)
+    goto failed;
+
+  /*  Convenience field */
+  seqhdr->profile = seqhdr->struct_c.profile;
+
+  if (seqhdr->profile == GST_VC1_PROFILE_ADVANCED)
+    return parse_sequence_header_advanced (seqhdr, &br);
+
+  /* Compute MB height and width */
+  calculate_mb_size (seqhdr, seqhdr->struct_c.coded_width,
+      seqhdr->struct_c.coded_height);
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse sequence header");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+/**
+ * gst_vc1_parse_entry_point_header:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @entrypoint: (out): The #GstVC1EntryPointHdr to set.
+ * @seqhdr: The #GstVC1SeqHdr currently being parsed
+ *
+ * Parses @data, and sets @entrypoint fields.
+ *
+ * Returns: a #GstVC1EntryPointHdr
+ */
+GstVC1ParserResult
+gst_vc1_parse_entry_point_header (const guint8 * data, gsize size,
+    GstVC1EntryPointHdr * entrypoint, GstVC1SeqHdr * seqhdr)
+{
+  GstBitReader br;
+  guint8 i;
+  GstVC1AdvancedSeqHdr *advanced = &seqhdr->advanced;
+
+  g_return_val_if_fail (entrypoint != NULL, GST_VC1_PARSER_ERROR);
+
+  gst_bit_reader_init (&br, data, size);
+
+  if (gst_bit_reader_get_remaining (&br) < 13)
+    goto failed;
+
+  entrypoint->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->closed_entry = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->panscan_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->refdist_flag = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->loopfilter = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->fastuvmc = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->extended_mv = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->dquant = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+  entrypoint->vstransform = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->overlap = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  entrypoint->quantizer = gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
+
+  if (advanced->hrd_param_flag) {
+    if (seqhdr->advanced.hrd_param.hrd_num_leaky_buckets >
+        MAX_HRD_NUM_LEAKY_BUCKETS) {
+      GST_WARNING
+          ("hrd_num_leaky_buckets (%d) > MAX_HRD_NUM_LEAKY_BUCKETS (%d)",
+          seqhdr->advanced.hrd_param.hrd_num_leaky_buckets,
+          MAX_HRD_NUM_LEAKY_BUCKETS);
+      goto failed;
+    }
+    for (i = 0; i < seqhdr->advanced.hrd_param.hrd_num_leaky_buckets; i++)
+      READ_UINT8 (&br, entrypoint->hrd_full[i], 8);
+  }
+
+  READ_UINT8 (&br, entrypoint->coded_size_flag, 1);
+  if (entrypoint->coded_size_flag) {
+    READ_UINT16 (&br, entrypoint->coded_width, 12);
+    READ_UINT16 (&br, entrypoint->coded_height, 12);
+    entrypoint->coded_height = (entrypoint->coded_height + 1) << 1;
+    entrypoint->coded_width = (entrypoint->coded_width + 1) << 1;
+    calculate_mb_size (seqhdr, entrypoint->coded_width,
+        entrypoint->coded_height);
+  }
+
+  if (entrypoint->extended_mv)
+    READ_UINT8 (&br, entrypoint->extended_dmv, 1);
+
+  READ_UINT8 (&br, entrypoint->range_mapy_flag, 1);
+  if (entrypoint->range_mapy_flag)
+    READ_UINT8 (&br, entrypoint->range_mapy, 3);
+
+  READ_UINT8 (&br, entrypoint->range_mapuv_flag, 1);
+  if (entrypoint->range_mapy_flag)
+    READ_UINT8 (&br, entrypoint->range_mapuv, 3);
+
+  advanced->entrypoint = *entrypoint;
+
+  return GST_VC1_PARSER_OK;
+
+failed:
+  GST_WARNING ("Failed to parse entry point header");
+
+  return GST_VC1_PARSER_ERROR;
+}
+
+/**
+ * gst_vc1_parse_frame_layer:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @framelayer: The #GstVC1FrameLayer to fill.
+ *
+ * Parses @data, and fills @framelayer fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_frame_layer (const guint8 * data, gsize size,
+    GstVC1FrameLayer * framelayer)
+{
+  GstBitReader br = GST_BIT_READER_INIT (data, size);
+
+  if (gst_bit_reader_get_remaining (&br) < 64) {
+    GST_WARNING ("Could not parse frame layer");
+
+    return GST_VC1_PARSER_ERROR;
+  }
+
+  /* set default values */
+  framelayer->skiped_p_frame = 0;
+
+  framelayer->key = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
+  gst_bit_reader_skip_unchecked (&br, 7);
+
+  framelayer->framesize = gst_bit_reader_get_bits_uint32_unchecked (&br, 24);
+
+  if (framelayer->framesize == 0 || framelayer->framesize == 1)
+    framelayer->skiped_p_frame = 1;
+
+  /* compute  next_framelayer_offset */
+  framelayer->next_framelayer_offset = framelayer->framesize + 8;
+
+  framelayer->timestamp = gst_bit_reader_get_bits_uint32_unchecked (&br, 32);
+
+  return GST_VC1_PARSER_OK;
+}
+
+/**
+ * gst_vc1_parse_frame_header:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @framehdr: The #GstVC1FrameHdr to fill.
+ * @seqhdr: The #GstVC1SeqHdr currently being parsed
+ * @bitplanes: The #GstVC1BitPlanes to store bitplanes in or %NULL
+ *
+ * Parses @data, and fills @entrypoint fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_frame_header (const guint8 * data, gsize size,
+    GstVC1FrameHdr * framehdr, GstVC1SeqHdr * seqhdr,
+    GstVC1BitPlanes * bitplanes)
+{
+  GstBitReader br;
+  GstVC1ParserResult result;
+
+  gst_bit_reader_init (&br, data, size);
+
+  if (seqhdr->profile == GST_VC1_PROFILE_ADVANCED)
+    result = parse_frame_header_advanced (&br, framehdr, seqhdr, bitplanes,
+        FALSE);
+  else
+    result = parse_frame_header (&br, framehdr, seqhdr, bitplanes);
+
+  framehdr->header_size = gst_bit_reader_get_pos (&br);
+  return result;
+}
+
+/**
+ * gst_vc1_parse_field_header:
+ * @data: The data to parse
+ * @size: the size of @data
+ * @fieldhdr: The #GstVC1FrameHdr to fill.
+ * @seqhdr: The #GstVC1SeqHdr currently being parsed
+ * @bitplanes: The #GstVC1BitPlanes to store bitplanes in or %NULL
+ *
+ * Parses @data, and fills @fieldhdr fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ */
+GstVC1ParserResult
+gst_vc1_parse_field_header (const guint8 * data, gsize size,
+    GstVC1FrameHdr * fieldhdr, GstVC1SeqHdr * seqhdr,
+    GstVC1BitPlanes * bitplanes)
+{
+  GstBitReader br;
+  GstVC1ParserResult result;
+
+  gst_bit_reader_init (&br, data, size);
+
+  result = parse_frame_header_advanced (&br, fieldhdr, seqhdr, bitplanes, TRUE);
+
+  return result;
+}
+
+/**
+ * gst_vc1_parse_slice_header:
+ * @data: The data to parse
+ * @size: The size of @data
+ * @slicehdr: The #GstVC1SliceHdr to fill
+ * @seqhdr: The #GstVC1SeqHdr that was previously parsed
+ *
+ * Parses @data, and fills @slicehdr fields.
+ *
+ * Returns: a #GstVC1ParserResult
+ *
+ * Since: 1.2
+ */
+GstVC1ParserResult
+gst_vc1_parse_slice_header (const guint8 * data, gsize size,
+    GstVC1SliceHdr * slicehdr, GstVC1SeqHdr * seqhdr)
+{
+  GstBitReader br;
+  GstVC1FrameHdr framehdr;
+  GstVC1ParserResult result;
+  guint8 pic_header_flag;
+
+  GST_DEBUG ("Parsing slice header");
+
+  if (seqhdr->profile != GST_VC1_PROFILE_ADVANCED)
+    return GST_VC1_PARSER_BROKEN_DATA;
+
+  gst_bit_reader_init (&br, data, size);
+
+  READ_UINT16 (&br, slicehdr->slice_addr, 9);
+  READ_UINT8 (&br, pic_header_flag, 1);
+  if (pic_header_flag)
+    result = parse_frame_header_advanced (&br, &framehdr, seqhdr, NULL, FALSE);
+  else
+    result = GST_VC1_PARSER_OK;
+
+  slicehdr->header_size = gst_bit_reader_get_pos (&br);
+  return result;
+
+failed:
+  GST_WARNING ("Failed to parse slice header");
+  return GST_VC1_PARSER_ERROR;
+}
+
+/**
+ * gst_vc1_bitplanes_new:
+ * @seqhdr: The #GstVC1SeqHdr from which to set @bitplanes
+ *
+ * Creates a new #GstVC1BitPlanes. It should be freed with
+ * gst_vc1_bitplanes_free() after use.
+ *
+ * Returns: a new #GstVC1BitPlanes
+ */
+GstVC1BitPlanes *
+gst_vc1_bitplanes_new (void)
+{
+  return g_slice_new0 (GstVC1BitPlanes);
+}
+
+/**
+ * gst_vc1_bitplane_free:
+ * @bitplanes: the #GstVC1BitPlanes to free
+ *
+ * Frees @bitplanes.
+ */
+void
+gst_vc1_bitplanes_free (GstVC1BitPlanes * bitplanes)
+{
+  gst_vc1_bitplanes_free_1 (bitplanes);
+  g_slice_free (GstVC1BitPlanes, bitplanes);
+}
+
+/**
+ * gst_vc1_bitplane_free_1:
+ * @bitplanes: The #GstVC1BitPlanes to free
+ *
+ * Frees @bitplanes fields.
+ */
+void
+gst_vc1_bitplanes_free_1 (GstVC1BitPlanes * bitplanes)
+{
+  g_free (bitplanes->acpred);
+  g_free (bitplanes->fieldtx);
+  g_free (bitplanes->overflags);
+  g_free (bitplanes->mvtypemb);
+  g_free (bitplanes->skipmb);
+  g_free (bitplanes->directmb);
+  g_free (bitplanes->forwardmb);
+}
+
+/**
+ * gst_vc1_bitplanes_ensure_size:
+ * @bitplanes: The #GstVC1BitPlanes to reset
+ * @seqhdr: The #GstVC1SeqHdr from which to set @bitplanes
+ *
+ * Fills the @bitplanes structure from @seqhdr, this function
+ * should be called after #gst_vc1_parse_sequence_header if
+ * in simple or main mode, or after #gst_vc1_parse_entry_point_header
+ * if in advanced mode.
+ *
+ * Returns: %TRUE if everything went fine, %FALSE otherwize
+ */
+gboolean
+gst_vc1_bitplanes_ensure_size (GstVC1BitPlanes * bitplanes,
+    GstVC1SeqHdr * seqhdr)
+{
+  g_return_val_if_fail (bitplanes != NULL, FALSE);
+  g_return_val_if_fail (seqhdr != NULL, FALSE);
+
+  if (bitplanes->size) {
+    bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
+    bitplanes->acpred =
+        g_realloc_n (bitplanes->acpred, bitplanes->size, sizeof (guint8));
+    bitplanes->fieldtx =
+        g_realloc_n (bitplanes->fieldtx, bitplanes->size, sizeof (guint8));
+    bitplanes->overflags =
+        g_realloc_n (bitplanes->overflags, bitplanes->size, sizeof (guint8));
+    bitplanes->mvtypemb =
+        g_realloc_n (bitplanes->mvtypemb, bitplanes->size, sizeof (guint8));
+    bitplanes->skipmb =
+        g_realloc_n (bitplanes->skipmb, bitplanes->size, sizeof (guint8));
+    bitplanes->directmb =
+        g_realloc_n (bitplanes->directmb, bitplanes->size, sizeof (guint8));
+    bitplanes->forwardmb =
+        g_realloc_n (bitplanes->forwardmb, bitplanes->size, sizeof (guint8));
+  } else {
+    bitplanes->size = seqhdr->mb_height * seqhdr->mb_stride;
+    bitplanes->acpred = g_malloc0 (bitplanes->size * sizeof (guint8));
+    bitplanes->fieldtx = g_malloc0 (bitplanes->size * sizeof (guint8));
+    bitplanes->overflags = g_malloc0 (bitplanes->size * sizeof (guint8));
+    bitplanes->mvtypemb = g_malloc0 (bitplanes->size * sizeof (guint8));
+    bitplanes->skipmb = g_malloc0 (bitplanes->size * sizeof (guint8));
+    bitplanes->directmb = g_malloc0 (bitplanes->size * sizeof (guint8));
+    bitplanes->forwardmb = g_malloc0 (bitplanes->size * sizeof (guint8));
+  }
+
+  return TRUE;
+}
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/gstvc1parser.h b/ext/codecparsers/gst-libs/gst/codecparsers/gstvc1parser.h
new file mode 100644 (file)
index 0000000..e025db9
--- /dev/null
@@ -0,0 +1,641 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __GST_VC1_PARSER_H__
+#define __GST_VC1_PARSER_H__
+
+#ifndef GST_USE_UNSTABLE_API
+#warning "The VC1 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
+
+#define MAX_HRD_NUM_LEAKY_BUCKETS 31
+
+/**
+ * @GST_VC1_BFRACTION_BASIS: The @bfraction variable should be divided
+ * by this constant to have the actual value.
+ */
+#define GST_VC1_BFRACTION_BASIS 840
+
+#define GST_VC1_BFRACTION_RESERVED (GST_VC1_BFRACTION_BASIS + 1)
+#define GST_VC1_BFRACTION_PTYPE_BI (GST_VC1_BFRACTION_BASIS + 2)
+
+typedef enum {
+  GST_VC1_END_OF_SEQ       = 0x0A,
+  GST_VC1_SLICE            = 0x0B,
+  GST_VC1_FIELD            = 0x0C,
+  GST_VC1_FRAME            = 0x0D,
+  GST_VC1_ENTRYPOINT       = 0x0E,
+  GST_VC1_SEQUENCE         = 0x0F,
+  GST_VC1_SLICE_USER       = 0x1B,
+  GST_VC1_FIELD_USER       = 0x1C,
+  GST_VC1_FRAME_USER       = 0x1D,
+  GST_VC1_ENTRY_POINT_USER = 0x1E,
+  GST_VC1_SEQUENCE_USER    = 0x1F
+} GstVC1StartCode;
+
+typedef enum {
+  GST_VC1_PROFILE_SIMPLE,
+  GST_VC1_PROFILE_MAIN,
+  GST_VC1_PROFILE_RESERVED,
+  GST_VC1_PROFILE_ADVANCED
+} GstVC1Profile;
+
+typedef enum {
+  GST_VC1_PARSER_OK,
+  GST_VC1_PARSER_BROKEN_DATA,
+  GST_VC1_PARSER_NO_BDU,
+  GST_VC1_PARSER_NO_BDU_END,
+  GST_VC1_PARSER_ERROR,
+} GstVC1ParserResult;
+
+typedef enum
+{
+  GST_VC1_PICTURE_TYPE_P,
+  GST_VC1_PICTURE_TYPE_B,
+  GST_VC1_PICTURE_TYPE_I,
+  GST_VC1_PICTURE_TYPE_BI,
+  GST_VC1_PICTURE_TYPE_SKIPPED
+} GstVC1PictureType;
+
+typedef enum
+{
+    GST_VC1_LEVEL_LOW    = 0,    /* Simple/Main profile low level */
+    GST_VC1_LEVEL_MEDIUM = 1,    /* Simple/Main profile medium level */
+    GST_VC1_LEVEL_HIGH   = 2,   /* Main profile high level */
+
+    GST_VC1_LEVEL_L0    = 0,    /* Advanced profile level 0 */
+    GST_VC1_LEVEL_L1    = 1,    /* Advanced profile level 1 */
+    GST_VC1_LEVEL_L2    = 2,    /* Advanced profile level 2 */
+    GST_VC1_LEVEL_L3    = 3,    /* Advanced profile level 3 */
+    GST_VC1_LEVEL_L4    = 4,    /* Advanced profile level 4 */
+
+    /* 5 to 7 reserved */
+    GST_VC1_LEVEL_UNKNOWN = 255  /* Unknown profile */
+} GstVC1Level;
+
+typedef enum
+{
+  GST_VC1_QUANTIZER_IMPLICITLY,
+  GST_VC1_QUANTIZER_EXPLICITLY,
+  GST_VC1_QUANTIZER_NON_UNIFORM,
+  GST_VC1_QUANTIZER_UNIFORM
+} GstVC1QuantizerSpec;
+
+typedef enum {
+  GST_VC1_DQPROFILE_FOUR_EDGES,
+  GST_VC1_DQPROFILE_DOUBLE_EDGES,
+  GST_VC1_DQPROFILE_SINGLE_EDGE,
+  GST_VC1_DQPROFILE_ALL_MBS
+} GstVC1DQProfile;
+
+typedef enum {
+  GST_VC1_CONDOVER_NONE,
+  GST_VC1_CONDOVER_ALL,
+  GST_VC1_CONDOVER_SELECT
+} GstVC1Condover;
+
+/**
+ * GstVC1MvMode:
+ *
+ */
+typedef enum
+{
+  GST_VC1_MVMODE_1MV_HPEL_BILINEAR,
+  GST_VC1_MVMODE_1MV,
+  GST_VC1_MVMODE_1MV_HPEL,
+  GST_VC1_MVMODE_MIXED_MV,
+  GST_VC1_MVMODE_INTENSITY_COMP
+} GstVC1MvMode;
+
+typedef enum
+{
+  GST_VC1_FRAME_PROGRESSIVE = 0x0,
+  GST_VC1_FRAME_INTERLACE   = 0x10,
+  GST_VC1_FIELD_INTERLACE   = 0x11
+} GstVC1FrameCodingMode;
+
+typedef struct _GstVC1SeqHdr            GstVC1SeqHdr;
+typedef struct _GstVC1AdvancedSeqHdr    GstVC1AdvancedSeqHdr;
+typedef struct _GstVC1HrdParam          GstVC1HrdParam;
+typedef struct _GstVC1EntryPointHdr     GstVC1EntryPointHdr;
+
+typedef struct _GstVC1SeqLayer     GstVC1SeqLayer;
+
+typedef struct _GstVC1SeqStructA   GstVC1SeqStructA;
+typedef struct _GstVC1SeqStructB   GstVC1SeqStructB;
+typedef struct _GstVC1SeqStructC   GstVC1SeqStructC;
+
+/* Pictures Structures */
+typedef struct _GstVC1FrameLayer        GstVC1FrameLayer;
+typedef struct _GstVC1FrameHdr          GstVC1FrameHdr;
+typedef struct _GstVC1PicAdvanced       GstVC1PicAdvanced;
+typedef struct _GstVC1PicSimpleMain     GstVC1PicSimpleMain;
+typedef struct _GstVC1Picture           GstVC1Picture;
+typedef struct _GstVC1SliceHdr          GstVC1SliceHdr;
+
+typedef struct _GstVC1VopDquant         GstVC1VopDquant;
+
+typedef struct _GstVC1BitPlanes         GstVC1BitPlanes;
+
+typedef struct _GstVC1BDU               GstVC1BDU;
+
+struct _GstVC1HrdParam
+{
+  guint8 hrd_num_leaky_buckets;
+  guint8 bit_rate_exponent;
+  guint8 buffer_size_exponent;
+  guint16 hrd_rate[MAX_HRD_NUM_LEAKY_BUCKETS];
+  guint16 hrd_buffer[MAX_HRD_NUM_LEAKY_BUCKETS];
+};
+
+/**
+ * GstVC1EntryPointHdr:
+ *
+ * Structure for entrypoint header, this will be used only in advanced profiles
+ */
+struct _GstVC1EntryPointHdr
+{
+  guint8 broken_link;
+  guint8 closed_entry;
+  guint8 panscan_flag;
+  guint8 refdist_flag;
+  guint8 loopfilter;
+  guint8 fastuvmc;
+  guint8 extended_mv;
+  guint8 dquant;
+  guint8 vstransform;
+  guint8 overlap;
+  guint8 quantizer;
+  guint8 coded_size_flag;
+  guint16 coded_width;
+  guint16 coded_height;
+  guint8 extended_dmv;
+  guint8 range_mapy_flag;
+  guint8 range_mapy;
+  guint8 range_mapuv_flag;
+  guint8 range_mapuv;
+
+  guint8 hrd_full[MAX_HRD_NUM_LEAKY_BUCKETS];
+};
+
+/**
+ * GstVC1AdvancedSeqHdr:
+ *
+ * Structure for the advanced profile sequence headers specific parameters.
+ */
+struct _GstVC1AdvancedSeqHdr
+{
+  GstVC1Level  level;
+
+  guint8  frmrtq_postproc;
+  guint8  bitrtq_postproc;
+  guint8  postprocflag;
+  guint16 max_coded_width;
+  guint16 max_coded_height;
+  guint8  pulldown;
+  guint8  interlace;
+  guint8  tfcntrflag;
+  guint8  finterpflag;
+  guint8  psf;
+  guint8  display_ext;
+  guint16 disp_horiz_size;
+  guint16 disp_vert_size;
+  guint8  aspect_ratio_flag;
+  guint8  aspect_ratio;
+  guint8  aspect_horiz_size;
+  guint8  aspect_vert_size;
+  guint8  framerate_flag;
+  guint8  framerateind;
+  guint8  frameratenr;
+  guint8  frameratedr;
+  guint16 framerateexp;
+  guint8  color_format_flag;
+  guint8  color_prim;
+  guint8  transfer_char;
+  guint8  matrix_coef;
+  guint8  hrd_param_flag;
+  guint8  colordiff_format;
+
+  GstVC1HrdParam hrd_param;
+
+  /* computed */
+  guint framerate; /* Around in fps, 0 if unknown*/
+  guint bitrate;   /* Around in kpbs, 0 if unknown*/
+  guint par_n;
+  guint par_d;
+  guint fps_n;
+  guint fps_d;
+
+  /* The last parsed entry point */
+  GstVC1EntryPointHdr entrypoint;
+};
+
+struct _GstVC1SeqStructA
+{
+  guint32 vert_size;
+  guint32 horiz_size;
+};
+
+struct _GstVC1SeqStructB
+{
+  GstVC1Level  level;
+
+  guint8 cbr;
+  guint32 framerate;
+
+  /* In simple and main profiles only */
+  guint32 hrd_buffer;
+  guint32 hrd_rate;
+};
+
+struct _GstVC1SeqStructC
+{
+  GstVC1Profile profile;
+
+  /* Only in simple and main profiles */
+  guint8 frmrtq_postproc;
+  guint8 bitrtq_postproc;
+  guint8 res_sprite;
+  guint8 loop_filter;
+  guint8 multires;
+  guint8 fastuvmc;
+  guint8 extended_mv;
+  guint8 dquant;
+  guint8 vstransform;
+  guint8 overlap;
+  guint8 syncmarker;
+  guint8 rangered;
+  guint8 maxbframes;
+  guint8 quantizer;
+  guint8 finterpflag;
+
+  /* Computed */
+  guint framerate; /* Around in fps, 0 if unknown*/
+  guint bitrate;   /* Around in kpbs, 0 if unknown*/
+
+  /* This should be filled by user if previously known */
+  guint16 coded_width;
+  /* This should be filled by user if previously known */
+  guint16 coded_height;
+
+  /* Wmvp specific */
+  guint8 wmvp;          /* Specify if the stream is wmp or not */
+  /* In the wmvp case, the framerate is not computed but in the bistream */
+  guint8 slice_code;
+};
+
+struct _GstVC1SeqLayer
+{
+  guint32 numframes;
+
+  GstVC1SeqStructA struct_a;
+  GstVC1SeqStructB struct_b;
+  GstVC1SeqStructC struct_c;
+};
+
+/**
+ * GstVC1SeqHdr:
+ *
+ * Structure for sequence headers in any profile.
+ */
+struct _GstVC1SeqHdr
+{
+  GstVC1Profile profile;
+
+  GstVC1SeqStructC struct_c;
+
+  /*  calculated */
+  guint mb_height;
+  guint mb_width;
+  guint mb_stride;
+
+  GstVC1AdvancedSeqHdr   advanced;
+
+};
+
+/**
+ * GstVC1PicSimpleMain:
+ * @bfaction: Should be divided by #GST_VC1_BFRACTION_BASIS
+ * to get the real value.
+ */
+struct _GstVC1PicSimpleMain
+{
+  guint8 frmcnt;
+  guint8 mvrange;
+  guint8 rangeredfrm;
+
+  /* I and P pic simple and main profiles only */
+  guint8 respic;
+
+  /* I and BI pic simple and main profiles only */
+  guint8 transacfrm2;
+  guint8 bf;
+
+  /* B and P pic simple and main profiles only */
+  guint8 mvmode;
+  guint8 mvtab;
+  guint8 ttmbf;
+
+  /* P pic simple and main profiles only */
+  guint8 mvmode2;
+  guint8 lumscale;
+  guint8 lumshift;
+
+  guint8 cbptab;
+  guint8 ttfrm;
+
+  /* B and BI picture only
+   * Should be divided by #GST_VC1_BFRACTION_BASIS
+   * to get the real value. */
+  guint16 bfraction;
+
+  /* Biplane value, those fields only mention the fact
+   * that the bitplane is in raw mode or not */
+  guint8 mvtypemb;
+  guint8 skipmb;
+  guint8 directmb; /* B pic main profile only */
+};
+
+/**
+ * GstVC1PicAdvanced:
+ * @bfaction: Should be divided by #GST_VC1_BFRACTION_BASIS
+ * to get the real value.
+ */
+struct _GstVC1PicAdvanced
+{
+  GstVC1FrameCodingMode fcm;
+  guint8  tfcntr;
+
+  guint8  rptfrm;
+  guint8  tff;
+  guint8  rff;
+  guint8  ps_present;
+  guint32 ps_hoffset;
+  guint32 ps_voffset;
+  guint16 ps_width;
+  guint16 ps_height;
+  guint8  rndctrl;
+  guint8  uvsamp;
+  guint8  postproc;
+
+  /*  B and P picture specific */
+  guint8  mvrange;
+  guint8  mvmode;
+  guint8  mvtab;
+  guint8  cbptab;
+  guint8  ttmbf;
+  guint8  ttfrm;
+
+  /* B and BI picture only
+   * Should be divided by #GST_VC1_BFRACTION_BASIS
+   * to get the real value. */
+  guint16 bfraction;
+
+  /* ppic */
+  guint8  mvmode2;
+  guint8  lumscale;
+  guint8  lumshift;
+
+  /* bipic */
+  guint8  bf;
+  guint8  condover;
+  guint8  transacfrm2;
+
+  /* Biplane value, those fields only mention the fact
+   * that the bitplane is in raw mode or not */
+  guint8  acpred;
+  guint8  overflags;
+  guint8  mvtypemb;
+  guint8  skipmb;
+  guint8  directmb;
+  guint8  forwardmb; /* B pic interlace field only */
+
+  /* For interlaced pictures only */
+  guint8  fieldtx;
+
+  /* P and B pictures */
+  guint8  intcomp;
+  guint8  dmvrange;
+  guint8  mbmodetab;
+  guint8  imvtab;
+  guint8  icbptab;
+  guint8  mvbptab2;
+  guint8  mvbptab4; /* If 4mvswitch in ppic */
+
+  /*  P picture */
+  guint8  mvswitch4;
+
+  /* For interlaced fields only */
+  guint16 refdist;
+  guint8 fptype; /* Raw value */
+
+  /* P pic */
+  guint8  numref;
+  guint8  reffield;
+  guint8  lumscale2;
+  guint8  lumshift2;
+  guint8  intcompfield;
+
+};
+
+struct _GstVC1BitPlanes
+{
+  guint8  *acpred;
+  guint8  *fieldtx;
+  guint8  *overflags;
+  guint8  *mvtypemb;
+  guint8  *skipmb;
+  guint8  *directmb;
+  guint8  *forwardmb;
+
+  guint size; /* Size of the arrays */
+};
+
+struct _GstVC1VopDquant
+{
+  guint8 pqdiff;
+  guint8 abspq;
+
+  /* Computed */
+  guint8 altpquant;
+
+  /*  if dqant != 2*/
+  guint8 dquantfrm;
+  guint8 dqprofile;
+
+  /* Boundary edge selection. This represents DQSBEDGE
+   * if dqprofile == GST_VC1_DQPROFILE_SINGLE_EDGE or
+   * DQDBEDGE if dqprofile == GST_VC1_DQPROFILE_DOUBLE_EDGE */
+  guint8 dqbedge;
+
+  /* FIXME: remove */
+  guint8 unused;
+
+  /* if dqprofile == GST_VC1_DQPROFILE_ALL_MBS */
+  guint8 dqbilevel;
+
+};
+
+struct _GstVC1FrameLayer
+{
+  guint8 key;
+  guint32 framesize;
+
+  guint32 timestamp;
+
+  /* calculated */
+  guint32 next_framelayer_offset;
+  guint8 skiped_p_frame;
+};
+
+/**
+ * GstVC1FrameHdr:
+ *
+ * Structure that represent picture in any profile or mode.
+ * You should look at @ptype and @profile to know what is currently
+ * in use.
+ */
+struct _GstVC1FrameHdr
+{
+  /* common fields */
+  GstVC1PictureType ptype;
+  guint8 interpfrm;
+  guint8 halfqp;
+  guint8 transacfrm;
+  guint8 transdctab;
+  guint8 pqindex;
+  guint8 pquantizer;
+
+  /* Computed */
+  guint8 pquant;
+
+  /* Convenience fields */
+  guint8 profile;
+  guint8 dquant;
+
+  /*  If dquant */
+  GstVC1VopDquant vopdquant;
+
+  union {
+    GstVC1PicSimpleMain simple;
+    GstVC1PicAdvanced advanced;
+  } pic;
+
+  /* Size of the picture layer in bits */
+  guint header_size;
+};
+
+/**
+ * GstVC1SliceHdr:
+ *
+ * Structure that represents slice layer in advanced profile.
+ */
+struct _GstVC1SliceHdr
+{
+  guint16 slice_addr;
+
+  /* Size of the slice layer in bits */
+  guint header_size;
+};
+
+/**
+ * GstVC1BDU:
+ *
+ * Structure that represents a Bitstream Data Unit.
+ */
+struct _GstVC1BDU
+{
+  GstVC1StartCode type;
+  guint size;
+  guint sc_offset;
+  guint offset;
+  guint8 * data;
+};
+
+GstVC1ParserResult gst_vc1_identify_next_bdu           (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1BDU *bdu);
+
+
+GstVC1ParserResult gst_vc1_parse_sequence_header       (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1SeqHdr * seqhdr);
+
+GstVC1ParserResult gst_vc1_parse_entry_point_header    (const  guint8 *data,
+                                                        gsize size,
+                                                        GstVC1EntryPointHdr * entrypoint,
+                                                        GstVC1SeqHdr *seqhdr);
+
+GstVC1ParserResult gst_vc1_parse_sequence_layer        (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1SeqLayer * seqlayer);
+
+GstVC1ParserResult
+gst_vc1_parse_sequence_header_struct_a                 (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1SeqStructA *structa);
+GstVC1ParserResult
+gst_vc1_parse_sequence_header_struct_b                 (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1SeqStructB *structb);
+
+GstVC1ParserResult
+gst_vc1_parse_sequence_header_struct_c                 (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1SeqStructC *structc);
+
+GstVC1ParserResult gst_vc1_parse_frame_layer           (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1FrameLayer * framelayer);
+
+GstVC1ParserResult gst_vc1_parse_frame_header          (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1FrameHdr * framehdr,
+                                                        GstVC1SeqHdr *seqhdr,
+                                                        GstVC1BitPlanes *bitplanes);
+
+GstVC1ParserResult gst_vc1_parse_field_header          (const guint8 *data,
+                                                        gsize size,
+                                                        GstVC1FrameHdr * fieldhdr,
+                                                        GstVC1SeqHdr *seqhdr,
+                                                        GstVC1BitPlanes *bitplanes);
+
+GstVC1ParserResult gst_vc1_parse_slice_header           (const guint8 *data,
+                                                         gsize size,
+                                                         GstVC1SliceHdr *slicehdr, 
+                                                         GstVC1SeqHdr *seqhdr);
+
+GstVC1BitPlanes *  gst_vc1_bitplanes_new               (void);
+
+void               gst_vc1_bitplanes_free              (GstVC1BitPlanes *bitplanes);
+
+void               gst_vc1_bitplanes_free_1            (GstVC1BitPlanes *bitplanes);
+
+gboolean           gst_vc1_bitplanes_ensure_size       (GstVC1BitPlanes *bitplanes,
+                                                        GstVC1SeqHdr *seqhdr);
+
+G_END_DECLS
+#endif
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/parserutils.c b/ext/codecparsers/gst-libs/gst/codecparsers/parserutils.c
new file mode 100644 (file)
index 0000000..d4a3f40
--- /dev/null
@@ -0,0 +1,57 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "parserutils.h"
+
+gboolean
+decode_vlc (GstBitReader * br, guint * 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 ("Did not find code");
+
+failed:
+  {
+    GST_WARNING ("Could not decode VLC returning");
+
+    return FALSE;
+  }
+}
diff --git a/ext/codecparsers/gst-libs/gst/codecparsers/parserutils.h b/ext/codecparsers/gst-libs/gst/codecparsers/parserutils.h
new file mode 100644 (file)
index 0000000..6b54ded
--- /dev/null
@@ -0,0 +1,108 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __PARSER_UTILS__
+#define __PARSER_UTILS__
+
+#include <gst/gst.h>
+#include <gst/base/gstbitreader.h>
+
+/* Parsing utils */
+#define GET_BITS(b, num, bits) G_STMT_START {        \
+  if (!gst_bit_reader_get_bits_uint32(b, bits, num)) \
+    goto failed;                                     \
+  GST_TRACE ("parsed %d bits: %d", num, *(bits));    \
+} G_STMT_END
+
+#define CHECK_ALLOWED(val, min, max) G_STMT_START { \
+  if (val < min || val > max) { \
+    GST_WARNING ("value not in allowed range. value: %d, range %d-%d", \
+                     val, min, max); \
+    goto failed; \
+  } \
+} G_STMT_END
+
+#define READ_UINT8(reader, val, nbits) G_STMT_START { \
+  if (!gst_bit_reader_get_bits_uint8 (reader, &val, nbits)) { \
+    GST_WARNING ("failed to read uint8, nbits: %d", nbits); \
+    goto failed; \
+  } \
+} G_STMT_END
+
+#define READ_UINT16(reader, val, nbits) G_STMT_START { \
+  if (!gst_bit_reader_get_bits_uint16 (reader, &val, nbits)) { \
+    GST_WARNING ("failed to read uint16, nbits: %d", nbits); \
+    goto failed; \
+  } \
+} G_STMT_END
+
+#define READ_UINT32(reader, val, nbits) G_STMT_START { \
+  if (!gst_bit_reader_get_bits_uint32 (reader, &val, nbits)) { \
+    GST_WARNING ("failed to read uint32, nbits: %d", nbits); \
+    goto failed; \
+  } \
+} G_STMT_END
+
+#define READ_UINT64(reader, val, nbits) G_STMT_START { \
+  if (!gst_bit_reader_get_bits_uint64 (reader, &val, nbits)) { \
+    GST_WARNING ("failed to read uint64, nbits: %d", nbits); \
+    goto failed; \
+  } \
+} G_STMT_END
+
+
+#define U_READ_UINT8(reader, val, nbits) G_STMT_START { \
+  val = gst_bit_reader_get_bits_uint8_unchecked (reader, nbits); \
+} G_STMT_END
+
+#define U_READ_UINT16(reader, val, nbits) G_STMT_START { \
+  val = gst_bit_reader_get_bits_uint16_unchecked (reader, nbits); \
+} G_STMT_END
+
+#define U_READ_UINT32(reader, val, nbits) G_STMT_START { \
+  val = gst_bit_reader_get_bits_uint32_unchecked (reader, nbits); \
+} G_STMT_END
+
+#define U_READ_UINT64(reader, val, nbits) G_STMT_START { \
+  val = gst_bit_reader_get_bits_uint64_unchecked (reader, nbits); \
+} 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
+
+typedef struct _VLCTable VLCTable;
+
+struct _VLCTable
+{
+  guint value;
+  guint cword;
+  guint cbits;
+};
+
+gboolean
+decode_vlc (GstBitReader * br, guint * res, const VLCTable * table,
+    guint length);
+
+#endif /* __PARSER_UTILS__ */
diff --git a/ext/codecparsers/tests/Makefile.am b/ext/codecparsers/tests/Makefile.am
new file mode 100644 (file)
index 0000000..5591bb6
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = check
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/ext/codecparsers/tests/check/Makefile.am b/ext/codecparsers/tests/check/Makefile.am
new file mode 100644 (file)
index 0000000..d29d457
--- /dev/null
@@ -0,0 +1,4 @@
+SUBDIRS = libs
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/ext/codecparsers/tests/check/libs/.gitignore b/ext/codecparsers/tests/check/libs/.gitignore
new file mode 100644 (file)
index 0000000..238cb3d
--- /dev/null
@@ -0,0 +1,4 @@
+.dirstamp
+h264parser
+mpegvideoparser
+vc1parser
diff --git a/ext/codecparsers/tests/check/libs/Makefile.am b/ext/codecparsers/tests/check/libs/Makefile.am
new file mode 100644 (file)
index 0000000..e034655
--- /dev/null
@@ -0,0 +1,24 @@
+noinst_PROGRAMS = \
+       h264parser      \
+       mpegvideoparser \
+       vc1parser       \
+       $(NULL)
+
+AM_CFLAGS = \
+       -I$(top_srcdir)/gst-libs        \
+       $(GST_PLUGINS_BASE_CFLAGS)      \
+       -DGST_USE_UNSTABLE_API          \
+       $(GST_CHECK_CFLAGS)             \
+       $(GST_BASE_CFLAGS)              \
+       $(GST_CFLAGS)                   \
+       $(NULL)
+
+LDADD = \
+       $(GST_PLUGINS_BASE_LIBS)        \
+       $(GST_CHECK_LIBS)               \
+       $(GST_BASE_LIBS)                \
+       $(GST_LIBS)                     \
+       $(top_builddir)/gst-libs/gst/codecparsers/libgstcodecparsers-$(GST_MAJORMINOR).la
+
+# Extra clean files so that maintainer-clean removes *everything*
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/ext/codecparsers/tests/check/libs/h264parser.c b/ext/codecparsers/tests/check/libs/h264parser.c
new file mode 100644 (file)
index 0000000..285a4f4
--- /dev/null
@@ -0,0 +1,182 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <gst/check/gstcheck.h>
+#include <gst/codecparsers/gsth264parser.h>
+
+static guint8 slice_dpa[] = {
+  0x00, 0x00, 0x01, 0x02, 0x00, 0x02, 0x01, 0x03, 0x00,
+  0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x09, 0x00, 0x0a, 0x00,
+  0x0b, 0x00, 0x0c, 0x00, 0x0d, 0x00, 0x0e, 0x00, 0x0f, 0x00, 0x10, 0x00,
+  0x11, 0x00, 0x12, 0x00, 0x13, 0x00, 0x14, 0x00, 0x15, 0x00, 0x16, 0x00,
+  0x17, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00,
+  0x1d, 0x00, 0x1e, 0x00, 0x1f, 0x00, 0x20, 0x00, 0x21, 0x00, 0x22, 0x00,
+  0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x00, 0x27, 0x00, 0x28, 0x00,
+  0x29, 0x00, 0x2a, 0x00, 0x2b, 0x00, 0x2c, 0x00, 0x2d, 0x00, 0x2e, 0x00,
+  0x2f, 0x00, 0x30, 0x00, 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00,
+  0x35, 0x00, 0x36, 0x00, 0x37, 0x00, 0x38, 0x00, 0x39, 0x00, 0x3a, 0x00,
+  0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, 0x40, 0x00,
+  0x41, 0x00, 0x42, 0x00, 0x43, 0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00,
+  0x47, 0x00, 0x48, 0x00, 0x49, 0x00, 0x4a, 0x00, 0x4b, 0x00, 0x4c, 0x00,
+  0x4d, 0x00, 0x4e, 0x00, 0x4f, 0x00, 0x50, 0x00, 0x51, 0x00, 0x52, 0x00,
+  0x53, 0x00, 0x54, 0x00, 0x55, 0x00, 0x56, 0x00, 0x57, 0x00, 0x58, 0x00,
+  0x59, 0x00, 0x5a, 0x00, 0x5b, 0x00, 0x5c, 0x00, 0x5d, 0x00, 0x5e, 0x00,
+  0x5f, 0x00, 0x60, 0x00, 0x61, 0x01, 0x04, 0x00, 0xc4, 0x00, 0xa6, 0x00,
+  0xc5, 0x00, 0xab, 0x00, 0x82, 0x00, 0xc2, 0x00, 0xd8, 0x00, 0xc6, 0x00,
+  0xe4, 0x00, 0xbe, 0x00, 0xb0, 0x00, 0xe6, 0x00, 0xb6, 0x00, 0xb7, 0x00,
+  0xb4, 0x00, 0xb5, 0x00, 0x87, 0x00, 0xb2, 0x00, 0xb3, 0x00, 0xd9, 0x00,
+  0x8c, 0x00, 0xe5, 0x00, 0xbf, 0x00, 0xb1, 0x00, 0xe7, 0x00, 0xbb, 0x00,
+  0xa3, 0x00, 0x84, 0x00, 0x85, 0x00, 0xbd, 0x00, 0x96, 0x00, 0xe8, 0x00,
+  0x86, 0x00, 0x8e, 0x00, 0x8b, 0x00, 0x9d, 0x00, 0xa9, 0x00, 0x8a, 0x01,
+  0x05, 0x00, 0x83, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0x8d, 0x00, 0x97, 0x00,
+  0x88, 0x00, 0xde, 0x00, 0xf1, 0x00, 0x9e, 0x00, 0xaa, 0x00, 0xf5, 0x00,
+  0xf4, 0x00, 0xf6, 0x00, 0xa2, 0x00, 0xad, 0x00, 0xc9, 0x00, 0xc7, 0x00,
+  0xae, 0x00, 0x62, 0x00, 0x63, 0x00, 0x90, 0x00, 0x64, 0x00, 0xcb, 0x00,
+  0x65, 0x00, 0xc8, 0x00, 0xca, 0x00, 0xcf, 0x00, 0xcc, 0x00, 0xcd, 0x00,
+  0xce, 0x00, 0xe9, 0x00, 0x66, 0x00, 0xd3, 0x00, 0xd0, 0x00, 0xd1, 0x00,
+  0xaf, 0x00, 0x67, 0x00, 0x91, 0x00, 0xd6, 0x00, 0xd4, 0x00, 0xd5, 0x00,
+  0x68, 0x00, 0xeb, 0x00, 0xed, 0x00, 0x89, 0x00, 0x6a, 0x00, 0x69, 0x00,
+  0x6b, 0x00, 0x6d, 0x00, 0x6c, 0x00, 0x6e, 0x00, 0xa0, 0x00, 0x6f, 0x00,
+  0x71, 0x00, 0x70, 0x00, 0x72, 0x00, 0x73, 0x00, 0x75, 0x00, 0x74, 0x00,
+  0x76, 0x00, 0x77, 0x00, 0xea, 0x00, 0x78, 0x00, 0x7a, 0x00, 0x79, 0x00,
+  0x7b, 0x00, 0x7d, 0x00, 0x7c, 0x00, 0xa1, 0x00, 0x7f, 0x00, 0x7e, 0x00,
+  0x80, 0x00, 0x81, 0x00, 0xec, 0x00, 0xee, 0x00, 0xba, 0x01, 0x06, 0x00,
+  0xef, 0x00, 0xe1, 0x00, 0xe0, 0x00, 0xdc, 0x01, 0x07, 0x01, 0x08, 0x01,
+  0x09, 0x01, 0x0a, 0x01, 0x0b, 0x01, 0x0c, 0x00, 0xdb, 0x00, 0xe2, 0x01,
+  0x0d, 0x01, 0x0e, 0x01, 0x0f, 0x01, 0x10, 0x01, 0x11, 0x01, 0x12, 0x00,
+  0xdf, 0x01, 0x13, 0x01, 0x14, 0x01, 0x15, 0x01, 0x16, 0x01, 0x17, 0x00,
+  0xfd, 0x00, 0xff, 0x01, 0x18, 0x01, 0x19, 0x01, 0x1a, 0x01, 0x1b, 0x01,
+  0x1c, 0x01, 0x1d, 0x01, 0x1e, 0x01, 0x1f, 0x01, 0x20, 0x01, 0x21, 0x01,
+  0x22, 0x01, 0x23, 0x01, 0x24, 0x01, 0x25, 0x01, 0x26, 0x00, 0xfe, 0x01,
+  0x00, 0x01, 0x27, 0x01, 0x28, 0x01, 0x29, 0x01, 0x2a, 0x01, 0x2b, 0x01,
+  0x2c, 0x01, 0x2d, 0x01, 0x2e, 0x01, 0x2f, 0x01, 0x30, 0x01, 0x31, 0x00,
+  0xe3, 0x00, 0xd7, 0x01, 0x32, 0x00, 0xf8, 0x00, 0xf9, 0x01, 0x33, 0x01,
+  0x34, 0x01, 0x35, 0x01, 0x36, 0x01, 0x37, 0x01, 0x38, 0x01, 0x39, 0x01,
+  0x3a, 0x01, 0x3b, 0x01, 0x3c, 0x01, 0x3d, 0x01, 0x3e, 0x01, 0x3f, 0x01,
+  0x40, 0x01, 0x41, 0x01, 0x42, 0x01, 0x43, 0x01, 0x44, 0x01, 0x45, 0x01,
+  0x46, 0x01, 0x47, 0x01, 0x48, 0x01, 0x49, 0x01, 0x4a, 0x01, 0x4b, 0x01,
+  0x4c, 0x00, 0x08, 0x05, 0x2e, 0x6e, 0x75, 0x6c, 0x6c, 0x0c, 0x76, 0x69,
+  0x73, 0x69, 0x62, 0x6c, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x04, 0x45,
+  0x75, 0x72, 0x6f, 0x06, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x62,
+  0x75, 0x6c, 0x6c, 0x65, 0x74, 0x6d, 0x61, 0x74, 0x68, 0x06, 0x53, 0x61,
+  0x63, 0x75, 0x74, 0x65, 0x06, 0x54, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06,
+  0x5a, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x73, 0x61, 0x63, 0x75, 0x74,
+  0x65, 0x06, 0x74, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x7a, 0x61, 0x63,
+  0x75, 0x74, 0x65, 0x07, 0x41, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07,
+  0x61, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x0c, 0x73, 0x63, 0x6f, 0x6d,
+  0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x53, 0x63, 0x6f,
+  0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x5a, 0x64,
+  0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x4c, 0x63, 0x61,
+  0x72, 0x6f, 0x6e, 0x06, 0x6c, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x0a, 0x7a,
+  0x64, 0x6f, 0x74, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x52, 0x61,
+  0x63, 0x75, 0x74, 0x65, 0x06, 0x41, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06,
+  0x4c, 0x61, 0x63, 0x75, 0x74, 0x65, 0x07, 0x45, 0x6f, 0x67, 0x6f, 0x6e,
+  0x65, 0x6b, 0x06, 0x45, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x44, 0x63,
+  0x61, 0x72, 0x6f, 0x6e, 0x07, 0x44, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e,
+  0x06, 0x4e, 0x61, 0x63, 0x75, 0x74, 0x65, 0x06, 0x4e, 0x63, 0x61, 0x72,
+  0x6f, 0x6e, 0x0d, 0x4f, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d,
+  0x6c, 0x61, 0x75, 0x74, 0x06, 0x52, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x05,
+  0x55, 0x72, 0x69, 0x6e, 0x67, 0x09, 0x6e, 0x75, 0x6e, 0x67, 0x61, 0x64,
+  0x65, 0x73, 0x68, 0x0d, 0x55, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75,
+  0x6d, 0x6c, 0x61, 0x75, 0x74, 0x0c, 0x54, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x06, 0x72, 0x61, 0x63, 0x75, 0x74,
+  0x65, 0x06, 0x61, 0x62, 0x72, 0x65, 0x76, 0x65, 0x06, 0x6c, 0x61, 0x63,
+  0x75, 0x74, 0x65, 0x07, 0x65, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x06,
+  0x65, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x06, 0x64, 0x63, 0x61, 0x72, 0x6f,
+  0x6e, 0x07, 0x64, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x06, 0x6e, 0x61,
+  0x63, 0x75, 0x74, 0x65, 0x06, 0x6e, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x0d,
+  0x6f, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d, 0x6c, 0x61, 0x75,
+  0x74, 0x06, 0x72, 0x63, 0x61, 0x72, 0x6f, 0x6e, 0x05, 0x75, 0x72, 0x69,
+  0x6e, 0x67, 0x0d, 0x75, 0x68, 0x75, 0x6e, 0x67, 0x61, 0x72, 0x75, 0x6d,
+  0x6c, 0x61, 0x75, 0x74, 0x0c, 0x74, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
+  0x63, 0x63, 0x65, 0x6e, 0x74, 0x0a, 0x49, 0x64, 0x6f, 0x74, 0x61, 0x63,
+  0x63, 0x65, 0x6e, 0x74, 0x0c, 0x52, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
+  0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x72, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x49, 0x6f, 0x67, 0x6f, 0x6e,
+  0x65, 0x6b, 0x07, 0x41, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x45,
+  0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x45, 0x64, 0x6f, 0x74, 0x61,
+  0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x47, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x4b, 0x63, 0x6f, 0x6d, 0x6d,
+  0x61, 0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x49, 0x6d, 0x61, 0x63,
+  0x72, 0x6f, 0x6e, 0x0c, 0x4c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63,
+  0x63, 0x65, 0x6e, 0x74, 0x0c, 0x4e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
+  0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x4f, 0x6d, 0x61, 0x63, 0x72, 0x6f,
+  0x6e, 0x07, 0x55, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x55, 0x6d,
+  0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x69, 0x6f, 0x67, 0x6f, 0x6e, 0x65,
+  0x6b, 0x07, 0x61, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e, 0x07, 0x65, 0x6d,
+  0x61, 0x63, 0x72, 0x6f, 0x6e, 0x0a, 0x65, 0x64, 0x6f, 0x74, 0x61, 0x63,
+  0x63, 0x65, 0x6e, 0x74, 0x0c, 0x67, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61,
+  0x63, 0x63, 0x65, 0x6e, 0x74, 0x0c, 0x6b, 0x63, 0x6f, 0x6d, 0x6d, 0x61,
+  0x61, 0x63, 0x63, 0x65, 0x6e, 0x74, 0x07, 0x69, 0x6d, 0x61, 0x63, 0x72,
+  0x6f, 0x6e, 0x0c, 0x6c, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63, 0x63,
+  0x65, 0x6e, 0x74, 0x0c, 0x6e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x61, 0x63,
+  0x63, 0x65, 0x6e, 0x74, 0x07, 0x6f, 0x6d, 0x61, 0x63, 0x72, 0x6f, 0x6e,
+  0x07, 0x75, 0x6f, 0x67, 0x6f, 0x6e, 0x65, 0x6b, 0x07, 0x75, 0x6d, 0x61,
+  0x63, 0x72, 0x6f, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02
+};
+
+GST_START_TEST (test_h264_parse_slice_dpa)
+{
+  GstH264ParserResult res;
+  GstH264NalUnit nalu;
+
+  GstH264NalParser *parser = gst_h264_nal_parser_new ();
+
+  res = gst_h264_parser_identify_nalu (parser, slice_dpa, 0,
+      sizeof (slice_dpa), &nalu);
+
+  assert_equals_int (res, GST_H264_PARSER_OK);
+  assert_equals_int (nalu.type, GST_H264_NAL_SLICE_DPA);
+
+  gst_h264_nal_parser_free (parser);
+}
+
+GST_END_TEST;
+
+static Suite *
+h264parser_suite (void)
+{
+  Suite *s = suite_create ("H264 Parser library");
+
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_h264_parse_slice_dpa);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = h264parser_suite ();
+
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}
diff --git a/ext/codecparsers/tests/check/libs/mpegvideoparser.c b/ext/codecparsers/tests/check/libs/mpegvideoparser.c
new file mode 100644 (file)
index 0000000..930fbb0
--- /dev/null
@@ -0,0 +1,199 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel Corporation
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include <gst/check/gstcheck.h>
+#include <gst/codecparsers/gstmpegvideoparser.h>
+
+/* actually seq + gop */
+static const guint8 mpeg2_seq[] = {
+  0x00, 0x00, 0x01, 0xb3, 0x02, 0x00, 0x18, 0x15, 0xff, 0xff, 0xe0, 0x28,
+  0x00, 0x00, 0x01, 0xb3, 0x78, 0x04, 0x38, 0x37, 0xff, 0xff, 0xf0, 0x00,
+  0x00, 0x00, 0x01, 0xb5, 0x14, 0x8a, 0x00, 0x11, 0x03, 0x71,
+  0x00, 0x00, 0x01, 0xb8, 0x00, 0x08, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x03, 0x00, 0x08, 0x00, 0x00
+};
+
+static const guint8 mis_identified_datas[] = {
+  0x00, 0x00, 0x01, 0x1f, 0x4a, 0xf4, 0xd4, 0xd8, 0x08, 0x23, 0xdd,
+  0x7c, 0xd3, 0x75, 0x21, 0x43, 0x85, 0x31, 0x43, 0x04, 0x24, 0x30,
+  0x18, 0x43, 0xba, 0x1a, 0x50, 0x60, 0xbb, 0x53, 0x56, 0x80, 0x41,
+  0xb9, 0xd4, 0x25, 0x42, 0xea, 0x71, 0xb7, 0x49, 0x84, 0x0b, 0x14,
+  0x24, 0xc2, 0xaa, 0xba, 0xf9, 0xf7, 0x5b, 0x78, 0xa2, 0xba, 0xd3,
+  0xc7, 0x12, 0xee, 0xbe, 0xba, 0xfa, 0xeb, 0xeb, 0xaf, 0xbe, 0x6f,
+  0xce, 0x92, 0x05, 0x15, 0x22, 0x44, 0xf4, 0xc9, 0x1b, 0xcd, 0x84,
+  0x80, 0x87, 0x35, 0x6c, 0x07, 0x82, 0xaf, 0x3c, 0x3a, 0x89, 0x48,
+  0x3a, 0x26, 0x00, 0x64, 0x03, 0x12, 0x60, 0x03, 0xf4, 0x8c, 0x21,
+  0x16, 0xbe, 0x3c, 0x7c, 0x18, 0x03, 0x10, 0x0c, 0x80, 0xa0, 0x05,
+  0xe1, 0x85, 0x94, 0x90, 0xc4, 0x74, 0x05, 0x72, 0x80, 0x7a, 0x8e,
+  0x3e, 0x00, 0x30,
+  /* The accelerated version of scan_for_start_codes()
+   * mis-identifies the following as a start code */
+  0x01, 0x00, 0x01, 0x80, 0x68, 0x14,
+  0x26, 0xe4, 0x80, 0x98, 0x0a, 0xba, 0x77, 0x01, 0xc2, 0x42, 0x12,
+  0xc4, 0x59, 0x2a, 0xbb, 0x49, 0xf2, 0xc5, 0xa8, 0xd9, 0x30, 0x33,
+  0x16, 0x50, 0x60, 0x61, 0x41, 0xaa, 0x0d, 0x41, 0x5b, 0x17, 0x77,
+  0x76, 0x1a, 0x14, 0x3a, 0x08, 0x19, 0x3d, 0x6c, 0x94, 0x55, 0xd0,
+  0x94, 0x5a, 0xeb, 0x61, 0x22, 0xa7, 0xa6, 0x83, 0x47, 0x6d, 0x4d,
+  0x84, 0xc4, 0x6f, 0x78, 0xd8, 0x3a, 0xb4, 0x02, 0x0c, 0x36, 0xa6,
+  0x0b, 0x18, 0x49, 0xf7, 0xad, 0x00, 0x82, 0x09, 0xba, 0x12, 0xba,
+  0x1d, 0x44, 0x94, 0x0a, 0x1b, 0x03, 0xbb, 0xa2, 0x53, 0x02, 0xc0,
+  0x41, 0xac, 0x22,
+  /* the real start code is here */
+  0x00, 0x00, 0x01, 0x20, 0x4a, 0xfd, 0xf5, 0x50
+};
+
+static GstMpegVideoPacketTypeCode ordercode[] = {
+  GST_MPEG_VIDEO_PACKET_SEQUENCE,
+  GST_MPEG_VIDEO_PACKET_EXTENSION,
+  GST_MPEG_VIDEO_PACKET_GOP,
+};
+
+GST_START_TEST (test_mpeg_parse)
+{
+  gint i, off;
+  GstMpegVideoPacket packet;
+
+  off = 12;
+  for (i = 0; i < 4; ++i) {
+    fail_unless (gst_mpeg_video_parse (&packet, mpeg2_seq, sizeof (mpeg2_seq),
+            off));
+    fail_unless (packet.offset == off + 4);
+    if (i == 3) {
+      fail_unless (GST_MPEG_VIDEO_PACKET_SLICE_MIN <= packet.type &&
+          packet.type <= GST_MPEG_VIDEO_PACKET_SLICE_MAX);
+      fail_unless (packet.size < 0);
+    } else {
+      assert_equals_int (ordercode[i], packet.type);
+    }
+    off = packet.offset + packet.size;
+  }
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_mpeg_parse_sequence_header)
+{
+  GstMpegVideoSequenceHdr seqhdr;
+  GstMpegVideoPacket packet;
+
+  gst_mpeg_video_parse (&packet, mpeg2_seq, sizeof (mpeg2_seq), 12);
+
+  fail_unless (packet.type == GST_MPEG_VIDEO_PACKET_SEQUENCE);
+  fail_unless (gst_mpeg_video_parse_sequence_header (&seqhdr, mpeg2_seq,
+          sizeof (mpeg2_seq), packet.offset));
+  assert_equals_int (seqhdr.width, 1920);
+  assert_equals_int (seqhdr.height, 1080);
+  assert_equals_int (seqhdr.aspect_ratio_info, 3);
+  assert_equals_int (seqhdr.par_w, 64);
+  assert_equals_int (seqhdr.par_h, 45);
+  assert_equals_int (seqhdr.frame_rate_code, 7);
+  assert_equals_int (seqhdr.fps_n, 60000);
+  assert_equals_int (seqhdr.fps_d, 1001);
+  assert_equals_int (seqhdr.bitrate_value, 262143);
+  assert_equals_int (seqhdr.bitrate, 0);
+  assert_equals_int (seqhdr.vbv_buffer_size_value, 512);
+  fail_unless (seqhdr.constrained_parameters_flag == FALSE);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_mpeg_parse_sequence_extension)
+{
+  GstMpegVideoSequenceExt seqext;
+  GstMpegVideoPacket packet;
+
+  gst_mpeg_video_parse (&packet, mpeg2_seq, sizeof (mpeg2_seq), 24);
+
+  fail_unless (packet.type == GST_MPEG_VIDEO_PACKET_EXTENSION);
+  fail_unless (gst_mpeg_video_parse_sequence_extension (&seqext,
+          mpeg2_seq, sizeof (mpeg2_seq), packet.offset));
+  assert_equals_int (seqext.profile, 4);
+  assert_equals_int (seqext.level, 8);
+  assert_equals_int (seqext.progressive, 1);
+  assert_equals_int (seqext.chroma_format, 1);
+  assert_equals_int (seqext.horiz_size_ext, 0);
+  assert_equals_int (seqext.vert_size_ext, 0);
+  assert_equals_int (seqext.vert_size_ext, 0);
+  assert_equals_int (seqext.bitrate_ext, 8);
+  assert_equals_int (seqext.vbv_buffer_size_extension, 3);
+  assert_equals_int (seqext.low_delay, 0);
+  assert_equals_int (seqext.fps_n_ext, 3);
+  assert_equals_int (seqext.fps_d_ext, 2);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_mis_identified_datas)
+{
+  GstMpegVideoPacket packet = { 0, };
+  const guint8 *data = mis_identified_datas;
+  gint i, off;
+
+  off = 0;
+  for (i = 0; i < 2; i++) {
+    gst_mpeg_video_parse (&packet, mis_identified_datas,
+        sizeof (mis_identified_datas), off);
+    assert_equals_int (data[packet.offset - 4], 0);
+    assert_equals_int (data[packet.offset - 3], 0);
+    assert_equals_int (data[packet.offset - 2], 1);
+    off = packet.offset + packet.size;
+    if (i == 1)
+      fail_unless (packet.size < 0);
+    else
+      fail_unless (packet.size > 0);
+  }
+}
+
+GST_END_TEST;
+
+static Suite *
+videoparsers_suite (void)
+{
+  Suite *s = suite_create ("Video Parsers library");
+
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_mpeg_parse);
+  tcase_add_test (tc_chain, test_mpeg_parse_sequence_header);
+  tcase_add_test (tc_chain, test_mpeg_parse_sequence_extension);
+  tcase_add_test (tc_chain, test_mis_identified_datas);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = videoparsers_suite ();
+
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}
diff --git a/ext/codecparsers/tests/check/libs/vc1parser.c b/ext/codecparsers/tests/check/libs/vc1parser.c
new file mode 100644 (file)
index 0000000..e72cf7f
--- /dev/null
@@ -0,0 +1,1240 @@
+/* Gstreamer
+ * Copyright (C) <2011> Intel
+ * Copyright (C) <2011> Collabora Ltd.
+ * Copyright (C) <2011> Thibault Saunier <thibault.saunier@collabora.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+#include <gst/check/gstcheck.h>
+#include <gst/codecparsers/gstvc1parser.h>
+
+static const guint8 sequence_fullframe[] = {
+  0x00, 0x00, 0x01, 0x0f, 0xca, 0x86, 0x13, 0xf0, 0xef, 0x88,
+  0x80, 0x00, 0x00, 0x01, 0x0e, 0x48, 0x3f, 0x4f, 0xc3, 0xbc,
+  0x3f, 0x2b, 0x3f, 0x3c, 0x3f, 0x00, 0x00, 0x01, 0x0d, 0x3f,
+  0x0c, 0x14, 0x27, 0x3f, 0x68, 0x0c, 0x03, 0x3f, 0x3f, 0x55,
+  0x3f, 0x60, 0x71, 0x24, 0x38, 0x28, 0x1b, 0xda, 0xac, 0x01,
+  0x3f, 0x3f, 0x3f, 0x33, 0x3f, 0x61, 0x75, 0x70, 0x3f, 0x3f,
+  0x3f, 0x0d, 0x3f, 0x03, 0x3f, 0x3f, 0x1b, 0x3f, 0x3f, 0x61,
+  0x1a, 0x73, 0x01, 0x26, 0x07, 0x0e, 0x29, 0x3f, 0x1d, 0x68,
+  0xe1, 0xa2, 0x98, 0x59, 0x21, 0x3f, 0x1e, 0x7c, 0x3f, 0x3f,
+  0x3f, 0x65, 0x49, 0x3f, 0x3f, 0x7e, 0x3f, 0x07, 0x6a, 0x0f,
+  0xdb, 0x87, 0x3f, 0x3f, 0x3f, 0x41, 0x3f, 0x3f, 0x77, 0x3f,
+  0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x44, 0x3f, 0x4a, 0x50, 0x53,
+  0x3f, 0x3f, 0x65, 0x3f, 0x2e, 0x3f, 0x3f, 0x3f, 0x08, 0x3f,
+  0x3f, 0x04, 0x5e, 0x11, 0x7d, 0x12, 0x3f, 0x4a, 0x6b, 0x50,
+  0x42, 0x3f, 0x15, 0x3f, 0x3f, 0x61, 0x3f, 0x3f, 0x75, 0x41,
+  0x3f, 0x3f, 0x75, 0x71, 0x3f, 0x3f, 0x3b, 0x3f, 0x0d, 0x3f,
+  0x3f, 0x6e, 0x3f, 0x3f, 0x06, 0x3f, 0x30, 0x08, 0x72, 0x3f,
+  0x3b, 0x3f, 0x67, 0x6e, 0x3f, 0x50, 0x1b, 0x61, 0x5a, 0x20,
+  0x2b, 0x70, 0x3f, 0x2c, 0x22, 0x3f, 0x36, 0x3f, 0x44, 0x40,
+  0x00, 0x00, 0x01, 0x05, 0x3f
+};
+
+static const guint8 pframe_header_main[] = {
+  0x4e, 0x29, 0x1a, 0x11
+};
+
+static const guint8 pframe_main[] = {
+  0x6a, 0x88, 0xbc, 0x1d, 0x40, 0x16, 0x96, 0x90, 0x05, 0x82,
+  0xac, 0x22, 0x88, 0xe0, 0x5d, 0x52, 0xca, 0x85, 0x4c, 0x47,
+  0x9d, 0xc9, 0x25, 0x45, 0x56, 0x99, 0x44, 0x15, 0xa5, 0xc5,
+  0xe1, 0x35, 0x11, 0x72, 0xc1, 0x27, 0x22, 0x6a, 0x08, 0x9a,
+  0x72, 0x4e, 0xe7, 0xa3, 0xf7, 0x23, 0x9d, 0x11, 0x8d, 0xc8,
+  0xe6, 0x4f, 0x46, 0x98, 0xe2, 0x03, 0xcc, 0x6c, 0xe8, 0x77,
+  0xd4, 0x7c, 0xfc, 0x13, 0x39, 0x20, 0x23, 0x03, 0x24, 0xcd,
+  0x15, 0xbf, 0x54, 0x61, 0xf2, 0x25, 0x25, 0xa0, 0x83, 0xa0,
+};
+
+static const guint8 bframe_header_main[] = {
+  0x4e, 0x39, 0x1a, 0x11
+};
+
+static const guint8 bframe_main[] = {
+  0x80, 0xae, 0x01, 0x43, 0x47, 0x6a, 0x9f, 0x53, 0x04, 0x55, 0x2a,
+  0x8b, 0x42, 0x75, 0x8b, 0x35, 0x50, 0xf5, 0x95, 0x56, 0xf2, 0x00,
+  0xe0, 0xa0, 0x60, 0x2c, 0xe8, 0x6b, 0x60, 0x0b, 0x20, 0x00, 0x11,
+  0xf1, 0x51, 0xfe, 0x91, 0x60, 0x6a, 0xe6, 0x12, 0x04, 0x2c, 0xe3,
+  0x07, 0x0a, 0x09, 0x09, 0x12, 0xcb, 0xe1, 0x42, 0x88, 0x10, 0x67,
+  0x80, 0x4c, 0xbf, 0x26, 0x00, 0x82, 0x61, 0x07, 0x21, 0x63, 0x4c,
+  0x0c, 0x32, 0x03, 0x53, 0x19, 0x1b, 0x4d, 0xca, 0xc9, 0xe0, 0xc1,
+  0x6d, 0x32, 0x48, 0xc9, 0xd7, 0xa6, 0x63, 0x4d, 0xeb, 0xd4, 0x1c,
+  0x02, 0x05, 0xfe, 0x57, 0x29, 0x00, 0x58, 0xb0, 0x67, 0x2d, 0x04,
+  0xee, 0x1b, 0xaf, 0x53, 0x40, 0x89, 0xbe, 0xf5, 0x76, 0x20, 0x0b,
+  0x83, 0xc1, 0x88, 0xee, 0x83, 0x94, 0xab, 0x1c, 0x79, 0xdd, 0x44,
+  0xe5, 0x15, 0xae, 0xa5, 0xd3, 0xd5, 0x68, 0x31, 0x3e, 0x5a, 0xa4,
+  0x6b, 0x9e, 0xe3, 0xd2, 0x49, 0x00, 0x1d, 0x6d, 0xeb, 0x0d, 0x6b,
+  0x54, 0xcd, 0xd2, 0xaf, 0x1f, 0x2b, 0xba, 0xf3, 0xd9, 0x4c, 0x71
+};
+
+static const guint8 i_bi_frame_header[] = {
+  0x4e, 0x79, 0x1a, 0x11
+};
+
+static const guint8 biframe_main[] = {
+  0x0f, 0xe0, 0x4c, 0x56, 0x19, 0xdb, 0x40, 0x68, 0xd9, 0x14, 0x2c, 0x92,
+  0x55, 0x1f, 0x59, 0xd5, 0x5b, 0xd8, 0x55, 0x13, 0x19, 0x64, 0x40, 0x2c,
+  0x27, 0x38, 0x71, 0x9d, 0x05, 0x52, 0x02, 0x18, 0x7b, 0x9d, 0x22, 0x88,
+  0x97, 0xaa, 0x54, 0x95, 0x52, 0x49, 0x23, 0x0b, 0x98, 0xee, 0x6c, 0x26,
+  0xe6, 0xff, 0xff, 0x1a, 0x25, 0x15, 0xc3, 0x30, 0x4f, 0x1f, 0xbd, 0xb1,
+  0x09, 0x1b, 0x55, 0x33, 0x6c, 0xcd, 0x8c, 0x11, 0x87, 0x1b, 0x86, 0x02,
+  0x78, 0xfd, 0x69, 0xc1, 0xa2, 0x3b, 0x27, 0x08, 0xc8, 0x63, 0x5f, 0x52,
+  0x10, 0x50, 0xe0, 0xf4, 0x4a, 0xfd, 0x83, 0x30, 0x3f, 0x20, 0x8d, 0x3a,
+  0x88, 0xa0, 0x00, 0x23, 0xd8, 0x51, 0xd0, 0xf6, 0x8c, 0xc4, 0xe8, 0x2d,
+  0x8c, 0x10, 0x13, 0xae, 0xb2, 0xaa, 0xc0, 0x92, 0x68, 0x33, 0x7b, 0x8f,
+  0x63, 0x0e, 0xda, 0x35, 0xc6, 0xa1, 0x11, 0xe6, 0x44, 0xe3, 0xb1, 0x52,
+  0xe9, 0x01, 0x05, 0x93, 0x1a, 0x36, 0x41, 0xf6, 0x62, 0x66, 0x05, 0xfb,
+  0xd6, 0x99, 0x80, 0x8a, 0x97, 0xad, 0xa4, 0x25, 0xec, 0x1a, 0x04, 0xf3,
+  0x0c, 0x9c, 0xe0, 0xea, 0x49, 0xfa, 0x4d, 0x58, 0xc8, 0x1b, 0x63, 0x23,
+  0xdc, 0x07, 0x9d, 0xe9, 0x84, 0x93, 0x12, 0xc8, 0xfc, 0x86, 0x98, 0xb0,
+  0x3d, 0xc8, 0xb4, 0xed, 0x4c, 0x18, 0xbe, 0xd8, 0x38, 0x1b, 0x6d, 0x39,
+  0x90, 0x06, 0x43, 0x75, 0x82, 0x89, 0xc1, 0x6f, 0xf1, 0x12, 0x6d, 0x84,
+  0x54, 0x45, 0x62, 0x2d, 0x00, 0x0a, 0x0e, 0x06, 0xf0, 0x04, 0x06, 0x5a
+};
+
+static const guint8 iframe_main[] = {
+  0x10, 0x04, 0x88, 0x18, 0x1f, 0xdf, 0xe1, 0xe1, 0xde, 0x17, 0x85, 0xe1,
+  0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e,
+  0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85,
+  0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78,
+  0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17,
+  0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1,
+  0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e,
+  0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85,
+  0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78,
+  0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17,
+  0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1,
+  0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e,
+  0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85,
+  0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78, 0x5e, 0x17, 0x85, 0xe1, 0x78
+};
+
+static const guint8 iframe_adv_hdr[] = {
+  0xdb, 0xfe, 0x3b, 0xf2, 0x1b, 0xca, 0x3b, 0xf8, 0x86, 0xf1, 0x80,
+  0xca, 0x02, 0x02, 0x03, 0x09, 0xa5, 0xb8, 0xd7, 0x07, 0xfc
+};
+
+static const guint8 entrypoint[] = {
+  0x5a, 0xc7, 0xfc, 0xef, 0xc8, 0x6c, 0x40
+};
+
+static const guint8 iframe_adv[] = {
+  0x69, 0x1c, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x7f, 0x16, 0x0c, 0x0f, 0x13, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0,
+  0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc,
+  0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f,
+  0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f,
+  0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3,
+  0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0,
+  0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc,
+  0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f,
+  0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f,
+  0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3,
+  0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0,
+  0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc,
+  0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f,
+  0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f,
+  0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3,
+  0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0,
+  0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc,
+  0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f,
+  0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f, 0xc3, 0xf0, 0xfc, 0x3f, 0x0f
+};
+
+static const guint8 bframe_adv[] = {
+  0x46, 0x03, 0x1f, 0xf0, 0x8d, 0xd8, 0xbf, 0xc0, 0xcc, 0x14,
+  0x24, 0xdc, 0x60, 0xe2, 0xa8, 0x5e, 0x0d, 0xff, 0xfc, 0x3b,
+  0x12, 0xfd, 0xe1, 0x2e, 0xd1, 0x84, 0xb0, 0xc2, 0xc4, 0xc1,
+  0x60, 0x20, 0x4a, 0x7c, 0x33, 0xff, 0xf2, 0x10, 0xd8, 0x5c,
+  0xf6, 0x7f, 0xc4, 0xd5, 0x0e, 0x0e, 0x51, 0xa8, 0x57, 0xff,
+  0xfa, 0x43, 0x1f, 0xd0, 0x80, 0xdc, 0x58, 0x02, 0x02, 0xaf,
+  0x10, 0xc6, 0x10, 0x12, 0x80, 0xd8, 0x07, 0xff, 0x9d, 0x00,
+  0x50, 0x51, 0xa8, 0x0a, 0xd3, 0xef, 0x54, 0x03, 0xcb, 0x3f,
+  0xff, 0x2b, 0x8b, 0x21, 0xcb, 0xdb, 0xf1, 0x62, 0x4e, 0x4d,
+  0x8b, 0x03, 0x00, 0x16, 0x53, 0xff, 0xa6, 0x65, 0x12, 0x70,
+  0xe0, 0x3f, 0xf4, 0x85, 0xb8, 0x4b, 0xc6, 0x04, 0x52, 0xff,
+  0xc1, 0xf0, 0x80, 0x39, 0x85, 0x9f, 0xf4, 0xca, 0x91, 0x28,
+  0x10, 0x64, 0x2c, 0xe0, 0xff, 0xff, 0x03, 0x2c, 0x3a, 0xfe,
+  0x03, 0xc3, 0x2d, 0x0e, 0x60, 0x61, 0x80, 0x09, 0x9f, 0xff,
+  0x03, 0x88, 0xc5, 0xd7, 0x9f, 0xfe, 0x1c, 0x14, 0x62, 0xc0,
+  0x62, 0xc1, 0x7f, 0xef, 0x87, 0x7d, 0x6c, 0xbf, 0xf7, 0xc2,
+  0x00, 0x10, 0x59, 0xd7, 0xfc, 0x33, 0x15, 0xbd, 0x35, 0xec,
+  0x17, 0x0b, 0x07, 0x20, 0xd8, 0x42, 0x7e, 0xbf, 0xfc, 0x56,
+  0xdd, 0x1f, 0x9c, 0x3a, 0x70, 0x45, 0x93, 0x01, 0x05, 0x37,
+  0xb7, 0xff, 0x9f, 0x25, 0x5b, 0xb1, 0xbb, 0x87, 0x35, 0x02,
+  0x70, 0x7e, 0x89, 0xb7, 0xf8, 0x5a, 0xb8, 0xb0, 0xb5, 0x04,
+  0x4d, 0x2e, 0x11, 0xb9, 0x74, 0xa1, 0x95, 0xf0, 0x7f, 0x7b,
+  0x38, 0x58, 0x50, 0x61, 0x9f, 0x3f, 0x80, 0x42, 0x7d, 0x15,
+  0x82, 0x00, 0x1d, 0x85, 0x2b, 0x85, 0xf7, 0x14, 0x94, 0x60,
+  0x42, 0x38, 0x28, 0xa8, 0x68, 0x2d, 0x28, 0x31, 0xbc, 0x36,
+  0x48, 0x64, 0xc0, 0x21, 0x56, 0x30, 0xb9, 0xc0, 0x45, 0x90,
+  0xe7, 0x12, 0x83, 0x84, 0xb1, 0x25, 0x86, 0x12, 0x18, 0x2d,
+  0x08, 0xe8, 0x2a, 0x98, 0x8e, 0x0d, 0x00, 0xaa, 0x72, 0x75,
+  0x61, 0x87, 0x00, 0x44, 0x57, 0xd4, 0x26, 0x02, 0x23, 0x90,
+  0xc0, 0x04, 0x90, 0x80, 0x70, 0x46, 0x11, 0xe0, 0x20, 0x26,
+  0x8c, 0x04, 0xa2, 0x88, 0x8e, 0x30, 0xc0, 0x30, 0x60, 0xdf,
+  0xa2, 0xdf, 0x02, 0xd0, 0x01, 0x40, 0x99, 0x4e, 0xa4, 0x7f,
+  0x84, 0x89, 0x63, 0x07, 0x0d, 0x19, 0x1d, 0x6c, 0x88, 0xca,
+  0x1c, 0x1d, 0x07, 0x43, 0xc1, 0x02, 0x9c, 0x60, 0xa3, 0x09,
+  0x0b, 0xc1, 0xfd, 0xa6, 0xa8, 0x21, 0x83, 0x8c, 0x08, 0x49,
+  0x40, 0x56, 0xf9, 0xa6, 0x6a, 0x01, 0x52, 0x0d, 0x0e, 0x12,
+  0xe1, 0x4c, 0xbf, 0x88, 0xe5, 0xa8, 0xb8, 0x02, 0x26, 0x0c,
+  0x24, 0x74, 0x15, 0x38, 0x70, 0x25, 0x30, 0x24, 0x5e, 0xe0,
+  0x22, 0x70, 0x68, 0x96, 0x7f, 0xec, 0x10, 0x23, 0x94, 0x30,
+  0x61, 0x62, 0x38, 0xb0, 0x29, 0x2d, 0x78, 0x21, 0xb3, 0xca,
+  0x40, 0xee, 0x11, 0xa0, 0x6f, 0xf8, 0x07, 0x71, 0x70, 0x47,
+  0xb8, 0x5f, 0x5e, 0x89, 0x6c, 0x31, 0x58, 0x22, 0x0f, 0xff,
+  0xf7, 0x17, 0x00, 0x30, 0x85, 0xf3, 0xc2, 0xb0, 0x55, 0xfe,
+  0xbf, 0xfe, 0x0a, 0x7c, 0x16, 0x07, 0xf0, 0xdb, 0x81, 0xf9,
+  0x40, 0x30, 0x81, 0x84, 0xac, 0x0f, 0xff, 0xe2, 0xb3, 0x4f,
+  0xc3, 0x8d, 0x30, 0x76, 0x9a, 0x33, 0xa0, 0x10, 0x50, 0xc8,
+  0x60, 0xae, 0x2b, 0x22, 0xff, 0xf8, 0xa9, 0x02, 0xf9, 0xf6,
+  0x7a, 0x44, 0x37, 0x69, 0x8b, 0x01, 0x2b, 0x9f, 0xff, 0x81,
+  0x60, 0x7a, 0xb9, 0x01, 0x0b, 0x27, 0x70, 0x40, 0xa1, 0x50,
+  0x60, 0xa4, 0x61, 0xa1, 0x66, 0x30, 0x91, 0x55, 0x6f, 0xff,
+  0xe6, 0x0d, 0x14, 0xae, 0xc8, 0x1a, 0x2c, 0x23, 0x4c, 0xc9,
+  0x94, 0x4c, 0x07, 0x61, 0x0d, 0x46, 0x63, 0x89, 0xca, 0xbf,
+  0xff, 0xea, 0x27, 0x0c, 0x30, 0x1e, 0x66, 0x1c, 0x13, 0x50,
+  0xb0, 0xd8, 0x34, 0x02, 0x14, 0x30, 0x01, 0x54, 0x6a, 0xbf,
+  0xff, 0x97, 0xa2, 0x3a, 0x83, 0x85, 0x04, 0x8a, 0xc2, 0x60,
+  0xc0, 0x85, 0x57, 0x71, 0x61, 0x45, 0x22, 0x01, 0x07, 0x00,
+  0x22, 0xff, 0xfb, 0x5b, 0xf1, 0x80, 0x8b, 0x46, 0x81, 0x68,
+  0x02, 0xe2, 0x71, 0x00, 0x11, 0x81, 0x86, 0x2f, 0xff, 0xf7,
+  0x5f, 0xdd, 0x42, 0x06, 0x03, 0x38, 0xb4, 0x01, 0xf6, 0xc0,
+  0xff, 0xc7, 0xfb, 0xb8, 0x15, 0x0b, 0xfc, 0x1c, 0x09, 0x86,
+  0x18, 0x30, 0x34, 0x15, 0x9c, 0x6a, 0x55, 0xff, 0xff, 0xbf,
+  0xe2, 0xc0, 0xc3, 0x86, 0xe2, 0x38, 0x18, 0xb3, 0x14, 0x81,
+  0xc0, 0x06, 0x04, 0xc2, 0x98, 0xb0, 0x12, 0x7f, 0xff, 0x8c,
+  0x06, 0xbf, 0x71, 0x85, 0x0c, 0x08, 0x47, 0x11, 0x87, 0xa0,
+  0xa4, 0xe0, 0x63, 0x0a, 0x0c, 0xae, 0x0a, 0xbf, 0xfe, 0xe0,
+  0x78, 0xb0, 0x13, 0xb8, 0x20, 0xc3, 0x5d, 0xc5, 0x21, 0x44,
+  0x82, 0x48, 0x00, 0x18, 0x24, 0x54, 0x00, 0x03, 0x5c, 0x1b,
+  0xff, 0xc3, 0x9a, 0x16, 0x30, 0xb1, 0x85, 0x07, 0x38, 0xc8,
+  0x59, 0x20, 0x81, 0x4c, 0x56, 0x75, 0x27, 0x0d, 0x08, 0x71,
+  0x58, 0x47, 0x0e, 0x12, 0x85, 0x81, 0x61, 0xbf, 0xfc, 0x5a,
+  0x4a, 0x0c, 0x28, 0x56, 0x20, 0x03, 0x14, 0x63, 0x0a, 0x2a,
+  0x45, 0x80, 0xd1, 0x38, 0x28, 0x68, 0x32, 0x27, 0xa2, 0x05,
+  0xff, 0xf7, 0x03, 0xe2, 0x30, 0x3c, 0x56, 0x61, 0x4e, 0x30,
+  0x18, 0xad, 0x80, 0xdc, 0x15, 0x04, 0xa7, 0x0c, 0x18, 0x30,
+  0x10, 0x38, 0x62, 0xff, 0xe1, 0x87, 0x3c, 0x20, 0x60, 0x63,
+  0x0a, 0x02, 0x29, 0xf0, 0xc2, 0xa4, 0x2c, 0x04, 0x66, 0x2b,
+  0x02, 0x72, 0xff, 0xce, 0x07, 0xd0, 0x10, 0x0e, 0x13, 0xc5,
+  0x22, 0xc3, 0x02, 0x96, 0x10, 0x33, 0x18, 0x08, 0x1e, 0xe7,
+  0xff, 0x9f, 0xd0, 0x61, 0xb9, 0x0a, 0xdf, 0xdc, 0x83, 0x85,
+  0x61, 0x38, 0x61, 0x69, 0x24, 0x12, 0x7f, 0xf0, 0x3a, 0x73,
+  0x03, 0x09, 0x87, 0x7c, 0x30, 0xb8, 0x58, 0x9c, 0x18, 0x30,
+  0x05, 0xd0, 0x4c, 0xff, 0xcb, 0xe3, 0x86, 0x14, 0x5a, 0xc3,
+  0x0b, 0x8a, 0xd7, 0x05, 0x15, 0x06, 0x0a, 0x00, 0x50, 0x78,
+  0x93, 0xff, 0x7f, 0xc6, 0xc5, 0x97, 0xf0, 0x97, 0x18, 0x70,
+  0x71, 0x8c, 0x14, 0x58, 0x03, 0xb4, 0x61, 0xa0, 0x7f, 0xef,
+  0xae, 0x18, 0x29, 0x84, 0xee, 0xbf, 0x88, 0xa0, 0x33, 0x0e,
+  0x11, 0x41, 0xfc, 0xff, 0xf1, 0xa8, 0xda, 0x1c, 0xa1, 0x81,
+  0x05, 0x8a, 0x9f, 0xf1, 0x2c, 0x30, 0x55, 0x18, 0x40, 0xc2,
+  0x7d, 0x8b, 0xf7, 0x8a, 0x80, 0x42, 0x58, 0x94, 0x30, 0x51,
+  0x1c, 0x00, 0x83, 0x08, 0x4b, 0x3e, 0x1c, 0x1b, 0xe2, 0xb0,
+  0x4b, 0x06, 0x03, 0x32, 0xa8, 0xc0, 0xc6, 0x08, 0xb5, 0x6c,
+  0x02, 0xa6, 0x00, 0x22, 0xa0, 0xd8, 0x53, 0x1a, 0x0c, 0x0d,
+  0x78, 0x97, 0x8c, 0x1c, 0x60, 0xa2, 0x5e, 0xc3, 0x21, 0x86,
+  0x8c, 0x0c, 0x55, 0x41, 0x28, 0x46, 0x1b, 0x82, 0x35, 0x85,
+  0x4e, 0x03, 0xc1, 0x62, 0x31, 0x8b, 0x83, 0x0b, 0x18, 0x54,
+  0x30, 0xbc, 0x1c, 0x38, 0x13, 0x02, 0x08, 0x03, 0x18, 0x08,
+  0x86, 0x1a, 0x36, 0x09, 0x33, 0x15, 0x1d, 0x00, 0x0b, 0xf0,
+  0xc1, 0x60, 0x2c, 0x0c, 0x58, 0x13, 0x01, 0xc6, 0x0e, 0xa2,
+  0xc7, 0x87, 0x0b, 0x3e, 0x16, 0x40, 0x22, 0x88, 0xb8, 0x27,
+  0x11, 0x07, 0x07, 0x04, 0xf4, 0xfb, 0x84, 0x30, 0x8e, 0x08,
+  0x30, 0xb2, 0x18, 0x08, 0xd8, 0x53, 0xf8, 0x8a, 0x5f, 0x15,
+  0x86, 0x10, 0x1b, 0x54, 0x03, 0x11, 0x40, 0x3f, 0xe8, 0x30,
+  0x84, 0x15, 0x02, 0xc4, 0x61, 0x44, 0x61, 0x62, 0xe1, 0x7f,
+  0xba, 0x84, 0xe1, 0x03, 0x0b, 0x1a, 0x02, 0x2c, 0xcb, 0xfc,
+  0x39, 0xc2, 0x4c, 0x26, 0x36, 0x18, 0x68, 0x19, 0x5d, 0x7f,
+  0x49, 0x5c, 0x61, 0xc2, 0xd0, 0xa7, 0x42, 0xfe, 0xeb, 0x9a,
+  0x01, 0x10, 0x10, 0x9c, 0x2b, 0x46, 0x00, 0x08, 0x91, 0x60,
+  0x61, 0x5f, 0x1a, 0x0a, 0xce, 0x2c, 0x0b, 0x30, 0xc2, 0xff,
+  0x41, 0x1f, 0xf8, 0xc0, 0x23, 0x03, 0x18, 0x69, 0x62, 0x58,
+  0x0f, 0xe0, 0x43, 0x02, 0x11, 0x85, 0x21, 0x84, 0xf7, 0xff,
+  0xb7, 0xc6, 0x14, 0x50, 0xc1, 0x0c, 0x66, 0xa1, 0x2e, 0xb0,
+  0xc0, 0xa5, 0xd0, 0xcc, 0xc6, 0x15, 0xa8, 0xa5, 0xfc, 0x38,
+  0x4b, 0x00, 0xe1, 0xc0, 0x25, 0xc4, 0x54, 0x09, 0x14, 0x50,
+  0x4b, 0xd2, 0x25, 0xc5, 0x68, 0xac, 0x2a, 0x04, 0xe2, 0x90,
+  0x27, 0xf1, 0x2f, 0xdc, 0x61, 0x67, 0xe2, 0x32, 0x0d, 0xc0,
+  0x80, 0xe2, 0xb6, 0x2b, 0x0d, 0x8a, 0x18, 0x30, 0x51, 0x4a,
+  0xbb, 0xff, 0xfc, 0x4e, 0xfc, 0x6a, 0xa2, 0xb0, 0x97, 0x0e,
+  0x75, 0x0c, 0x21, 0x82, 0x06, 0x8b, 0x11, 0x86, 0x8c, 0x38,
+  0x2c, 0x0c, 0x5a, 0x97, 0xff, 0x83, 0x17, 0x87, 0x20, 0x96,
+  0x29, 0x05, 0x8a, 0xc6, 0x10, 0x2b, 0x38, 0x20, 0xc0, 0x06,
+  0xc0, 0x82, 0xc0, 0xc8, 0x60, 0x4a, 0x1a, 0xd1, 0xaf, 0xff,
+  0xb8, 0xc3, 0x38, 0x43, 0x04, 0x8a, 0x31, 0x81, 0x0a, 0x30,
+  0x81, 0x86, 0x8c, 0x2c, 0x08, 0x5c, 0x18, 0x00, 0x0b, 0x82,
+  0x84, 0x60, 0x0e, 0x07, 0xff, 0xf1, 0x2f, 0x0c, 0x13, 0x40,
+  0x84, 0xe5, 0x41, 0x58, 0x1d, 0xf1, 0x90, 0x70, 0x94, 0x30,
+  0xa6, 0x02, 0x82, 0x90, 0xb5, 0x81, 0xff, 0xfc, 0xf1, 0xbe,
+  0x60, 0x4c, 0x18, 0x30, 0xe1, 0x84, 0x0a, 0x50, 0x21, 0x80,
+  0x90, 0xb0, 0x2d, 0x30, 0xb4, 0x34, 0x04, 0x11, 0x6f, 0xff,
+  0xf8, 0x5c, 0x61, 0x45, 0xe0, 0x40, 0x22, 0x30, 0xaa, 0x18,
+  0x30, 0x41, 0x2c, 0x60, 0xc3, 0x09, 0x11, 0xe8, 0x42, 0x30,
+  0x8e, 0x04, 0x0c, 0x2b, 0x7f, 0xfe, 0x80, 0x45, 0xf8, 0x8e,
+  0x23, 0x0d, 0xc3, 0x81, 0x04, 0x51, 0x14, 0x0f, 0xe2, 0x1a, 0x10,
+  0x07, 0xf2, 0x48, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x29, 0x96,
+  0x00, 0x00, 0x00, 0x08, 0x00, 0x92, 0x03, 0x42, 0x1e, 0xc1,
+  0x80, 0xba, 0x03, 0x54, 0x13, 0xe6, 0x88, 0xc0, 0xb6, 0x28,
+  0x30, 0x39, 0x08, 0x01, 0x48, 0x53, 0x16, 0x03, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x07, 0x81, 0x00, 0x00,
+  0x00, 0x50, 0x2b, 0x0a, 0x42, 0x50, 0x45, 0x85, 0x4e, 0x08,
+  0x64, 0x0c, 0x58, 0x86, 0x30, 0x06, 0x06, 0x70, 0x24, 0x00,
+  0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x44, 0xb6, 0x1f, 0xe4, 0xb6, 0x31, 0x25, 0x43, 0xb1, 0x87,
+  0xc1, 0x11, 0x86, 0xa1, 0x10, 0xe4, 0x3d, 0x5e, 0x1c, 0x42,
+  0xe9, 0x64, 0xb9, 0x6b, 0x80, 0x29, 0x85, 0xdb, 0xc3, 0x4c,
+  0x52, 0xb0, 0x84, 0x86, 0x88, 0x0c, 0x00, 0x02, 0x43, 0xb3,
+  0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00,
+  0x0a, 0x26, 0x8a, 0x1e, 0x82, 0x98, 0x07, 0x01, 0x51, 0x85,
+  0x80, 0x42, 0x11, 0x8f, 0xd2, 0x30, 0xbf, 0x0a, 0x09, 0xcb,
+  0x45, 0x10, 0x98, 0x78, 0x18, 0xe0, 0xf8, 0xf4, 0x2d, 0x01,
+  0x80, 0xc0, 0x60, 0x30, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x01, 0xd8, 0x24, 0x00, 0x14, 0x87, 0xe0, 0x11, 0x01, 0xc1,
+  0x2a, 0x07, 0x07, 0x01, 0x81, 0xa1, 0x9e, 0x74, 0x38, 0x1c,
+  0x0e, 0x04, 0x2c, 0x21, 0x84, 0x02, 0xd4, 0x31, 0x00, 0xa8,
+  0x82, 0x36, 0x30, 0xc8, 0xe4, 0x0c, 0x32, 0xbb, 0x8a, 0xb7,
+  0x00, 0x98, 0x08, 0x2e, 0x61, 0xec, 0x00, 0x4a, 0x60, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0xbf, 0xf8, 0x04, 0x03, 0x40, 0x00,
+  0x45, 0xe9, 0x40, 0x40, 0xd2, 0x0a, 0x84, 0x78, 0xf4, 0x66,
+  0xf8, 0x4a, 0x92, 0x82, 0x4c, 0xc9, 0xd0, 0x12, 0xb4, 0x68,
+  0x83, 0x27, 0xb0, 0x36, 0x02, 0x80, 0x98, 0x09, 0x84, 0xe1,
+  0x60, 0x0c, 0x0d, 0x03, 0x74, 0x0b, 0x86, 0x40, 0x1e, 0x89,
+  0xf0, 0x1f, 0x81, 0x4e, 0x00, 0x2b, 0xf0, 0x04, 0x80, 0x00,
+  0x00, 0x00, 0x00, 0x03, 0x78, 0x00, 0x00, 0x09, 0x96, 0x24,
+  0x09, 0x0d, 0x14, 0x03, 0x87, 0x80, 0xe8, 0x54, 0x09, 0x0f,
+  0xf4, 0x09, 0x33, 0x9e, 0xd0, 0x4e, 0x0c, 0x31, 0x80, 0x41,
+  0x84, 0x98, 0xe3, 0xc1, 0x88, 0x27, 0xa0, 0xd2, 0x0a, 0x90,
+  0x66, 0x4b, 0x0d, 0xc0, 0xac, 0x61, 0x97, 0x9c, 0x12, 0x1b,
+  0xec, 0x51, 0x5c, 0x48, 0xa2, 0x9e, 0x1d, 0x03, 0x12, 0x03,
+  0x0c, 0xe4, 0x53, 0xb2, 0x80, 0x1c, 0xe2, 0xc2, 0xc0, 0x00,
+  0x00, 0x00, 0x00, 0x05, 0x60, 0x01, 0x57, 0x04, 0x86, 0x48,
+  0x04, 0xf9, 0x01, 0x20, 0x2e, 0x15, 0x94, 0x01, 0x0e, 0xf2,
+  0x9f, 0x40, 0x51, 0x6c, 0x0d, 0x06, 0x24, 0x50, 0x48, 0x00,
+  0x83, 0x65, 0x05, 0x67, 0x25, 0x36, 0x7a, 0x26, 0x83, 0xd1,
+  0x9e, 0xc2, 0x7f, 0x40, 0xd0, 0x2a, 0x14, 0x26, 0xb8, 0xac,
+  0x64, 0x86, 0xd8, 0x47, 0x84, 0x89, 0x4e, 0x79, 0xc8, 0x21,
+  0x4c, 0x24, 0x17, 0xa6, 0x6a, 0x51, 0x32, 0x6b, 0x93, 0x20,
+  0xa1, 0x72, 0x65, 0x97, 0x77, 0x03, 0x18, 0x88, 0x41, 0xe0,
+  0x88, 0x40, 0x21, 0x4e, 0xb6, 0x05, 0x60, 0x02, 0x40, 0x00,
+  0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x8f, 0x03, 0x44, 0xc0,
+  0x23, 0x20, 0x06, 0x88, 0x32, 0x16, 0x19, 0xc2, 0xc9, 0x79,
+  0xf4, 0xd9, 0x3d, 0x32, 0x22, 0xc9, 0x4e, 0x41, 0x80, 0x4c,
+  0x34, 0x0b, 0x31, 0x82, 0x19, 0x80, 0x93, 0x3c, 0xf2, 0x04,
+  0xa4, 0x39, 0x21, 0x8c, 0xd6, 0x12, 0x40, 0x80, 0x84, 0x1a,
+  0x6e, 0xe3, 0x09, 0xe8, 0x4c, 0x1a, 0x00, 0xe0, 0x49, 0xa8,
+  0x02, 0xb2, 0x31, 0x06, 0x60, 0xf8, 0x28, 0x11, 0x68, 0x24,
+  0x14, 0x82, 0xfc, 0x82, 0xf9, 0x82, 0x07, 0x48, 0xab, 0x25,
+  0xca, 0x0e, 0x44, 0x6a, 0x28, 0x24, 0x28, 0x54, 0x1a, 0x80,
+  0x44, 0x46, 0x80, 0xa4, 0x63, 0x2e, 0x02, 0x90, 0x00, 0x00,
+  0x00, 0x00, 0x00, 0x01, 0x21, 0xbf, 0xc1, 0xa0, 0x78, 0x2c,
+  0xc5, 0xde, 0x80, 0xc0, 0x4c, 0x22, 0x22, 0x53, 0x01, 0xc8,
+  0x38, 0x18, 0x42, 0xbb, 0x05, 0xb3, 0x26, 0xc0, 0xf6, 0x4b,
+  0x01, 0xd0, 0x12, 0x01, 0xac, 0x0f, 0x18, 0x73, 0x6d, 0x2c,
+  0x8c, 0x85, 0x28, 0x4c, 0x90, 0x80, 0x10, 0x82, 0x5d, 0x50,
+  0x13, 0xd6, 0x34, 0xc8, 0x08, 0x4b, 0x09, 0x86, 0x64, 0x06,
+  0xb3, 0xdd, 0xa6, 0x4b, 0xd2, 0x6c, 0x97, 0x27, 0xf0, 0x8d,
+  0x45, 0xd1, 0x81, 0xc2, 0x0c, 0x2e, 0x44, 0x98, 0xe1, 0x26,
+  0xbd, 0xaa, 0x12, 0x6b, 0xfb, 0x80, 0x90, 0xdc, 0x42, 0x16,
+  0xdf, 0xd4, 0xd4, 0x08, 0x5c, 0xa3, 0x75, 0xbc, 0x82, 0x09,
+  0x83, 0x01, 0x81, 0x70, 0xbb, 0x30, 0xb4, 0x41, 0x4c, 0x68,
+  0x30, 0x29, 0x02, 0x82, 0x1f, 0x0c, 0x71, 0x40, 0x00, 0x00,
+  0x00, 0x00, 0x07, 0x83, 0x80, 0x18, 0x06, 0x10, 0x47, 0x43,
+  0xb0, 0x48, 0x81, 0xa0, 0x13, 0x6d, 0x9c, 0x84, 0xc5, 0xd9,
+  0x85, 0x6e, 0x15, 0x79, 0x5c, 0xc5, 0x32, 0xf8, 0x51, 0x31,
+  0x96, 0x2e, 0x00, 0x01, 0x05, 0xc0, 0x92, 0x89, 0x08, 0x60,
+  0x9b, 0x32, 0x58, 0x25, 0xad, 0xc0, 0x8a, 0x18, 0x66, 0x43,
+  0x58, 0x51, 0xb0, 0x11, 0x08, 0x94, 0x01, 0x22, 0x5b, 0xe0,
+  0x4c, 0x84, 0x14, 0x80, 0x4a, 0x9c, 0x02, 0x8a, 0x00, 0x38,
+  0xe1, 0xf5, 0x3b, 0x20, 0x21, 0x28, 0x1e, 0x0b, 0xd8, 0x80,
+  0x81, 0x8a, 0x89, 0x64, 0xb1, 0x2f, 0xe3, 0x30, 0x2d, 0xd4,
+  0x20, 0x08, 0x43, 0xf1, 0x19, 0x0a, 0x85, 0x9e, 0xb2, 0xd0,
+  0x00, 0x54, 0x56, 0x50, 0x2c, 0x04, 0x80, 0xee, 0x0e, 0x8a,
+  0x54, 0x29, 0x10, 0xa5, 0x82, 0xfb, 0x82, 0xc3, 0x80, 0x10,
+  0x04, 0x00, 0x00, 0x00, 0x00, 0x01, 0x37, 0xf0, 0x00, 0x01,
+  0xeb, 0x59, 0x3d, 0x83, 0x21, 0x41, 0xf6, 0xdd, 0x22, 0xc9,
+  0x72, 0x6c, 0x8a, 0xc1, 0x04, 0x9a, 0x5b, 0x94, 0x12, 0x1e,
+  0x5a, 0x09, 0x11, 0x2c, 0x0a, 0x2d, 0x05, 0x6b, 0x57, 0x64,
+  0xcc, 0x34, 0x47, 0x00, 0x88, 0x2a, 0xa0, 0x7a, 0x41, 0x8b,
+  0xb2, 0x88, 0x20, 0x9b, 0xf0, 0x24, 0x40, 0x46, 0x09, 0x54,
+  0xe0, 0x68, 0x27, 0xf0, 0x09, 0x68, 0x80, 0xb4, 0x23, 0x53,
+  0x38, 0x84, 0x1f, 0x02, 0x6d, 0x62, 0x05, 0x78, 0x49, 0x98,
+  0x0e, 0x18, 0xc6, 0x43, 0x20, 0x21, 0x02, 0x0a, 0x44, 0x64,
+  0x1c, 0x1d, 0x04, 0xa0, 0xc8, 0x07, 0x07, 0xe1, 0x28, 0xa6,
+  0x6c, 0x37, 0xc5, 0x51, 0x86, 0xdd, 0x00, 0xbd, 0x00, 0x00,
+  0x00, 0x00, 0x01, 0x2b, 0x80, 0x01, 0xb3, 0x13, 0xe8, 0x76,
+  0x09, 0xea, 0x04, 0x23, 0x0b, 0x21, 0x01, 0x02, 0x18, 0x07,
+  0x00, 0x8c, 0xd2, 0x0d, 0x64, 0xc8, 0x1b, 0x09, 0x30, 0x48,
+  0xa5, 0x97, 0x0d, 0x20, 0xa0, 0x91, 0x27, 0x08, 0x32, 0x41,
+  0x56, 0x04, 0x99, 0xcf, 0x20, 0x4a, 0x09, 0xb8, 0x86, 0x49,
+  0x19, 0xc0, 0x48, 0xd4, 0xf3, 0x82, 0xae, 0x38, 0x63, 0x04,
+  0x26, 0x16, 0x1e, 0x30, 0xd7, 0x4c, 0x80, 0x12, 0x50, 0xfd,
+  0x92, 0xe2, 0x03, 0x9f, 0x40, 0x2b, 0x67, 0x38, 0x16, 0x17,
+  0x4f, 0xf9, 0x76, 0xaf, 0x09, 0x8b, 0xb9, 0x84, 0x00, 0x02,
+  0x8f, 0x2c, 0x00, 0x5d, 0x03, 0x50, 0x00, 0x42, 0x13, 0x06,
+  0x60, 0x96, 0xc3, 0xd0, 0x00, 0x3c, 0x10, 0xc0, 0x4e, 0x02,
+  0x00, 0x04, 0xe0, 0xf0, 0x23, 0x60, 0x00, 0x00, 0x00, 0x00,
+  0x24, 0x1b, 0xe0, 0x00, 0x04, 0x02, 0xe9, 0x4c, 0x97, 0x26,
+  0x40, 0x70, 0x24, 0x3b, 0x50, 0xb6, 0x40, 0x54, 0x41, 0x26,
+  0x79, 0xa4, 0x94, 0xbc, 0xc5, 0x97, 0x18, 0x61, 0x88, 0x2e,
+  0x70, 0x22, 0x62, 0x3c, 0x02, 0x05, 0x80, 0x90, 0xea, 0x06,
+  0x68, 0xf4, 0xb2, 0x66, 0x06, 0x09, 0x33, 0x07, 0x54, 0x83,
+  0x64, 0xcc, 0x28, 0xc1, 0x60, 0xba, 0x08, 0x8d, 0x1a, 0xf1,
+  0xa0, 0x84, 0x85, 0x81, 0x94, 0x23, 0x06, 0x2f, 0x22, 0xb2,
+};
+
+static const guint8 bframe2_adv[] = {
+  0x46, 0x88, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+  0x03, 0xf8, 0xa1, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+  0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
+};
+
+static const guint8 pframe_adv[] = {
+  0x24, 0x20, 0x04, 0xbf, 0x85, 0x88, 0x65, 0xc1, 0x00, 0xdc,
+  0x4c, 0x06, 0xce, 0x05, 0x01, 0x01, 0x41, 0x0c, 0x60, 0x42,
+  0x67, 0xff, 0xfb, 0x85, 0x0b, 0x9c, 0x56, 0x0d, 0x0b, 0x1b,
+  0x8c, 0x08, 0x08, 0x47, 0x1b, 0xce, 0xc1, 0x83, 0x09, 0x8a,
+  0xa1, 0x83, 0x09, 0x16, 0x7f, 0xff, 0x98, 0x94, 0xff, 0x81,
+  0x4f, 0xf9, 0x41, 0xe1, 0x83, 0x01, 0xff, 0xff, 0x14, 0x40,
+  0xcd, 0x70, 0xd7, 0xf2, 0xf7, 0xc1, 0xf1, 0x18, 0x59, 0xff,
+  0xfc, 0x51, 0x18, 0x68, 0x2c, 0xd4, 0x54, 0x16, 0xbf, 0xfe,
+  0x0c, 0xf1, 0x81, 0x28, 0x67, 0xff, 0x86, 0x39, 0x05, 0xe6,
+  0x5f, 0xff, 0xe0, 0x48, 0xc0, 0xff, 0xfe, 0x61, 0x18, 0x37,
+  0xff, 0x97, 0xdc, 0x1c, 0x45, 0x06, 0x06, 0xff, 0xf0, 0x30,
+  0x7d, 0x17, 0xff, 0xff, 0x86, 0x07, 0x03, 0xff, 0xf9, 0x01,
+  0xf0, 0x7f, 0xff, 0xdf, 0xc1, 0x20, 0x9f, 0xfd, 0x0c, 0x0f,
+  0x86, 0x7f, 0xff, 0xee, 0x50, 0xef, 0xfe, 0xc1, 0xa5, 0xc6,
+  0x1b, 0xff, 0xff, 0x86, 0x61, 0x9f, 0xfc, 0x1c, 0x1f, 0xa2,
+  0xff, 0xff, 0xe0, 0xf8, 0x10, 0x1f, 0xfe, 0x0e, 0x0f, 0x99,
+  0x95, 0xff, 0xff, 0xb8, 0x3e, 0xe5, 0xff, 0x81, 0x83, 0xe1,
+  0x6b, 0xff, 0xff, 0x40, 0xc0, 0x7c, 0x30, 0xbf, 0xe0, 0xb2,
+  0x0e, 0x09, 0x61, 0x53, 0xff, 0xfd, 0x60, 0x20, 0xfc, 0x27,
+  0xf0, 0x96, 0x51, 0x26, 0x6c, 0xcf, 0xff, 0xff, 0xe7, 0x60,
+  0xe0, 0xb5, 0xee, 0x82, 0xa0, 0xb8, 0x41, 0x32, 0x3f, 0x2f,
+  0xcd, 0x3f, 0xa0, 0xa8, 0x96, 0x8e, 0x2a, 0x4c, 0x08, 0x6e,
+  0x36, 0x1a, 0x83, 0x2a, 0x8b, 0x02, 0xcb, 0x2f, 0xff, 0xe9,
+  0xf8, 0xa4, 0x0e, 0x00, 0x12, 0xc1, 0x88, 0xc3, 0x0c, 0x05,
+  0x51, 0x44, 0x61, 0xa3, 0x0b, 0x18, 0x58, 0x38, 0x70, 0x97,
+  0xff, 0xff, 0xf8, 0x8c, 0x14, 0x2c, 0x0c, 0x19, 0x86, 0x0c,
+  0x27, 0x09, 0xc1, 0x03, 0x08, 0x62, 0xc0, 0xff, 0xff, 0xfe,
+  0x94, 0x6d, 0x22, 0x77, 0xc0, 0x44, 0x71, 0x1c, 0x60, 0xe5,
+  0xb7, 0xff, 0xfe, 0xbf, 0xba, 0x57, 0x82, 0x0c, 0x24, 0xc8,
+  0x5a, 0xbf, 0xff, 0xff, 0xcb, 0x14, 0xc8, 0x30, 0x43, 0x16,
+  0x29, 0x51, 0x86, 0x0b, 0x00, 0x51, 0x60, 0x60, 0xc0, 0x17,
+  0x75, 0xff, 0xf9, 0x77, 0x0e, 0x18, 0x4b, 0x84, 0xc5, 0x47,
+  0x11, 0xc5, 0x10, 0x68, 0x1b, 0x8c, 0x00, 0x6a, 0x71, 0x60,
+  0xc0, 0x46, 0xe2, 0xe0, 0x22, 0x65, 0xff, 0xd6, 0x09, 0x0e,
+  0x01, 0x15, 0x55, 0x85, 0x48, 0x28, 0x8f, 0xc2, 0x42, 0x06,
+  0x1c, 0x23, 0x8b, 0x01, 0x42, 0x74, 0x08, 0x61, 0x9f, 0xff,
+  0xc2, 0xca, 0x19, 0x81, 0x02, 0x10, 0x20, 0xc0, 0x1c, 0x5c,
+  0x13, 0x84, 0xe6, 0x1a, 0x8b, 0x02, 0x38, 0x98, 0x09, 0x98,
+  0xa3, 0xff, 0xfd, 0xc9, 0x05, 0x5e, 0x82, 0x18, 0xc1, 0x40,
+  0xc6, 0xf6, 0x04, 0x14, 0x40, 0x60, 0x80, 0xfd, 0x04, 0x6f,
+  0xff, 0xf4, 0x58, 0x0a, 0xf8, 0x86, 0x30, 0x02, 0x14, 0x44,
+  0xe2, 0xc2, 0x43, 0x3c, 0x1b, 0xff, 0x86, 0xb5, 0x66, 0x16,
+  0xf0, 0x7f, 0xa0, 0x9c, 0x5e, 0x84, 0x07, 0xd1, 0x73, 0xff,
+  0xee, 0x88, 0xc2, 0xe1, 0x7f, 0xfc, 0xc0, 0xf0, 0x59, 0x65,
+  0xfe, 0x9f, 0x70, 0xbf, 0xff, 0xdc, 0x1e, 0x2a, 0x02, 0x57,
+  0xff, 0xc0, 0x26, 0x2d, 0x3c, 0x4d, 0x5f, 0xff, 0xc4, 0xc1,
+  0x30, 0x11, 0x15, 0xc4, 0xaf, 0xfc, 0x5c, 0x0e, 0x0e, 0x0e,
+  0x84, 0x8c, 0x34, 0x34, 0xbf, 0xff, 0x11, 0x81, 0x30, 0x10,
+  0x48, 0x87, 0xf9, 0x43, 0x05, 0x25, 0x04, 0x11, 0x43, 0x70,
+  0x4f, 0xff, 0xfd, 0x04, 0xe1, 0x0e, 0xfe, 0x6f, 0x83, 0x88,
+  0xe1, 0x98, 0x76, 0x0f, 0xfc, 0x89, 0x0e, 0xe7, 0xc2, 0x78,
+  0x4c, 0x24, 0xd4, 0x18, 0x8c, 0xbf, 0x27, 0x16, 0xd0, 0xb0,
+  0xc9, 0xf4, 0x12, 0x6a, 0x08, 0xe4, 0x5c, 0x24, 0xbf, 0x46,
+  0x60, 0xf6, 0x53, 0xf5, 0x6c, 0xff, 0x2e, 0x32, 0x09, 0x1e,
+  0xab, 0x09, 0x00, 0x1e, 0x88, 0x56, 0x6e, 0x7a, 0x1c, 0xd0,
+  0x30, 0x3c, 0xab, 0xf0, 0x44, 0x5a, 0x90, 0x4f, 0x9a, 0xf0,
+  0xe6, 0x7d, 0x62, 0xc1, 0x87, 0x4b, 0xdb, 0xfd, 0x68, 0xd9,
+  0x35, 0x3b, 0x01, 0x04, 0x81, 0x2c, 0x24, 0xee, 0xb3, 0x9b,
+  0x65, 0x30, 0x49, 0x20, 0xa8, 0x08, 0xf6, 0xaf, 0x33, 0x80,
+  0x38, 0x49, 0xa3, 0x94, 0x6e, 0x35, 0x06, 0x4d, 0xc3, 0x30,
+  0x92, 0x7c, 0x3c, 0x6b, 0x9e, 0xd5, 0x31, 0x4d, 0x69, 0x87,
+  0x2e, 0x04, 0x7e, 0x04, 0x12, 0x5f, 0xa3, 0x0a, 0xe4, 0x5b,
+  0x21, 0x6c, 0x45, 0x54, 0x29, 0x11, 0x48, 0x8a, 0xa8, 0x52,
+  0x22, 0xa8, 0x33, 0x06, 0xe0, 0xbd, 0xe8, 0x41, 0x00, 0x03,
+  0x52, 0xe7, 0x00, 0x7d, 0xf0, 0x42, 0x4d, 0x0f, 0x20, 0x26,
+  0x24, 0x09, 0xbb, 0x48, 0x1c, 0xeb, 0xa5, 0xa2, 0x0e, 0xed,
+  0x11, 0x66, 0x97, 0x93, 0xb8, 0x4a, 0x70, 0x8a, 0x75, 0x38,
+  0x47, 0xc1, 0x26, 0x3e, 0x50, 0x87, 0x33, 0xf2, 0x37, 0xc7,
+  0x3b, 0x67, 0x09, 0x33, 0x44, 0xfc, 0xcd, 0xda, 0x19, 0xa6,
+  0x3f, 0x27, 0xec, 0x24, 0x12, 0x64, 0x06, 0x13, 0xdd, 0x9e,
+  0x81, 0x92, 0x17, 0x5f, 0xb3, 0xd9, 0x37, 0xf2, 0x0f, 0x15,
+  0x00, 0x87, 0xb3, 0xe6, 0xc9, 0xc1, 0xbc, 0x24, 0x7f, 0x0f,
+  0x7c, 0x76, 0x4c, 0xe0, 0xfb, 0xf7, 0x66, 0x4c, 0x9c, 0x19,
+  0x32, 0x6f, 0xb2, 0x64, 0xfa, 0x00, 0x01, 0x26, 0xaa, 0xa4,
+  0x16, 0x45, 0x1f, 0x94, 0xee, 0xde, 0x33, 0x09, 0x2e, 0x48,
+  0xc2, 0x4b, 0xf4, 0x62, 0x91, 0x16, 0x00, 0x52, 0x20, 0xe2,
+  0xba, 0xe2, 0x35, 0x42, 0xa7, 0xa0, 0x9c, 0x9e, 0xcc, 0x39,
+  0x9d, 0x31, 0x00, 0xc3, 0xe0, 0x2a, 0x1f, 0x85, 0x61, 0xd3,
+  0x63, 0x3f, 0x22, 0xa8, 0xd9, 0xc1, 0x50, 0x50, 0x2f, 0x21,
+  0xb1, 0xd8, 0x49, 0x34, 0xa0, 0xb0, 0x0c, 0x7d, 0xe9, 0x53,
+  0x27, 0x09, 0xf9, 0x1b, 0x33, 0x5d, 0x93, 0xb8, 0x48, 0x89,
+  0xbb, 0x18, 0x4e, 0xf0, 0x44, 0x86, 0x13, 0x7a, 0x16, 0xc4,
+  0x36, 0xc7, 0x24, 0xe2, 0x39, 0x20, 0x20, 0x62, 0xb0, 0xf1,
+  0xa0, 0x21, 0xc7, 0x2a, 0xdf, 0xd6, 0xd1, 0x5e, 0xcf, 0xba,
+  0x09, 0x92, 0xa4, 0xb7, 0xd6, 0x7b, 0x0b, 0xaa, 0x60, 0xe7,
+  0x8c, 0xe2, 0xfb, 0xf8, 0xb1, 0x96, 0x70, 0xc5, 0xf7, 0x3d,
+  0x7a, 0xce, 0x13, 0x09, 0x0f, 0xd4, 0x2c, 0xfe, 0x30, 0xdd,
+  0xdc, 0x11, 0xb1, 0x4e, 0xab, 0x98, 0x0d, 0x45, 0xf0, 0x41,
+  0x9d, 0x0c, 0xd6, 0xa1, 0x8e, 0x5c, 0xf4, 0xdf, 0x93, 0x88,
+  0x3f, 0x23, 0x61, 0x23, 0x6e, 0xf4, 0x78, 0xac, 0xfa, 0x00,
+  0x00, 0x07, 0x1f, 0x94, 0xe9, 0x13, 0xd3, 0x05, 0x61, 0x99,
+  0x22, 0x49, 0xf8, 0x6d, 0xb9, 0xb3, 0x83, 0xa6, 0x70, 0x78,
+  0xf3, 0x37, 0x54, 0xdf, 0xb6, 0x82, 0x67, 0x07, 0x3d, 0x66,
+  0xea, 0x86, 0x72, 0xd3, 0x38, 0x3b, 0x0a, 0xcd, 0xd5, 0x0e,
+  0x00, 0x07, 0x19, 0x6d, 0x92, 0x77, 0x3e, 0x0d, 0xba, 0x66,
+  0xa6, 0x8c, 0x8d, 0x48, 0xf2, 0xe2, 0x38, 0x31, 0x7f, 0x71,
+  0xf9, 0xe8, 0x6c, 0x46, 0xb1, 0x91, 0xc5, 0x6a, 0xbb, 0x16,
+  0x36, 0x44, 0xb3, 0x67, 0x64, 0xcf, 0xee, 0xcc, 0x04, 0x61,
+  0x7b, 0x91, 0x7e, 0xcd, 0x47, 0x27, 0x16, 0x0f, 0x04, 0x8f,
+  0x02, 0x84, 0x8f, 0x85, 0xb5, 0xb3, 0x5a, 0x81, 0x23, 0xa8,
+};
+
+static const guint8 pframe2_adv[] = {
+  0x1c, 0x22, 0x1f, 0xdc, 0x9d, 0x3b, 0x81, 0x61, 0x85, 0x2,
+  0x57, 0xa0, 0x50, 0xac, 0x03, 0x81, 0x0c, 0x39, 0x4f, 0xff,
+  0xc2, 0x20, 0x9f, 0xf4, 0x86, 0x16, 0x8e, 0xe1, 0xda, 0x0c,
+  0x24, 0x4b, 0x3f, 0xff, 0x03, 0x77, 0xfe, 0x05, 0x10, 0xc5,
+  0x81, 0x3a, 0x50, 0x71, 0x4c, 0x56, 0x10, 0xfa, 0x06, 0x82,
+  0xaf, 0xfe, 0x19, 0x49, 0x17, 0xb6, 0x42, 0xad, 0xf0, 0xe8,
+  0x6f, 0xc0, 0x97, 0xff, 0x83, 0xd0, 0xce, 0x15, 0x16, 0x85,
+  0xa6, 0x77, 0x09, 0xb3, 0xe1, 0x88, 0x30, 0xd0, 0x0f, 0x18,
+  0x60, 0x40, 0x5f, 0xfe, 0x07, 0x6f, 0x6c, 0x18, 0x09, 0xdf,
+  0xc3, 0x00, 0xee, 0x98, 0x39, 0x8b, 0x40, 0xff, 0xf8, 0x64,
+  0xfb, 0xae, 0xae, 0x25, 0xc1, 0x61, 0xa1, 0xa1, 0x63, 0x06,
+  0xba, 0xb8, 0x9a, 0x00, 0xe6, 0x40, 0x75, 0xff, 0x08, 0xfc,
+  0xa2, 0x88, 0xa2, 0xf7, 0xd4, 0x47, 0xe2, 0x8b, 0x20, 0x11,
+  0x02, 0xe0, 0xc1, 0x80, 0xdf, 0xe0, 0xff, 0xe2, 0x18, 0xe0,
+  0x40, 0x42, 0xe0, 0xc0, 0x82, 0x59, 0x49, 0x9c, 0x4c, 0x60,
+  0x95, 0x86, 0x60, 0xff, 0xf8, 0x22, 0x7d, 0x21, 0xa1, 0x62,
+  0x60, 0xc0, 0x06, 0x06, 0x30, 0x90, 0xa0, 0xc1, 0xbb, 0xa0,
+  0x10, 0x8e, 0xcf, 0xca, 0x17, 0x4f, 0xf0, 0x34, 0xfb, 0x00,
+  0x88, 0xe0, 0xa3, 0x07, 0x04, 0x18, 0x30, 0xe2, 0xc8, 0x50,
+  0xb4, 0x14, 0xac, 0x12, 0x9d, 0x30, 0xcf, 0xfb, 0x97, 0xeb,
+  0x42, 0x14, 0x83, 0x45, 0x30, 0x31, 0x70, 0x4d, 0x14, 0xc5,
+  0x10, 0x51, 0x4c, 0x61, 0x21, 0x4f, 0xf8, 0x1d, 0x7f, 0x0c,
+  0xf8, 0x30, 0x1e, 0xa3, 0x00, 0x08, 0x0b, 0x15, 0x46, 0x0a,
+  0x0a, 0x26, 0x87, 0x02, 0x06, 0x0a, 0xa3, 0x0a, 0x54, 0x18,
+  0x62, 0x80, 0x70, 0x3f, 0xf0, 0xcf, 0xe6, 0x0e, 0x1a, 0x82,
+  0x34, 0x30, 0x59, 0x14, 0xc6, 0xa3, 0x04, 0x18, 0x70, 0xc1,
+  0x82, 0xc6, 0x05, 0x21, 0x27, 0xe0, 0x7f, 0xe1, 0x8d, 0xae,
+  0x91, 0x6a, 0x1c, 0x04, 0x30, 0x00, 0xc1, 0xba, 0x90, 0x59,
+  0x89, 0xda, 0xd4, 0x61, 0x8b, 0xc1, 0xfe, 0xda, 0x8c, 0x30,
+  0xa0, 0x3d, 0xa3, 0x06, 0x0d, 0x01, 0x85, 0x08, 0x6e, 0x16,
+  0x04, 0x30, 0x01, 0x30, 0x51, 0x06, 0x15, 0x1a, 0x03, 0xe2,
+  0xd5, 0xeb, 0xa1, 0x98, 0x2d, 0x02, 0x97, 0x77, 0x57, 0x16,
+  0x05, 0x61, 0x14, 0x92, 0x32, 0x50, 0x01, 0x4c, 0x46, 0x18,
+  0x40, 0x97, 0x9a, 0x0a, 0x97, 0x70, 0xaf, 0x84, 0x84, 0xbd,
+  0x7a, 0x45, 0x60, 0xa1, 0x14, 0x47, 0x17, 0x06, 0x00, 0x30,
+  0x29, 0x44, 0x51, 0x24, 0x60, 0x62, 0x30, 0x15, 0x08, 0x19,
+  0xda, 0xa2, 0x32, 0x06, 0x81, 0xf0, 0x0c, 0x30, 0x43, 0xeb,
+  0x00, 0x06, 0x40, 0x60, 0x40, 0xb0, 0xe1, 0x68, 0x34, 0x0c,
+  0x04, 0x6e, 0x29, 0x08, 0xc3, 0x01, 0x1b, 0x06, 0xe0, 0x00,
+  0x37, 0x55, 0x03, 0xdc, 0x0e, 0xea, 0x04, 0xb2, 0xda, 0x09,
+  0x21, 0x54, 0x60, 0xa2, 0x5d, 0x86, 0x02, 0x22, 0x81, 0x80,
+  0x0b, 0x44, 0x82, 0x3d, 0x04, 0x71, 0x4a, 0x10, 0x11, 0xfc,
+  0x61, 0x04, 0xc0, 0x5b, 0x01, 0x00, 0x46, 0x12, 0x07, 0x11,
+  0x83, 0x05, 0x31, 0x24, 0x4a, 0x0c, 0x09, 0x04, 0x15, 0x00,
+  0xd0, 0xdc, 0x0f, 0xd3, 0xfd, 0xc5, 0x86, 0x38, 0x5f, 0x85,
+  0xc0, 0x42, 0xc2, 0x48, 0x61, 0x20, 0x41, 0x62, 0x48, 0xb0,
+  0x0a, 0x49, 0x60, 0xb8, 0x96, 0xef, 0xad, 0xba, 0x60, 0x23,
+  0x88, 0xa2, 0x39, 0x60, 0xa8, 0x23, 0x86, 0x8d, 0x02, 0x81,
+  0x86, 0x18, 0x30, 0x23, 0x13, 0x42, 0xa3, 0x5b, 0x38, 0x14,
+  0x20, 0x5a, 0x18, 0x4a, 0xae, 0x68, 0x8d, 0x4a, 0x8c, 0x00,
+  0x51, 0x0e, 0x63, 0x18, 0x10, 0x9a, 0x0c, 0x70, 0x41, 0x38,
+  0x46, 0x21, 0x18, 0x25, 0x00, 0x50, 0x95, 0xb8, 0x38, 0x75,
+  0xe1, 0xab, 0xe8, 0xa2, 0x3f, 0x18, 0x77, 0xb9, 0xc5, 0x81,
+  0x86, 0x0b, 0x2a, 0x21, 0x8c, 0x08, 0x2e, 0x2a, 0x0a, 0xa4,
+  0x10, 0xd8, 0x58, 0x3e, 0x80, 0x25, 0x09, 0xcf, 0x47, 0x16,
+  0xb9, 0x8a, 0x8e, 0x26, 0x0a, 0x76, 0x51, 0x18, 0x80, 0x19,
+  0xa8, 0x0c, 0x9e, 0x5f, 0x6f, 0xd8, 0x59, 0xf7, 0x05, 0x13,
+  0x14, 0x53, 0x30, 0x40, 0xa5, 0x04, 0x55, 0xb1, 0x00, 0x55,
+  0x74, 0xf9, 0x83, 0xd4, 0xf1, 0x37, 0xee, 0x16, 0x32, 0x12,
+  0xf4, 0x14, 0xc8, 0x4b, 0x30, 0xd4, 0x02, 0x92, 0x80, 0x61,
+  0x02, 0x88, 0x94, 0xbf, 0xf8, 0x18, 0xc3, 0x97, 0xe5, 0x58,
+  0xa8, 0x35, 0x98, 0x1a, 0xc1, 0x41, 0xd4, 0x19, 0xc6, 0x18,
+  0x48, 0xb0, 0xbf, 0xfc, 0x1c, 0x56, 0x6e, 0x13, 0xcc, 0x04,
+  0x4b, 0x07, 0x27, 0x55, 0x2f, 0x7d, 0x44, 0x61, 0x65, 0x3f,
+  0xf0, 0xc0, 0xc0, 0xab, 0x89, 0x83, 0x0d, 0x67, 0x16, 0x00,
+  0xc8, 0xa1, 0x84, 0x41, 0x95, 0x33, 0xb8, 0x2e, 0x18, 0x25,
+  0xff, 0xf8, 0x18, 0x96, 0xa2, 0xc0, 0x18, 0x58, 0x06, 0x3a,
+  0xbf, 0xc1, 0x96, 0xed, 0x10, 0xc4, 0x98, 0xc0, 0x46, 0x13,
+  0xff, 0xe1, 0x63, 0x03, 0x17, 0x01, 0x6e, 0x74, 0x06, 0x70,
+  0x2a, 0x6a, 0xb3, 0x74, 0x07, 0x61, 0x58, 0x2c, 0x2d, 0xbf,
+  0xfd, 0x01, 0x42, 0x30, 0x85, 0xfb, 0xc6, 0x1a, 0x0a, 0x14,
+  0x2c, 0x5c, 0x08, 0xbc, 0x43, 0x2f, 0xc2, 0x5f, 0x72, 0x8b,
+  0x9c, 0x32, 0x06, 0x0a, 0x27, 0x03, 0x50, 0x61, 0x5f, 0x41,
+  0x4e, 0x19, 0x83, 0xff, 0xfb, 0x42, 0x3e, 0x6e, 0x34, 0x12,
+  0x7f, 0x75, 0x18, 0x04, 0x1f, 0x06, 0x86, 0x7f, 0xf9, 0x44,
+  0x97, 0xee, 0x0d, 0xe9, 0xf2, 0x38, 0x3e, 0xf8, 0x37, 0xfe,
+  0x98, 0x1c, 0xd6, 0x30, 0x11, 0x2f, 0xff, 0xe0, 0x76, 0x50,
+  0x38, 0x5f, 0xfe, 0x70, 0xc4, 0x29, 0x0b, 0x82, 0x2f, 0xff,
+  0xe0, 0x62, 0x48, 0xc3, 0x85, 0x10, 0xa1, 0x69, 0x17, 0xfe,
+  0x50, 0xc8, 0x5f, 0x4f, 0xff, 0xfc, 0x30, 0xa0, 0x7f, 0xe9,
+  0x0c, 0x00, 0xc2, 0x7f, 0xff, 0xf9, 0x0a, 0x82, 0x56, 0x0d,
+  0xfe, 0xd0, 0x8e, 0xff, 0xff, 0xfd, 0x04, 0x64, 0x58, 0x5f,
+  0xfe, 0x0f, 0xdc, 0x5a, 0xff, 0xff, 0xe0, 0x9c, 0x33, 0xfd,
+  0x60, 0x7c, 0x38, 0x0f, 0xff, 0xff, 0x81, 0xf8, 0x1f, 0xfc,
+  0x0f, 0x82, 0x7f, 0xff, 0xe8, 0xe5, 0x3c, 0x0f, 0xf7, 0xc0,
+  0xf8, 0xc3, 0x17, 0xff, 0xff, 0x13, 0x37, 0xc1, 0xbf, 0xe0,
+  0x70, 0xcc, 0xbf, 0xff, 0xf1, 0x85, 0xfc, 0x1f, 0xfe, 0x07,
+  0x83, 0x2f, 0xff, 0xff, 0x1b, 0x7c, 0x1f, 0xfd, 0x42, 0x94,
+  0x36, 0x9f, 0xff, 0xfc, 0x1f, 0xe0, 0xfd, 0x99, 0x86, 0x02,
+  0x1a, 0x29, 0x81, 0x21, 0x7f, 0xff, 0xfc, 0x83, 0x95, 0x85,
+  0x11, 0x60, 0x60, 0x22, 0xc8, 0xd0, 0xc2, 0xc4, 0xb5, 0x83,
+  0x95, 0x27, 0xa7, 0xff, 0xfc, 0x85, 0x85, 0xb4, 0x47, 0x24,
+  0x18, 0x28, 0xaa, 0x1a, 0x23, 0x2a, 0x84, 0xdb, 0xff, 0xff,
+  0xf2, 0x63, 0x92, 0xc4, 0xc0, 0x21, 0xc0, 0xc2, 0xc0, 0x00,
+  0x82, 0xc6, 0x00, 0x28, 0x89, 0x72, 0xff, 0xff, 0xef, 0x16,
+  0x05, 0x11, 0x1c, 0x61, 0x22, 0x38, 0x50, 0xb8, 0x2a, 0xbb,
+  0x9c, 0xe7, 0xcf, 0xff, 0xff, 0xe6, 0x30, 0xce, 0x0f, 0xc0,
+  0x04, 0x71, 0x1d, 0xff, 0xff, 0xff, 0xfb, 0xb7, 0x07, 0xe1,
+  0x21, 0x82, 0xc0, 0x87, 0x6b, 0xb7, 0xff, 0xff, 0xf7, 0x0c,
+  0x10, 0xc5, 0x85, 0x40, 0x96, 0x12, 0x58, 0xe1, 0xc1, 0x5d,
+  0xff, 0xff, 0xfb, 0x89, 0xcb, 0x84, 0x30, 0x9c, 0x2a, 0xc5,
+  0x41, 0x64, 0x5a, 0xee, 0x0d, 0x8a, 0x61, 0x4b, 0xff, 0xff,
+  0x0c, 0xc0, 0x86, 0x10, 0x23, 0x8a, 0x42, 0xe3, 0x0a, 0xc0,
+  0x23, 0x07, 0x14, 0x6e, 0x2c, 0x09, 0x4e, 0x2c, 0x05, 0x82,
+  0x01, 0x02, 0x2f, 0xff, 0xf4, 0x07, 0xb0, 0x8d, 0x02, 0x09,
+  0x14, 0x45, 0x81, 0x86, 0xb8, 0x10, 0xb0, 0x27, 0x00, 0x30,
+  0xaa, 0x21, 0x85, 0x80, 0x5c, 0x56, 0x2f, 0xff, 0xf0, 0x7a,
+  0x0c, 0x01, 0x68, 0x14, 0x08, 0x1a, 0x82, 0x3d, 0xc2, 0xc4,
+  0xe0, 0x60, 0xc0, 0x0e, 0x30, 0x10, 0x6f, 0xff, 0xf4, 0x5b,
+  0x8b, 0x3e, 0x30, 0x92, 0x70, 0xc1, 0x86, 0x80, 0x48, 0x33,
+  0xc0, 0x82, 0xc5, 0x8f, 0xff, 0xf0, 0xb7, 0x88, 0xed, 0xf1,
+  0x85, 0x80, 0x7c, 0x1b, 0xa0, 0x9d, 0xff, 0xfe, 0x51, 0x47,
+  0x45, 0xff, 0x94, 0x2f, 0x0c, 0x15, 0x46, 0xff, 0xff, 0xd3,
+  0x0c, 0x58, 0x67, 0xfe, 0x74, 0x57, 0x11, 0x80, 0xc6, 0x14,
+  0xe2, 0xc0, 0xa9, 0xff, 0x9d, 0xd4, 0x34, 0x61, 0xc2, 0x5a,
+  0x09, 0x7f, 0xfa, 0x60, 0xc0, 0x80, 0x8c, 0x6e, 0x62, 0x6a,
+  0xff, 0xc4, 0x50, 0x3c, 0x86, 0x1a, 0x70, 0x3f, 0xfe, 0x0d,
+  0x8b, 0x90, 0xc7, 0x04, 0x10, 0xd7, 0xfe, 0x10, 0x00, 0x28,
+  0x82, 0x0b, 0x01, 0xc3, 0x0a, 0x84, 0x7f, 0xfb, 0xc2, 0x36,
+  0x10, 0xf3, 0xf5, 0xe1, 0x64, 0x80, 0x88, 0x0e, 0x29, 0x94,
+  0x1f, 0xf2, 0x49, 0xcf, 0xc9, 0xe4, 0xf3, 0xf2, 0x79, 0x3c,
+  0xfc, 0x9e, 0x4f, 0x3f, 0x27, 0x93, 0xcf, 0xc9, 0xe4, 0xf3,
+  0xf2, 0x79, 0x3c, 0xe2, 0x2f, 0xc9, 0xc9, 0x5c, 0x62, 0x09,
+  0x32, 0x51, 0x20, 0x69, 0x21, 0xa1, 0x4e, 0xe0, 0x60, 0x79,
+  0xcd, 0x39, 0x96, 0x2a, 0x12, 0x65, 0x1b, 0x59, 0x45, 0x60,
+  0x94, 0x98, 0x24, 0xd4, 0x4e, 0xc1, 0xf0, 0x48, 0x73, 0xbd,
+  0xf8, 0xce, 0xd1, 0x9d, 0x6f, 0x70, 0xcc, 0x91, 0x08, 0xc2,
+  0x4e, 0x77, 0x92, 0x21, 0x18, 0x49, 0xd0, 0xf7, 0x47, 0x21,
+  0x08, 0xc2, 0x4e, 0x87, 0x92, 0x21, 0x18, 0x48, 0x90, 0xba,
+  0x67, 0x43, 0xf2, 0x44, 0x58, 0x24, 0xe7, 0x79, 0x2b, 0xbe,
+  0x78, 0xc2, 0x94, 0xbc, 0x90, 0x94, 0x7a, 0x84, 0xc4, 0x82,
+  0x71, 0xeb, 0x25, 0xf2, 0x4e, 0xe6, 0x1f, 0x0f, 0x59, 0x08,
+  0xb7, 0x41, 0xf1, 0x55, 0xc2, 0x4c, 0x29, 0x7a, 0x09, 0x33,
+  0xd9, 0x81, 0x9e, 0x49, 0x9b, 0x2c, 0xf2, 0x79, 0xf9, 0x3c,
+  0x9e, 0x7e, 0x4f, 0x27, 0x9f, 0x93, 0xc9, 0xe7, 0xe4, 0xf2,
+  0x79, 0xc6, 0x63, 0x3e, 0x73, 0xc8, 0xf2, 0xe7, 0xe4, 0xf2,
+  0x79, 0xf9, 0x3c, 0x9e, 0x7e, 0x4f, 0x27, 0x9f, 0x93, 0xc9,
+  0xe7, 0xe4, 0xf2, 0x42, 0x4b, 0x35, 0xa2, 0x8b, 0xd5, 0x18,
+  0x71, 0xf4, 0x0f, 0xc8, 0x49, 0x92, 0x6d, 0x61, 0xc1, 0x4a,
+  0x94, 0x7d, 0x09, 0x15, 0x4c, 0x00, 0x48, 0xa8, 0x78, 0x12,
+  0x29, 0xfb, 0x3f, 0x89, 0x82, 0x4d, 0xc3, 0x3a, 0x09, 0x32,
+  0x3d, 0xf7, 0x92, 0x2e, 0x2e, 0x9b, 0xbb, 0x11, 0x8d, 0x9a,
+  0x3f, 0x68, 0x01, 0x99, 0x0f, 0x21, 0x0a, 0xe6, 0x75, 0x0d,
+  0x92, 0x32, 0xc9, 0xfc, 0x08, 0x25, 0xb2, 0xf7, 0xfd, 0xfc,
+  0x01, 0xc9, 0x93, 0xc9, 0x6f, 0x08, 0x49, 0x9c, 0xf2, 0x75,
+  0x92, 0x76, 0x09, 0x35, 0x26, 0x6f, 0x24, 0x3c, 0x82, 0x40,
+  0x12, 0x19, 0xb6, 0x64, 0x27, 0xbf, 0x2d, 0xbb, 0x59, 0x60,
+  0x91, 0x54, 0xe3, 0x6f, 0x64, 0x64, 0x99, 0xe4, 0xb3, 0x71,
+  0x4c, 0xf2, 0x79, 0xfe, 0x4f, 0x27, 0x9f, 0x93, 0xc9, 0xe7,
+  0xe4, 0xf2, 0x79, 0xf9, 0x3c, 0x9e, 0x7e, 0x4f, 0x27, 0x9f,
+  0x93, 0xc9, 0xe7, 0xe4, 0xf2, 0x79, 0xf9, 0x3c, 0x9e, 0x7e,
+  0x4f, 0x24, 0x24, 0x42, 0xaa, 0xc2, 0x40, 0x93, 0xc7, 0xe1,
+  0xa8, 0xc6, 0xd9, 0x84, 0xa5, 0x02, 0xd6, 0x84, 0x8a, 0x76,
+  0x0e, 0xc5, 0xec, 0xc7, 0x70, 0x08, 0xa8, 0x70, 0xf8, 0xa5,
+  0x45, 0x2e, 0x09, 0x10, 0xef, 0x82, 0x40, 0x43, 0x08, 0x52,
+  0x61, 0x86, 0x47, 0x28, 0xb1, 0xb4, 0x5f, 0x96, 0xb7, 0xec,
+  0xd8, 0xe6, 0xec, 0xdf, 0x4d, 0xb9, 0x3c, 0x96, 0x6c, 0x2b,
+  0x24, 0x42, 0x3d, 0xfa, 0xbc, 0xad, 0xe3, 0xa2, 0x37, 0x62,
+  0x15, 0xf7, 0xed, 0xb0, 0xee, 0x4d, 0x5d, 0xf3, 0x81, 0x19,
+  0x23, 0x16, 0x81, 0x9b, 0x25, 0x76, 0x65, 0x1d, 0x92, 0xf9,
+  0x39, 0xdf, 0x7e, 0x6a, 0x3b, 0x64, 0x8e, 0x4c, 0xc1, 0x7a,
+  0xc9, 0x3d, 0x66, 0x68, 0x4d, 0xd9, 0x27, 0x1c, 0x88, 0x74,
+  0x24, 0x46, 0x2a, 0x68, 0xa6, 0x72, 0x70, 0x86, 0xac, 0xd0,
+  0x46, 0x99, 0x06, 0xdb, 0x25, 0x32, 0x08, 0x7b, 0x2f, 0x04,
+  0x5f, 0xb3, 0x9e, 0x4c, 0xfc, 0x9d, 0x94, 0x23, 0x3c, 0x9e,
+  0x7f, 0x93, 0xc9, 0xe7, 0xe4, 0xf2, 0x79, 0xf9, 0x3c, 0x9e,
+  0x71, 0x07, 0x10, 0x7e, 0x7e, 0x4f, 0x27, 0x9f, 0x93, 0xc9,
+  0xe7, 0xe4, 0xf2, 0x79, 0xf9, 0x3c, 0x9e, 0x7e, 0x4f, 0x24,
+  0x24, 0x76, 0xa5, 0xca, 0x61, 0xc4, 0x7a, 0x92, 0x3d, 0x0a,
+  0x5c, 0x9f, 0xca, 0x47, 0x09, 0x31, 0xa2, 0x52, 0x18, 0xb5,
+  0x65, 0x1f, 0x44, 0x65, 0xf6, 0xc2, 0x44, 0x0f, 0x91, 0xb8,
+  0x31, 0x21, 0xc2, 0x44, 0x23, 0x70, 0x90, 0xf6, 0xe1, 0x22,
+  0x09, 0xfc, 0x00, 0x20, 0x77, 0x61, 0x20, 0xce, 0x3b, 0x45,
+  0x9e, 0xb5, 0xa8, 0x01, 0xb0, 0x4d, 0xe3, 0x0e, 0x7e, 0x24,
+  0xc3, 0xbd, 0xf8, 0x64, 0x9d, 0xd9, 0x88, 0x6d, 0x93, 0xc9,
+  0x66, 0x8b, 0x39, 0x93, 0x57, 0x59, 0xee, 0x4b, 0xe8, 0x4e,
+  0xb2, 0x45, 0x2f, 0xb4, 0xe8, 0x64, 0xaf, 0x2d, 0xc0, 0xdf,
+  0xb2, 0x4f, 0x31, 0x32, 0x4f, 0x2e, 0x62, 0x83, 0xf5, 0xd0,
+  0xa1, 0xf9, 0x3a, 0x97, 0xdf, 0xdf, 0x3d, 0x53, 0x92, 0x32,
+  0x5c, 0xc7, 0xb4, 0xcc, 0xc8, 0x71, 0xbd, 0xd9, 0xf9, 0x2c,
+  0xf2, 0x79, 0xfe, 0x4f, 0x27, 0x9f, 0x93, 0xc9, 0xe7, 0xe4,
+  0xf2, 0x79, 0xf9, 0x3c, 0x9e, 0x73, 0xc8, 0xf2, 0xe7, 0xe4,
+  0xf2, 0x79, 0xf9, 0x3c, 0x9e, 0x7e, 0x4f, 0x27, 0x9f, 0x93,
+  0xc9, 0xe7, 0x3c, 0xf9, 0x38, 0xd8, 0x8c, 0x8e, 0x98, 0x62,
+  0x16, 0x31, 0x3d, 0xa0, 0x73, 0x1f, 0x8a, 0x46, 0x10, 0x0c,
+  0x11, 0xcb, 0x2f, 0x57, 0x1d, 0x82, 0x4f, 0x47, 0x64, 0x58,
+  0x01, 0x07, 0x07, 0x2c, 0x50, 0xe1, 0x4a, 0xc9, 0x29, 0xa6,
+  0xe6, 0x66, 0x13, 0x7d, 0x84, 0x89, 0x3f, 0x00, 0x48, 0x82,
+  0x57, 0x10, 0x8f, 0xe5, 0xe5, 0xf7, 0x3e, 0xd6, 0xf3, 0x0c,
+  0xb7, 0xe7, 0xc9, 0x8f, 0x3e, 0x4f, 0x6a, 0xfc, 0xf3, 0xd5,
+  0xe9, 0x4a, 0x0a, 0x46, 0x52, 0x52, 0x97, 0x88, 0xe5, 0xb8,
+  0x7e, 0x1c, 0xdc, 0x58, 0x72, 0xdb, 0xe1, 0xe4, 0x8b, 0x6f,
+  0xea, 0x41, 0xa1, 0x03, 0x6f, 0xd0, 0xe6, 0x5d, 0xd1, 0x90,
+  0xeb, 0x7d, 0xb6, 0x7e, 0xe8, 0x0e, 0x8e, 0x53, 0xef, 0xe7,
+  0xdc, 0x2c, 0x91, 0x96, 0xec, 0x12, 0x28, 0x9b, 0x93, 0xb9,
+  0x74, 0xaf, 0x00, 0xd8, 0x90, 0xd5, 0x99, 0x21, 0xe5, 0x9d,
+  0x03, 0x5f, 0x5c, 0x95, 0x22, 0x9b, 0x09, 0x38, 0x1e, 0x48,
+  0xcf, 0x24, 0x39, 0x4c, 0xcd, 0x8d, 0x64, 0x8e, 0x82, 0x4d
+};
+
+GST_START_TEST (test_vc1_identify_bdu)
+{
+  GstVC1ParserResult res;
+  GstVC1BDU bdu;
+  GstVC1SeqHdr hdr;
+  GstVC1EntryPointHdr entrypt;
+
+  res = gst_vc1_identify_next_bdu (sequence_fullframe,
+      sizeof (sequence_fullframe), &bdu);
+
+  assert_equals_int (res, GST_VC1_PARSER_OK);
+  assert_equals_int (bdu.type, GST_VC1_SEQUENCE);
+
+  res = gst_vc1_parse_sequence_header (bdu.data + bdu.offset, bdu.size, &hdr);
+  assert_equals_int (res, GST_VC1_PARSER_OK);
+  assert_equals_int (hdr.profile, GST_VC1_PROFILE_ADVANCED);
+
+  assert_equals_int (hdr.advanced.level, GST_VC1_LEVEL_L1);
+  assert_equals_int (hdr.advanced.colordiff_format, 1);
+
+  res = gst_vc1_identify_next_bdu (sequence_fullframe + bdu.sc_offset +
+      bdu.size, sizeof (sequence_fullframe) - bdu.sc_offset - bdu.size, &bdu);
+
+  fail_unless (res == GST_VC1_PARSER_OK);
+  fail_unless (bdu.type == GST_VC1_ENTRYPOINT);
+
+  res = gst_vc1_parse_entry_point_header (bdu.data + bdu.offset,
+      bdu.size, &entrypt, &hdr);
+  fail_unless (res == GST_VC1_PARSER_OK);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_p_frame_header_main)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+
+  GstVC1SeqStructC *structc = &seqhdr.struct_c;
+  GstVC1PicSimpleMain *pic = &framehdr.pic.simple;
+
+  structc->coded_height = 240;
+  structc->coded_width = 320;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (pframe_header_main,
+          sizeof (pframe_header_main), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_MAIN);
+
+  assert_equals_int (structc->frmrtq_postproc, 7);
+  assert_equals_int (structc->bitrtq_postproc, 2);
+  assert_equals_int (structc->loop_filter, 1);
+  assert_equals_int (structc->multires, 0);
+  assert_equals_int (structc->extended_mv, 0);
+  assert_equals_int (structc->rangered, 0);
+  assert_equals_int (structc->vstransform, 1);
+  assert_equals_int (structc->overlap, 1);
+  assert_equals_int (structc->syncmarker, 0);
+  assert_equals_int (structc->dquant, 1);
+  assert_equals_int (structc->quantizer, 0);
+  assert_equals_int (structc->maxbframes, 1);
+
+  assert_equals_int (gst_vc1_parse_frame_header (pframe_main,
+          sizeof (pframe_main), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_P);
+  assert_equals_int (framehdr.interpfrm, 0);
+  assert_equals_int (pic->frmcnt, 1);
+  assert_equals_int (pic->rangeredfrm, 0);
+  assert_equals_int (framehdr.pqindex, 10);
+  assert_equals_int (framehdr.pquant, 7);
+  assert_equals_int (framehdr.halfqp, 0);
+  assert_equals_int (framehdr.pquantizer, 0);
+
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_b_frame_header_main)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+  GstVC1BitPlanes b = { 0, };
+
+  GstVC1SeqStructC *structc = &seqhdr.struct_c;
+  GstVC1PicSimpleMain *pic = &framehdr.pic.simple;
+
+  structc->coded_height = 240;
+  structc->coded_width = 320;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (bframe_header_main,
+          sizeof (bframe_header_main), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_MAIN);
+  assert_equals_int (seqhdr.mb_height, 15);
+  assert_equals_int (seqhdr.mb_width, 20);
+
+  gst_vc1_bitplanes_ensure_size (&b, &seqhdr);
+
+  assert_equals_int (b.size, 315);
+
+  assert_equals_int (structc->frmrtq_postproc, 7);
+  assert_equals_int (structc->bitrtq_postproc, 3);
+  assert_equals_int (structc->loop_filter, 1);
+  assert_equals_int (structc->multires, 0);
+  assert_equals_int (structc->extended_mv, 0);
+  assert_equals_int (structc->rangered, 0);
+  assert_equals_int (structc->vstransform, 1);
+  assert_equals_int (structc->overlap, 1);
+  assert_equals_int (structc->syncmarker, 0);
+  assert_equals_int (structc->dquant, 1);
+  assert_equals_int (structc->quantizer, 0);
+  assert_equals_int (structc->maxbframes, 1);
+
+  assert_equals_int (gst_vc1_parse_frame_header (bframe_main,
+          sizeof (bframe_main), &framehdr, &seqhdr, &b), GST_VC1_PARSER_OK);
+
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_B);
+  assert_equals_int (framehdr.interpfrm, 0);
+
+  assert_equals_int (pic->frmcnt, 2);
+  assert_equals_int (pic->rangeredfrm, 0);
+  assert_equals_int (pic->ttmbf, 0);
+  assert_equals_int (pic->mvtab, 2);
+  assert_equals_int (pic->cbptab, 1);
+  assert_equals_int (framehdr.pquant, 7);
+  assert_equals_int (framehdr.halfqp, 0);
+  assert_equals_int (framehdr.pquantizer, 0);
+
+  gst_vc1_bitplanes_free_1 (&b);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_bi_frame_header_main)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+
+  GstVC1SeqStructC *structc = &seqhdr.struct_c;
+  GstVC1PicSimpleMain *pic = &framehdr.pic.simple;
+
+  structc->coded_height = 240;
+  structc->coded_width = 320;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (i_bi_frame_header,
+          sizeof (i_bi_frame_header), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_MAIN);
+  assert_equals_int (structc->frmrtq_postproc, 7);
+  assert_equals_int (structc->bitrtq_postproc, 7);
+  assert_equals_int (structc->loop_filter, 1);
+  assert_equals_int (structc->multires, 0);
+  assert_equals_int (structc->extended_mv, 0);
+  assert_equals_int (structc->rangered, 0);
+  assert_equals_int (structc->vstransform, 1);
+  assert_equals_int (structc->overlap, 1);
+  assert_equals_int (structc->syncmarker, 0);
+  assert_equals_int (structc->dquant, 1);
+  assert_equals_int (structc->quantizer, 0);
+  assert_equals_int (structc->maxbframes, 1);
+
+  assert_equals_int (gst_vc1_parse_frame_header (biframe_main,
+          sizeof (biframe_main), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_BI);
+  assert_equals_int (framehdr.interpfrm, 0);
+
+  assert_equals_int (pic->frmcnt, 0);
+  assert_equals_int (pic->rangeredfrm, 0);
+  assert_equals_int (framehdr.pqindex, 6);
+  assert_equals_int (framehdr.pquant, 6);
+  assert_equals_int (framehdr.halfqp, 0);
+  assert_equals_int (framehdr.pquantizer, 1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_i_frame_header_main)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+
+  GstVC1SeqStructC *structc = &seqhdr.struct_c;
+  GstVC1PicSimpleMain *pic = &framehdr.pic.simple;
+
+  structc->coded_height = 240;
+  structc->coded_width = 320;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (i_bi_frame_header,
+          sizeof (i_bi_frame_header), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_MAIN);
+  assert_equals_int (structc->frmrtq_postproc, 7);
+  assert_equals_int (structc->bitrtq_postproc, 7);
+  assert_equals_int (structc->loop_filter, 1);
+  assert_equals_int (structc->multires, 0);
+  assert_equals_int (structc->extended_mv, 0);
+  assert_equals_int (structc->rangered, 0);
+  assert_equals_int (structc->vstransform, 1);
+  assert_equals_int (structc->overlap, 1);
+  assert_equals_int (structc->syncmarker, 0);
+  assert_equals_int (structc->dquant, 1);
+  assert_equals_int (structc->quantizer, 0);
+  assert_equals_int (structc->maxbframes, 1);
+
+  assert_equals_int (gst_vc1_parse_frame_header (iframe_main,
+          sizeof (iframe_main), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_I);
+  assert_equals_int (framehdr.interpfrm, 0);
+
+  assert_equals_int (pic->frmcnt, 0);
+  assert_equals_int (pic->rangeredfrm, 0);
+  assert_equals_int (framehdr.pqindex, 4);
+  assert_equals_int (framehdr.pquant, 4);
+  assert_equals_int (framehdr.halfqp, 1);
+  assert_equals_int (framehdr.pquantizer, 1);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_i_frame_header_adv)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+
+  GstVC1AdvancedSeqHdr *advhdr = &seqhdr.advanced;
+  GstVC1EntryPointHdr *entrypt = &advhdr->entrypoint;
+  GstVC1PicAdvanced *pic = &framehdr.pic.advanced;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (iframe_adv_hdr,
+          sizeof (iframe_adv_hdr), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_ADVANCED);
+  assert_equals_int (advhdr->level, GST_VC1_LEVEL_L3);
+  assert_equals_int (advhdr->frmrtq_postproc, 7);
+  assert_equals_int (advhdr->bitrtq_postproc, 31);
+  assert_equals_int (advhdr->postprocflag, 0);
+  assert_equals_int (advhdr->max_coded_width, 1920);
+  assert_equals_int (advhdr->max_coded_height, 1080);
+  assert_equals_int (advhdr->interlace, 1);
+  assert_equals_int (advhdr->tfcntrflag, 0);
+  assert_equals_int (advhdr->finterpflag, 0);
+
+  assert_equals_int (advhdr->display_ext, 1);
+  assert_equals_int (advhdr->disp_horiz_size, 1920);
+  assert_equals_int (advhdr->disp_vert_size, 1080);
+
+  assert_equals_int (gst_vc1_parse_entry_point_header (entrypoint,
+          sizeof (entrypoint), entrypt, &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (entrypt->broken_link, 0);
+  assert_equals_int (entrypt->closed_entry, 1);
+  assert_equals_int (entrypt->panscan_flag, 0);
+  assert_equals_int (entrypt->refdist_flag, 1);
+  assert_equals_int (entrypt->loopfilter, 1);
+  assert_equals_int (entrypt->fastuvmc, 0);
+  assert_equals_int (entrypt->extended_mv, 1);
+  assert_equals_int (entrypt->dquant, 1);
+  assert_equals_int (entrypt->vstransform, 1);
+  assert_equals_int (entrypt->overlap, 0);
+  assert_equals_int (entrypt->quantizer, 0);
+  assert_equals_int (entrypt->coded_height, 1080);
+  assert_equals_int (entrypt->coded_width, 1920);
+
+  assert_equals_int (gst_vc1_parse_frame_header (iframe_adv,
+          sizeof (iframe_adv), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_I);
+  assert_equals_int (framehdr.pqindex, 3);
+  assert_equals_int (framehdr.pquant, 3);
+  assert_equals_int (framehdr.halfqp, 1);
+  assert_equals_int (framehdr.pquantizer, 1);
+
+  assert_equals_int (pic->fcm, 0);
+  assert_equals_int (pic->tff, 1);
+  assert_equals_int (pic->rff, 0);
+  assert_equals_int (pic->rndctrl, 0);
+}
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_b_frame_header_adv)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+
+  GstVC1AdvancedSeqHdr *advhdr = &seqhdr.advanced;
+  GstVC1EntryPointHdr *entrypt = &advhdr->entrypoint;
+  GstVC1PicAdvanced *pic = &framehdr.pic.advanced;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (iframe_adv_hdr,
+          sizeof (iframe_adv_hdr), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_ADVANCED);
+  assert_equals_int (advhdr->level, GST_VC1_LEVEL_L3);
+  assert_equals_int (advhdr->frmrtq_postproc, 7);
+  assert_equals_int (advhdr->bitrtq_postproc, 31);
+  assert_equals_int (advhdr->postprocflag, 0);
+  assert_equals_int (advhdr->max_coded_width, 1920);
+  assert_equals_int (advhdr->max_coded_height, 1080);
+  assert_equals_int (advhdr->interlace, 1);
+  assert_equals_int (advhdr->tfcntrflag, 0);
+  assert_equals_int (advhdr->finterpflag, 0);
+
+  assert_equals_int (advhdr->display_ext, 1);
+  assert_equals_int (advhdr->disp_horiz_size, 1920);
+  assert_equals_int (advhdr->disp_vert_size, 1080);
+
+  assert_equals_int (gst_vc1_parse_entry_point_header (entrypoint,
+          sizeof (entrypoint), entrypt, &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (entrypt->broken_link, 0);
+  assert_equals_int (entrypt->closed_entry, 1);
+  assert_equals_int (entrypt->panscan_flag, 0);
+  assert_equals_int (entrypt->refdist_flag, 1);
+  assert_equals_int (entrypt->loopfilter, 1);
+  assert_equals_int (entrypt->fastuvmc, 0);
+  assert_equals_int (entrypt->extended_mv, 1);
+  assert_equals_int (entrypt->dquant, 1);
+  assert_equals_int (entrypt->vstransform, 1);
+  assert_equals_int (entrypt->overlap, 0);
+  assert_equals_int (entrypt->quantizer, 0);
+
+  assert_equals_int (gst_vc1_parse_frame_header (bframe_adv,
+          sizeof (bframe_adv), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_B);
+  assert_equals_int (framehdr.pqindex, 1);
+  assert_equals_int (framehdr.pquant, 1);
+  assert_equals_int (framehdr.halfqp, 1);
+  assert_equals_int (framehdr.pquantizer, 1);
+
+  assert_equals_int (framehdr.vopdquant.dquantfrm, 0);
+  assert_equals_int (framehdr.transacfrm, 1);
+
+  assert_equals_int (gst_vc1_parse_frame_header (bframe2_adv,
+          sizeof (bframe2_adv), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_B);
+  assert_equals_int (framehdr.pqindex, 4);
+  assert_equals_int (framehdr.pquant, 4);
+  assert_equals_int (framehdr.halfqp, 0);
+  assert_equals_int (framehdr.pquantizer, 1);
+  assert_equals_int (framehdr.transacfrm, 0);
+
+  assert_equals_int (pic->mvrange, 0);
+  assert_equals_int (pic->mvmode, 0);
+}
+
+
+GST_END_TEST;
+
+GST_START_TEST (test_vc1_parse_p_frame_header_adv)
+{
+  GstVC1FrameHdr framehdr;
+  GstVC1SeqHdr seqhdr;
+
+  GstVC1AdvancedSeqHdr *advhdr = &seqhdr.advanced;
+  GstVC1EntryPointHdr *entrypt = &advhdr->entrypoint;
+  GstVC1PicAdvanced *pic = &framehdr.pic.advanced;
+
+  assert_equals_int (gst_vc1_parse_sequence_header (iframe_adv_hdr,
+          sizeof (iframe_adv_hdr), &seqhdr), GST_VC1_PARSER_OK);
+
+  assert_equals_int (seqhdr.profile, GST_VC1_PROFILE_ADVANCED);
+  assert_equals_int (advhdr->level, GST_VC1_LEVEL_L3);
+  assert_equals_int (advhdr->frmrtq_postproc, 7);
+  assert_equals_int (advhdr->bitrtq_postproc, 31);
+  assert_equals_int (advhdr->postprocflag, 0);
+  assert_equals_int (advhdr->max_coded_width, 1920);
+  assert_equals_int (advhdr->max_coded_height, 1080);
+  assert_equals_int (advhdr->interlace, 1);
+  assert_equals_int (advhdr->tfcntrflag, 0);
+  assert_equals_int (advhdr->finterpflag, 0);
+
+  assert_equals_int (advhdr->display_ext, 1);
+  assert_equals_int (advhdr->disp_horiz_size, 1920);
+  assert_equals_int (advhdr->disp_vert_size, 1080);
+
+  assert_equals_int (gst_vc1_parse_entry_point_header (entrypoint,
+          sizeof (entrypoint), entrypt, &seqhdr), GST_VC1_PARSER_OK);
+  assert_equals_int (entrypt->broken_link, 0);
+  assert_equals_int (entrypt->closed_entry, 1);
+  assert_equals_int (entrypt->panscan_flag, 0);
+  assert_equals_int (entrypt->refdist_flag, 1);
+  assert_equals_int (entrypt->loopfilter, 1);
+  assert_equals_int (entrypt->fastuvmc, 0);
+  assert_equals_int (entrypt->extended_mv, 1);
+  assert_equals_int (entrypt->dquant, 1);
+  assert_equals_int (entrypt->vstransform, 1);
+  assert_equals_int (entrypt->overlap, 0);
+  assert_equals_int (entrypt->quantizer, 0);
+  assert_equals_int (entrypt->coded_height, 1080);
+  assert_equals_int (entrypt->coded_width, 1920);
+
+
+  assert_equals_int (gst_vc1_parse_frame_header (pframe_adv,
+          sizeof (pframe_adv), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_P);
+  assert_equals_int (framehdr.pqindex, 1);
+  assert_equals_int (framehdr.pquant, 1);
+  assert_equals_int (framehdr.halfqp, 0);
+  assert_equals_int (framehdr.pquantizer, 1);
+
+  assert_equals_int (pic->mvmode, 0);
+  assert_equals_int (pic->mvrange, 0);
+
+  assert_equals_int (gst_vc1_parse_frame_header (pframe2_adv,
+          sizeof (pframe2_adv), &framehdr, &seqhdr, NULL), GST_VC1_PARSER_OK);
+  assert_equals_int (framehdr.ptype, GST_VC1_PICTURE_TYPE_P);
+  assert_equals_int (framehdr.pqindex, 1);
+  assert_equals_int (framehdr.pquant, 1);
+  assert_equals_int (framehdr.halfqp, 0);
+  assert_equals_int (framehdr.pquantizer, 1);
+
+  assert_equals_int (pic->mvmode, 3);
+  assert_equals_int (pic->mvrange, 0);
+}
+
+GST_END_TEST static Suite *
+vc1parser_suite (void)
+{
+  Suite *s = suite_create ("VC1 Parser library");
+
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_vc1_identify_bdu);
+  tcase_add_test (tc_chain, test_vc1_parse_p_frame_header_main);
+  tcase_add_test (tc_chain, test_vc1_parse_b_frame_header_main);
+  tcase_add_test (tc_chain, test_vc1_parse_bi_frame_header_main);
+  tcase_add_test (tc_chain, test_vc1_parse_i_frame_header_main);
+  tcase_add_test (tc_chain, test_vc1_parse_i_frame_header_adv);
+  tcase_add_test (tc_chain, test_vc1_parse_b_frame_header_adv);
+  tcase_add_test (tc_chain, test_vc1_parse_p_frame_header_adv);
+
+  return s;
+}
+
+int
+main (int argc, char **argv)
+{
+  int nf;
+
+  Suite *s = vc1parser_suite ();
+
+  SRunner *sr = srunner_create (s);
+
+  gst_check_init (&argc, &argv);
+
+  srunner_run_all (sr, CK_NORMAL);
+  nf = srunner_ntests_failed (sr);
+  srunner_free (sr);
+
+  return nf;
+}