initial import 06/147606/4
authorjohnny14 <johnny14@naver.com>
Tue, 5 Sep 2017 05:32:00 +0000 (14:32 +0900)
committerjohnny14 <johnny14@naver.com>
Tue, 12 Sep 2017 02:07:20 +0000 (11:07 +0900)
this package for nexell hardware codec

Change-Id: I33059b8e7ff3eaae5d425c8a07e2d24a5c72f902
Signed-off-by: johnny Nam <johnny@dignsys.com>
15 files changed:
LICENSE.LGPLv2+ [new file with mode: 0644]
Makefile.am [new file with mode: 0644]
Makefile.cross [new file with mode: 0644]
autogen.sh [new file with mode: 0755]
buildcfg.mk [new file with mode: 0644]
configure.ac [new file with mode: 0644]
packaging/nx-video-api.spec [new file with mode: 0644]
src/Makefile.am [new file with mode: 0644]
src/include/linux/videodev2_nxp_media.h [new file with mode: 0644]
src/mm_types.h [new file with mode: 0644]
src/nx_video_alloc.c [new file with mode: 0644]
src/nx_video_alloc.h [new file with mode: 0644]
src/nx_video_api.h [new file with mode: 0644]
src/nx_video_dec.c [new file with mode: 0644]
src/nx_video_enc.c [new file with mode: 0644]

diff --git a/LICENSE.LGPLv2+ b/LICENSE.LGPLv2+
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/Makefile.am b/Makefile.am
new file mode 100644 (file)
index 0000000..5ff2f58
--- /dev/null
@@ -0,0 +1,3 @@
+SUBDIRS = src
+
+EXTRA_DIST = autogen.sh
diff --git a/Makefile.cross b/Makefile.cross
new file mode 100644 (file)
index 0000000..974c7fa
--- /dev/null
@@ -0,0 +1,80 @@
+################################################################################
+#
+#      libnx_video_api.so
+#
+include ./buildcfg.mk
+
+# Directory Path
+INC_PATH       := ../sysroot/include
+LIB_PATH       := ../sysroot/lib
+
+# Target Information
+LIBNAME        := libnx_video_api
+TARGET := $(LIBNAME).so
+
+# Sources
+COBJS  := \
+               ./src/nx_video_alloc.o  \
+               ./src/nx_video_enc.o    \
+               ./src/nx_video_dec.o
+CPPOBJS        :=
+OBJS   := $(COBJS) $(CPPOBJS)
+
+# Add Include Path
+INCLUDE        += -I./ -I./src -I./src/include -I$(INC_PATH)
+
+# Add Dependent Libraries
+LIBRARY += -L$(LIB_PATH)
+
+# Compile Options
+CFLAGS += -fPIC
+
+# Build
+all: $(TARGET)
+
+$(TARGET):     depend $(OBJS)
+       $(quiet)$(CC) $(LDFLAGS) -shared -Wl,-soname,$(TARGET) -o $@ $(OBJS) $(LIBRARY)
+
+install:
+       @echo "$(ColorMagenta)[[[ Intall $(LIBNAME) ]]]$(ColorEnd)"
+       install -m 755 -d $(LIB_PATH)
+       install -m 755 -d $(INC_PATH)
+       install -m 644 $(TARGET) $(LIB_PATH)
+       install -m 644 ./src/include/linux/videodev2_nxp_media.h $(INC_PATH)
+       install -m 644 ./src/nx_video_alloc.h $(INC_PATH)
+       install -m 644 ./src/nx_video_api.h $(INC_PATH)
+
+clean:
+       @echo "$(ColorMagenta)[[[ Clean $(LIBNAME) ]]]$(ColorEnd)"
+       rm -f $(COBJS) $(CPPOBJS) $(TARGET) $(LIBNAME).a .depend
+
+distclean:
+       @echo "$(ColorMagenta)[[[ Distclean $(LIBNAME) ]]]$(ColorEnd)"
+       rm -f $(COBJS) $(CPPOBJS) $(TARGET) .depend
+       rm -f $(LIB_PATH)/$(TARGET)
+       rm -f $(INC_PATH)/videodev2_nxp_media.h
+       rm -f $(INC_PATH)/nx_video_alloc.h
+       rm -f $(INC_PATH)/nx_video_api.h
+
+update:
+       @cmp -s                                                                                                                         \
+               ../linux-artik7/include/uapi/linux/videodev2_nxp_media.h                \
+               ./src/include/linux/videodev2_nxp_media.h;                                              \
+       RETVAL=$$?;                                                                                                                     \
+       if [ $$RETVAL -ne 0 ]; then                                                                                     \
+               echo "$(ColorMagenta)[[[ Update Private Header ]]]$(ColorEnd)"; \
+               cp -a                                                                                                                   \
+                       ../linux-artik7/include/uapi/linux/videodev2_nxp_media.h        \
+                       ./src/include/linux;                                                                            \
+       fi
+
+# Dependency
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
+
+SRCS := $(COBJS:.o=.c) $(CPPOBJS:.o=.cpp)
+INCS := $(INCLUDE)
+depend dep:
+       @echo "$(ColorMagenta)[[[ Build $(LIBNAME) ]]]$(ColorEnd)"
+       $(quiet)$(CC) -M $(CFLAGS) $(INCS) $(SRCS) > .depend
diff --git a/autogen.sh b/autogen.sh
new file mode 100755 (executable)
index 0000000..c896097
--- /dev/null
@@ -0,0 +1,14 @@
+#! /bin/sh
+
+srcdir=`dirname "$0"`
+test -z "$srcdir" && srcdir=.
+
+ORIGDIR=`pwd`
+cd "$srcdir"
+
+autoreconf --force --verbose --install || exit 1
+cd "$ORIGDIR" || exit $?
+
+if test -z "$NOCONFIGURE"; then
+    "$srcdir"/configure "$@"
+fi
diff --git a/buildcfg.mk b/buildcfg.mk
new file mode 100644 (file)
index 0000000..6513dff
--- /dev/null
@@ -0,0 +1,89 @@
+#########################################################################
+# Embedded Linux Build Enviornment:
+#
+#########################################################################
+OBJTREE                := $(if $(BUILD_DIR),$(BUILD_DIR),$(CURDIR))
+
+ARCHNAME       := S5P6818
+CROSS_COMPILE  ?= aarch64-linux-gnu-
+
+ifneq ($(verbose),1)
+       quiet   := @
+endif
+
+INTERACTIVE := $(shell [ -t 0 ] && echo 1)
+ifdef INTERACTIVE
+# Light Color
+       ColorRed=\033[0;91m
+       ColorGreen=\033[0;92m
+       ColorYellow=\033[0;93m
+       ColorBlue=\033[0;93m
+       ColorMagenta=\033[0;95m
+       ColorCyan=\033[0;96m
+       ColorEnd=\033[0m
+# Dark Color
+       # ColorRed=\033[0;31m
+       # ColorGreen=\033[0;32m
+       # ColorYellow=\033[0;33m
+       # ColorBlue=\033[0;33m
+       # ColorMagenta=\033[0;35m
+       # ColorCyan=\033[0;36m
+       # ColorEnd=\033[0m
+else
+       ColorRed=
+       ColorGreen=
+       ColorYellow=
+       ColorBlue=
+       ColorMagenta=
+       ColorCyan=
+       ColorEnd=
+endif
+
+#########################################################################
+#      Toolchain.
+#########################################################################
+CROSS          := $(CROSS_COMPILE)
+CC                     := $(CROSS)gcc
+CPP                    := $(CROSS)g++
+AR                     := $(CROSS)ar
+AS                     := $(CROSS)as
+LD                     := $(CROSS)ld
+NM                     := $(CROSS)nm
+RANLIB                 := $(CROSS)ranlib
+OBJCOPY                := $(CROSS)objcopy
+STRIP          := $(CROSS)strip
+
+#########################################################################
+#      Library & Header macro
+#########################################################################
+INCLUDE        :=
+
+#########################################################################
+#      Build Options
+#########################################################################
+OPTS           := -Wall -O2 -Wextra -Wcast-align -Wno-unused-parameter -Wshadow -Wwrite-strings -Wcast-qual -fno-strict-aliasing -fstrict-overflow -fsigned-char -fno-omit-frame-pointer -fno-optimize-sibling-calls
+COPTS          := $(OPTS)
+CPPOPTS        := $(OPTS) -Wnon-virtual-dtor
+
+CFLAGS                 := $(COPTS)
+CPPFLAGS       := $(CPPOPTS)
+AFLAGS                 :=
+
+ARFLAGS                := crv
+LDFLAGS        :=
+LIBRARY                :=
+
+#########################################################################
+#      Generic Rules
+#########################################################################
+%.o: %.c
+       @echo "Compiling : $(CC) $(ColorCyan)$(notdir $<)$(ColorEnd)"
+       $(quiet)$(CC) $(CFLAGS) $(INCLUDE) -c -o $@ $<
+
+%.o: %.s
+       @echo "Compiling : $(AS) $(ColorCyan)$(notdir $<)$(ColorEnd)"
+       $(quiet)$(AS) $(AFLAGS) $(INCLUDE) -c -o $@ $<
+
+%.o: %.cpp
+       @echo "Compiling : $(CPP) $(ColorCyan)$(notdir $<)$(ColorEnd)"
+       $(quiet)$(CPP) $(CPPFLAGS) $(INCLUDE) -c -o $@ $<
diff --git a/configure.ac b/configure.ac
new file mode 100644 (file)
index 0000000..a953fe2
--- /dev/null
@@ -0,0 +1,28 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.69])
+AC_INIT([FULL-PACKAGE-NAME], [VERSION], [BUG-REPORT-ADDRESS])
+AC_CONFIG_SRCDIR([Makefile.am])
+AC_CONFIG_HEADERS([config.h])
+
+AM_INIT_AUTOMAKE([1.10 foreign dist-bzip2])
+
+# Checks for programs.
+AC_PROG_CXX
+AC_PROG_CC
+
+# Checks for libraries.
+
+# Checks for header files.
+
+# Initialize libtool
+LT_PREREQ([2.2])
+LT_INIT([disable-static])
+
+# Checks for typedefs, structures, and compiler characteristics.
+
+# Checks for library functions.
+
+AC_CONFIG_FILES([Makefile src/Makefile])
+AC_OUTPUT
diff --git a/packaging/nx-video-api.spec b/packaging/nx-video-api.spec
new file mode 100644 (file)
index 0000000..a5df13e
--- /dev/null
@@ -0,0 +1,51 @@
+Name:    nx-video-api
+Version: 1.0.2
+Release: 1
+License: LGPLv2+
+Summary: Nexell video APIs
+Group: Development/Libraries
+Source:  %{name}-%{version}.tar.gz
+
+BuildRequires:  pkgconfig automake autoconf libtool
+BuildRequires:  pkgconfig(libdrm)
+
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+%description
+Nexell video APIs
+
+%package devel
+Summary: Nexell video API development
+Group: Development/Libraries
+License: Apache 2.0
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Nexell scaler (devel)
+
+%prep
+%setup -q
+
+%build
+export CFLAGS="-I/usr/include/libdrm"
+autoreconf -v --install || exit 1
+%configure
+make %{?_smp_mflags}
+
+%postun -p /sbin/ldconfig
+
+%install
+rm -rf %{buildroot}
+make install DESTDIR=%{buildroot}
+
+find %{buildroot} -type f -name "*.la" -delete
+
+%files
+%{_libdir}/libnx_video_api.so
+%{_libdir}/libnx_video_api.so.*
+%license LICENSE.LGPLv2+
+
+%files devel
+%{_includedir}/*
+%license LICENSE.LGPLv2+
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644 (file)
index 0000000..55bf7b3
--- /dev/null
@@ -0,0 +1,20 @@
+AM_CFLAGS = \
+       $(WARN_CFLAGS)  \
+       -I./include             \
+       -I${includedir}
+
+libnx_video_api_la_LTLIBRARIES = libnx_video_api.la
+libnx_video_api_ladir = ${libdir}
+libnx_video_api_la_LDFLAGS = -L${libdir} -ldrm
+
+libnx_video_api_la_SOURCES = \
+       nx_video_alloc.c        \
+       nx_video_enc.c          \
+       nx_video_dec.c
+
+libnx_video_apiincludedir = ${includedir}
+libnx_video_apiinclude_HEADERS = \
+       include/linux/videodev2_nxp_media.h     \
+       nx_video_alloc.h        \
+       nx_video_api.h  \
+       mm_types.h
diff --git a/src/include/linux/videodev2_nxp_media.h b/src/include/linux/videodev2_nxp_media.h
new file mode 100644 (file)
index 0000000..672f720
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2016  Nexell Co., Ltd.
+ * Author: Seonghee, Kim <kshblue@nexell.co.kr>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _VIDEODEV2_NXP_MEDIA_H
+#define _VIDEODEV2_NXP_MEDIA_H
+
+/*
+ * F O R M A T S
+ */
+
+
+/* compressed formats */
+#define V4L2_PIX_FMT_DIV3                      v4l2_fourcc('D', 'I', 'V', '3')
+#define V4L2_PIX_FMT_DIV4                      v4l2_fourcc('D', 'I', 'V', '4')
+#define V4L2_PIX_FMT_DIV5                      v4l2_fourcc('D', 'I', 'V', '5')
+#define V4L2_PIX_FMT_DIV6                      v4l2_fourcc('D', 'I', 'V', '6')
+#define V4L2_PIX_FMT_DIVX                      v4l2_fourcc('D', 'I', 'V', 'X')
+#define V4L2_PIX_FMT_RV8                       v4l2_fourcc('R', 'V', '3', '0')
+#define V4L2_PIX_FMT_RV9                       v4l2_fourcc('R', 'V', '4', '0')
+#define V4L2_PIX_FMT_WMV9                      v4l2_fourcc('W', 'M', 'V', '3')
+#define V4L2_PIX_FMT_WVC1                      v4l2_fourcc('W', 'V', 'C', '1')
+#define V4L2_PIX_FMT_FLV1                      v4l2_fourcc('F', 'L', 'V', '1')
+#define V4L2_PIX_FMT_THEORA                    v4l2_fourcc('T', 'H', 'E', 'O')
+
+/* two non contiguous planes - one Y, one Cr + Cb interleaved  */
+/* 24  Y/CbCr 4:4:4 */
+#define V4L2_PIX_FMT_NV24M     v4l2_fourcc('N', 'M', '2', '4')
+/* 24  Y/CrCb 4:4:4 */
+#define V4L2_PIX_FMT_NV42M     v4l2_fourcc('N', 'M', '4', '2')
+
+/* three non contiguous planes - Y, Cb, Cr */
+/* 16  YUV422 planar */
+#define V4L2_PIX_FMT_YUV422M   v4l2_fourcc('Y', 'M', '1', '6')
+/* 24  YUV444 planar */
+#define V4L2_PIX_FMT_YUV444M   v4l2_fourcc('Y', 'M', '2', '4')
+
+
+
+/*
+ * C O N T R O L S
+ */
+
+
+/* Video Codec */
+#define V4L2_CID_NXP_VPU_BASE                  (V4L2_CTRL_CLASS_MPEG | 0x3000)
+
+#define V4L2_CID_MPEG_VIDEO_FPS_NUM            (V4L2_CID_NXP_VPU_BASE + 0x1)
+#define V4L2_CID_MPEG_VIDEO_FPS_DEN            (V4L2_CID_NXP_VPU_BASE + 0x2)
+#define V4L2_CID_MPEG_VIDEO_SEARCH_RANGE       (V4L2_CID_NXP_VPU_BASE + 0x4)
+#define V4L2_CID_MPEG_VIDEO_H264_AUD_INSERT    (V4L2_CID_NXP_VPU_BASE + 0x5)
+#define V4L2_CID_MPEG_VIDEO_RC_DELAY           (V4L2_CID_NXP_VPU_BASE + 0x6)
+#define V4L2_CID_MPEG_VIDEO_RC_GAMMA_FACTOR    (V4L2_CID_NXP_VPU_BASE + 0x7)
+#define V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE    (V4L2_CID_NXP_VPU_BASE + 0x8)
+#define V4L2_CID_MPEG_VIDEO_FORCE_I_FRAME      (V4L2_CID_NXP_VPU_BASE + 0x9)
+#define V4L2_CID_MPEG_VIDEO_FORCE_SKIP_FRAME   (V4L2_CID_NXP_VPU_BASE + 0xA)
+
+#define V4L2_CID_MPEG_VIDEO_H263_PROFILE       (V4L2_CID_NXP_VPU_BASE + 0xB)
+enum v4l2_mpeg_video_h263_profile
+{
+  V4L2_MPEG_VIDEO_H263_PROFILE_P0 = 0,
+  V4L2_MPEG_VIDEO_H263_PROFILE_P3 = 1,
+};
+
+#define V4L2_CID_MPEG_VIDEO_THUMBNAIL_MODE     (V4L2_CID_NXP_VPU_BASE + 0xC)
+
+#endif
diff --git a/src/mm_types.h b/src/mm_types.h
new file mode 100644 (file)
index 0000000..02323a5
--- /dev/null
@@ -0,0 +1,588 @@
+/*
+ * libmm-common
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jonghyuk Choi <jhchoi.choi@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+/**
+ * This file declares common data structure of multimedia framework.
+ *
+ * @file               mm_types.h
+ * @author
+ * @version            1.0
+ * @brief              This file declares common data structure of multimedia framework.
+ */
+
+/**
+        @addtogroup COMMON
+        @{
+ */
+
+#ifndef __MM_TYPES_H__
+#define        __MM_TYPES_H__
+
+#include <stdbool.h>
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+
+#define MM_MAX_FILENAME_LEN    256                     /**< Maximum length of the file name */
+#define MM_MAX_URL_LEN         2048    /**< Maximum length of the maximum URL */
+
+/**
+ * @def Defines range of logical volume factor.
+ * It's for logical volume control in player.
+ * So, don't use this one for media volume.
+ * range : 0 ~ 1.0 (1.0 = 100%)
+ */
+#define MM_VOLUME_LEVEL_MIN    0       /**< Minimum factor of volume */
+#define MM_VOLUME_LEVEL_MAX    1.0     /**< Maximum factor of volume */
+
+/**
+ * Multimedia Framework handle type.
+ */
+  typedef void *MMHandleType;           /**< Handle type */
+
+
+/**
+ * Enumerations of video capture devices.
+ */
+  enum MMVideoDeviceType
+  {
+    MM_VIDEO_DEVICE_NONE = -1,          /**< No camera */
+    MM_VIDEO_DEVICE_CAMERA0,            /**< Primary camera */
+    MM_VIDEO_DEVICE_CAMERA1,            /**< Secondary camera */
+    MM_VIDEO_DEVICE_NUM,                /**< Number of video capture devices */
+  };
+
+/**
+ * Enumerations of audio capture devices.
+ */
+  enum MMAudioDeviceType
+  {
+    MM_AUDIO_DEVICE_MIC,        /**< Mic device */
+    MM_AUDIO_DEVICE_MODEM,      /**< Modem */
+    MM_AUDIO_DEVICE_RADIO,      /**< Radio */
+    MM_AUDIO_DEVICE_NUM,        /**< Number of audio capture devices */
+  };
+
+/**
+ * Enumerations of display surfaces.
+ */
+  typedef enum
+  {
+    MM_DISPLAY_SURFACE_OVERLAY,                /**< Overlay surface - default */
+    MM_DISPLAY_SURFACE_EVAS,                   /**< Evas object surface */
+    MM_DISPLAY_SURFACE_GL,                     /**< GL surface */
+    MM_DISPLAY_SURFACE_NULL,                   /**< This just disposes of buffers */
+    MM_DISPLAY_SURFACE_REMOTE,                 /**< Daemon client surface */
+    MM_DISPLAY_SURFACE_NUM,                    /**< number of enum */
+  } MMDisplaySurfaceType;
+
+/**
+ * Enumerations of display modes.
+ */
+  enum MMDisplayModeType
+  {
+    MM_DISPLAY_MODE_DEFAULT,                                            /**< default - primary display(UI+Video) + secondary display(UI+Video) if available */
+    MM_DISPLAY_MODE_PRI_VIDEO_ON_AND_SEC_VIDEO_FULL_SCREEN,             /**< primary display(UI+Video) + secondary display(Video Full Screen) if available */
+    MM_DISPLAY_MODE_PRI_VIDEO_OFF_AND_SEC_VIDEO_FULL_SCREEN,            /**< primary display(UI only) + secondary display(Video Full Screen) if available */
+    MM_DISPLAY_MODE_NUM,                                                /**< number of enum */
+  };
+
+/**
+ * Enumerations of display devices.
+ */
+  enum MMDisplayDeviceType
+  {
+    MM_DISPLAY_DEVICE_MAINLCD,                 /**< Main LCD - default */
+    MM_DISPLAY_DEVICE_SUBLCD,                  /**< Sub LCD */
+    MM_DISPLAY_DEVICE_TVOUT,                   /**< TV out */
+    MM_DISPLAY_DEVICE_MAINLCD_AND_SUBLCD,      /**< Main LCD and Sub LCD */
+    MM_DISPLAY_DEVICE_MAINLCD_AND_TVOUT,       /**< Main LCD and TV */
+    MM_DISPLAY_DEVICE_NUM,                     /**< number of enum */
+  };
+
+/**
+ * Enumerations of display scales.
+ */
+  enum MMDisplayScaleType
+  {
+    MM_DISPLAY_SCALE_DEFAULT,                   /**< Default size */
+    MM_DISPLAY_SCALE_DOUBLE_LENGTH,     /**< Expand width, height to double size */
+    MM_DISPLAY_SCALE_TRIPLE_LENGTH,     /**< Expand width, height to triple size */
+    MM_DISPLAY_SCALE_NUM,                       /**< Number of display scales */
+  };
+
+/**
+ * Enumerations of storage.
+ */
+  enum MMStorageType
+  {
+    MM_STORAGE_INTERNAL,                        /**< Internal storage */
+    MM_STORAGE_EXTERNAL,                        /**< External storage such as memory card */
+    MM_STORAGE_NUM,                                     /**< Number of storage type */
+  };
+
+/**
+ * Enumerations for quality.
+ */
+  enum MMQualityType
+  {
+    MM_QUALITY_LOW,             /**< Low quality */
+    MM_QUALITY_HIGH,            /**< High quality */
+    MM_QUALITY_NUM,             /**< Number of quality type */
+  };
+
+/**
+ * Enumerations of channel type.
+ */
+  enum MMVolumeChannelType
+  {
+    MM_VOLUME_CHANNEL_LEFT,             /**< Left channel */
+    MM_VOLUME_CHANNEL_RIGHT,                    /**< Right channel */
+    MM_VOLUME_CHANNEL_NUM,              /**< Numbers of channels */
+    MM_CHANNEL_LEFT = MM_VOLUME_CHANNEL_LEFT,                   /**< Left channel */
+    MM_CHANNEL_RIGHT = MM_VOLUME_CHANNEL_RIGHT,                 /**< Right channel */
+    MM_CHANNEL_NUM = MM_VOLUME_CHANNEL_NUM,             /**< Numbers of channels */
+  };
+
+/*
+ * Enumerations of SW Volume Table Type.
+ */
+  enum MMSoftwareVolumeTableType
+  {
+    MM_SOUND_VOLUME_TYPE_SYSTEM,                /**< Volume table for System */
+    MM_SOUND_VOLUME_TYPE_NOTIFICATION,          /**< Volume table for Notification */
+    MM_SOUND_VOLUME_TYPE_ALARM,                         /**< Volume table for Alarm */
+    MM_SOUND_VOLUME_TYPE_RINGTONE,              /**< Volume table for Ringtone */
+    MM_SOUND_VOLUME_TYPE_MEDIA,                         /**< Volume table for Multimedia */
+    MM_SOUND_VOLUME_TYPE_CALL,                          /**< Volume table for Call */
+    MM_SOUND_VOLUME_TYPE_VOIP,                          /**< Volume table for VOIP */
+    MM_SOUND_VOLUME_TYPE_VOICE,                         /**< Volume table for VOICE */
+    MM_SOUND_VOLUME_TYPE_SVOICE,                        /**< Volume table for SVOICE */
+    MM_SOUND_VOLUME_TYPE_EMERGENCY,             /**< Volume table for Emergency (FIXED) */
+    MM_SOUND_VOLUME_TYPE_NUM,
+    MM_SOUND_VOLUME_TABLE_NUM = MM_SOUND_VOLUME_TYPE_NUM,
+  };
+
+/*
+ * Enumerations of SW Volume Gain.
+ */
+  enum MMSoftwareVolumeGainType
+  {
+    MM_SOUND_VOLUME_GAIN_DEFAULT = 0,                   /**< Volume gain for Default */
+    MM_SOUND_VOLUME_GAIN_DIALER = 1 << 8,                       /**< Volume gain for Dialer */
+    MM_SOUND_VOLUME_GAIN_TOUCH = 2 << 8,                        /**< Volume gain for Touch */
+    MM_SOUND_VOLUME_GAIN_AF = 3 << 8,                           /**< Volume gain for AF */
+    MM_SOUND_VOLUME_GAIN_SHUTTER1 = 4 << 8,             /**< Volume gain for Shutter1 */
+    MM_SOUND_VOLUME_GAIN_SHUTTER2 = 5 << 8,             /**< Volume gain for Shutter2 */
+    MM_SOUND_VOLUME_GAIN_CAMCORDING = 6 << 8,           /**< Volume gain for Camcording */
+    MM_SOUND_VOLUME_GAIN_MIDI = 7 << 8,                         /**< Volume gain for Midi */
+    MM_SOUND_VOLUME_GAIN_BOOTING = 8 << 8,              /**< Volume gain for Booting */
+    MM_SOUND_VOLUME_GAIN_VIDEO = 9 << 8,                        /**< Volume gain for Video */
+    MM_SOUND_VOLUME_GAIN_TTS = 10 << 8,                         /**< Volume gain for TTS */
+    MM_SOUND_VOLUME_GAIN_NUM
+  };
+
+#define MM_SOUND_PRIORITY_ALLOW_MIX    (0x80) /**< This define has deprecated */
+/*
+ * Enumerations of Sound Priority.
+ */
+  enum MMSoundPriorityType
+  {
+    MM_SOUND_PRIORITY_0,                /**< This enum has deprecated */
+    MM_SOUND_PRIORITY_1,                /**< This enum has deprecated */
+    MM_SOUND_PRIORITY_2,                /**< This enum has deprecated */
+    MM_SOUND_PRIORITY_3,                /**< This enum has deprecated */
+    MM_SOUND_PRIORITY_4,                /**< This enum has deprecated */
+    MM_SOUND_PRIORITY_5,                /**< This enum has deprecated */
+    MM_SOUND_PRIORITY_NUM,
+  };
+
+/**
+ * Enumerations of video codec.
+ */
+  enum MMVideoCodecType
+  {
+    MM_VIDEO_CODEC_INVALID = -1,        /**< Invalid codec type */
+    MM_VIDEO_CODEC_NONE,                        /**< None (will be deprecated) */
+    MM_VIDEO_CODEC_H263,                        /**< H263 codec                */
+    MM_VIDEO_CODEC_H264,                        /**< H264 codec                */
+    MM_VIDEO_CODEC_H26L,                        /**< H26L codec                */
+    MM_VIDEO_CODEC_MPEG4,                       /**< MPEG4 codec       */
+    MM_VIDEO_CODEC_MPEG1,                       /**< MPEG1 codec       */
+    MM_VIDEO_CODEC_WMV,                         /**< WMV codec         */
+    MM_VIDEO_CODEC_DIVX,                        /**< DIVX codec                */
+    MM_VIDEO_CODEC_XVID,                        /**< XVID codec                */
+    MM_VIDEO_CODEC_H261,                                /**< H261 codec                                                                                */
+    MM_VIDEO_CODEC_H262,                                /**< H262/MPEG2-part2 codec                                                    */
+    MM_VIDEO_CODEC_H263V2,                              /**< H263v2 codec                                                                      */
+    MM_VIDEO_CODEC_H263V3,                              /**< H263v3 codec                                                                      */
+    MM_VIDEO_CODEC_MJPEG,                               /**< Motion JPEG Video codec                                           */
+    MM_VIDEO_CODEC_MPEG2,                               /**< MPEG2 codec                                                                       */
+    MM_VIDEO_CODEC_MPEG4_SIMPLE,            /**< MPEG4 part-2 Simple profile codec                             */
+    MM_VIDEO_CODEC_MPEG4_ADV_SIMPLE,        /**< MPEG4 part-2 Advanced Simple profile codec            */
+    MM_VIDEO_CODEC_MPEG4_MAIN,                          /**< MPEG4 part-2 Main profile codec                           */
+    MM_VIDEO_CODEC_MPEG4_CORE,                          /**< MPEG4 part-2 Core profile codec                           */
+    MM_VIDEO_CODEC_MPEG4_ACE,                           /**< MPEG4 part-2 Adv Coding Eff profile codec         */
+    MM_VIDEO_CODEC_MPEG4_ARTS,                          /**< MPEG4 part-2 Adv RealTime Simple profile codec    */
+    MM_VIDEO_CODEC_MPEG4_AVC,                           /**< MPEG4 part-10 (h.264) codec                                       */
+    MM_VIDEO_CODEC_REAL,                                /**< Real video                                                                                */
+    MM_VIDEO_CODEC_VC1,                                         /**< VC-1 video                                                                                */
+    MM_VIDEO_CODEC_AVS,                                         /**< AVS video                                                                         */
+    MM_VIDEO_CODEC_CINEPAK,                             /**< Cinepak video     codec                                                   */
+    MM_VIDEO_CODEC_INDEO,                               /**< Indeo video       codec                                                   */
+    MM_VIDEO_CODEC_THEORA,                              /**< Theora video      codec                                                   */
+    MM_VIDEO_CODEC_FLV,                                         /**< Adobe Flash Video codec                                           */
+    MM_VIDEO_CODEC_NUM,                         /**< Number of video codec type        */
+  };
+
+/**
+ * Enumerations of audio codec.
+ */
+  enum MMAudioCodecType
+  {
+    MM_AUDIO_CODEC_INVALID = -1,        /**< Invalid codec type */
+    MM_AUDIO_CODEC_AMR,                         /**< AMR codec         */
+    MM_AUDIO_CODEC_G723_1,                      /**< G723.1 codec      */
+    MM_AUDIO_CODEC_MP3,                         /**< MP3 codec         */
+    MM_AUDIO_CODEC_OGG,                         /**< OGG codec         */
+    MM_AUDIO_CODEC_AAC,                         /**< AAC codec         */
+    MM_AUDIO_CODEC_WMA,                         /**< WMA codec         */
+    MM_AUDIO_CODEC_MMF,                         /**< MMF codec         */
+    MM_AUDIO_CODEC_ADPCM,                       /**< ADPCM codec       */
+    MM_AUDIO_CODEC_WAVE,                        /**< WAVE codec                */
+    MM_AUDIO_CODEC_WAVE_NEW,                            /**< WAVE codec                */
+    MM_AUDIO_CODEC_MIDI,                        /**< MIDI codec                */
+    MM_AUDIO_CODEC_IMELODY,             /**< IMELODY codec     */
+    MM_AUDIO_CODEC_MXMF,
+    MM_AUDIO_CODEC_MPA,                         /**< MPEG1-Layer1 codec                                                */
+    MM_AUDIO_CODEC_MP2,                         /**< MPEG1-Layer2 codec                                                */
+    MM_AUDIO_CODEC_G711,                /**< G711 codec                                                                */
+    MM_AUDIO_CODEC_G722,                /**< G722 wideband speech codec                                */
+    MM_AUDIO_CODEC_G722_1,              /**< G722.1 codec                                                      */
+    MM_AUDIO_CODEC_G722_2,              /**< G722.2  (AMR-WB) codec                                    */
+    MM_AUDIO_CODEC_G723,                /**< G723 wideband speech codec                                */
+    MM_AUDIO_CODEC_G726,                /**< G726 (ADPCM) codec                                                */
+    MM_AUDIO_CODEC_G728,                /**< G728 speech codec                                         */
+    MM_AUDIO_CODEC_G729,                /**< G729 codec                                                                */
+    MM_AUDIO_CODEC_G729A,               /**< G729a codec                                                       */
+    MM_AUDIO_CODEC_G729_1,              /**< G729.1 codec                                                      */
+    MM_AUDIO_CODEC_REAL,            /**< Real audio                                                    */
+    MM_AUDIO_CODEC_AAC_LC,              /**< AAC-Low complexity codec                          */
+    MM_AUDIO_CODEC_AAC_MAIN,            /**< AAC-Main profile codec                                    */
+    MM_AUDIO_CODEC_AAC_SRS,             /**< AAC-Scalable sample rate codec                    */
+    MM_AUDIO_CODEC_AAC_LTP,             /**< AAC-Long term prediction codec                    */
+    MM_AUDIO_CODEC_AAC_HE_V1,           /**< AAC-High Efficiency v1 codec                      */
+    MM_AUDIO_CODEC_AAC_HE_V2,           /**< AAC-High efficiency v2 codec                      */
+    MM_AUDIO_CODEC_AC3,                         /**< DolbyDigital codec                                                */
+    MM_AUDIO_CODEC_ALAC,                /**< Apple Lossless audio codec                                */
+    MM_AUDIO_CODEC_ATRAC,               /**< Sony proprietary audio codec                      */
+    MM_AUDIO_CODEC_SPEEX,               /**< SPEEX audio codec                                         */
+    MM_AUDIO_CODEC_VORBIS,              /**< Vorbis audio codec                                                */
+    MM_AUDIO_CODEC_AIFF,            /**< AIFF codec                                                            */
+    MM_AUDIO_CODEC_AU,                  /**< AU codec                                                          */
+    MM_AUDIO_CODEC_NONE,                        /**< None (will be deprecated) */
+    MM_AUDIO_CODEC_PCM,                         /**< PCM codec */
+    MM_AUDIO_CODEC_ALAW,                        /**< ALAW codec */
+    MM_AUDIO_CODEC_MULAW,                       /**< MULAW codec */
+    MM_AUDIO_CODEC_MS_ADPCM,            /**< MS ADPCM codec */
+    MM_AUDIO_CODEC_FLAC,                        /**< Free Lossless audio codec                         */
+    MM_AUDIO_CODEC_NUM,                         /**< Number of audio codec type        */
+  };
+
+/**
+ * Enumerations of image codec.
+ */
+  enum MMImageCodecType
+  {
+    MM_IMAGE_CODEC_INVALID = -1,    /**< Invalid codec type */
+    MM_IMAGE_CODEC_JPEG,            /**< JPEG codec */
+    MM_IMAGE_CODEC_PNG,             /**< PNG codec             */
+    MM_IMAGE_CODEC_BMP,             /**< BMP codec             */
+    MM_IMAGE_CODEC_WBMP,            /**< WBMP codec            */
+    MM_IMAGE_CODEC_TIFF,            /**< TIFF codec            */
+    MM_IMAGE_CODEC_PCX,             /**< PCX codec             */
+    MM_IMAGE_CODEC_GIF,             /**< GIF codec             */
+    MM_IMAGE_CODEC_ICO,             /**< ICO codec             */
+    MM_IMAGE_CODEC_RAS,             /**< RAS codec             */
+    MM_IMAGE_CODEC_TGA,             /**< TGA codec             */
+    MM_IMAGE_CODEC_XBM,             /**< XBM codec             */
+    MM_IMAGE_CODEC_XPM,             /**< XPM codec             */
+    MM_IMAGE_CODEC_SRW,             /**< SRW (Samsung standard RAW) */
+    MM_IMAGE_CODEC_JPEG_SRW,        /**< JPEG + SRW */
+    MM_IMAGE_CODEC_NUM,             /**< Number of image codecs */
+  };
+
+/**
+ * Enumerations of file container format.
+ */
+  enum MMFileFormatType
+  {
+    MM_FILE_FORMAT_INVALID = -1,    /**< Invalid file format */
+    MM_FILE_FORMAT_3GP,                         /**< 3GP file format */
+    MM_FILE_FORMAT_ASF,                         /**< Advanced Systems File file format */
+    MM_FILE_FORMAT_AVI,                         /**< Audio Video Interleaved file format */
+    MM_FILE_FORMAT_MATROSKA,            /**< MATROSAK file format */
+    MM_FILE_FORMAT_MP4,                         /**< MP4 file format */
+    MM_FILE_FORMAT_OGG,                         /**< OGG file format */
+    MM_FILE_FORMAT_NUT,                         /**< NUT file format */
+    MM_FILE_FORMAT_QT,                          /**< MOV file format */
+    MM_FILE_FORMAT_REAL,                /**< RealMedia file format */
+    MM_FILE_FORMAT_AMR,                         /**< AMR file format */
+    MM_FILE_FORMAT_AAC,                         /**< AAC file format */
+    MM_FILE_FORMAT_MP3,                         /**< MP3 file format */
+    MM_FILE_FORMAT_AIFF,                /**< AIFF file format */
+    MM_FILE_FORMAT_AU,                          /**< Audio file format */
+    MM_FILE_FORMAT_WAV,                         /**< WAV file format */
+    MM_FILE_FORMAT_MID,                         /**< MID file format */
+    MM_FILE_FORMAT_MMF,                         /**< MMF file format */
+    MM_FILE_FORMAT_DIVX,                /**< DivX file format */
+    MM_FILE_FORMAT_FLV,                         /**< Flash video file format */
+    MM_FILE_FORMAT_VOB,                         /**< DVD-Video Object file format */
+    MM_FILE_FORMAT_IMELODY,             /**< IMelody file format */
+    MM_FILE_FORMAT_WMA,                 /**< WMA file format */
+    MM_FILE_FORMAT_WMV,                 /**< WMV file format */
+    MM_FILE_FORMAT_JPG,                 /**< JPEG file format */
+    MM_FILE_FORMAT_FLAC,                /**< FLAC file format */
+    MM_FILE_FORMAT_M2TS,                /**< MPEG2-Transport Stream file format */
+    MM_FILE_FORMAT_M2PS,                        /**< MPEG2-Program Stream file format */
+    MM_FILE_FORMAT_M1VIDEO,             /**< MPEG1-Video file format */
+    MM_FILE_FORMAT_M1AUDIO,             /**< MPEG1-Audio file format */
+    MM_FILE_FORMAT_NUM,                 /**< Number of file format type */
+  };
+
+/**
+ * Enumerations of display layers.
+ */
+  typedef enum
+  {
+    MM_VIDEO_LAYER_PRIMARY,             /**< Primary of the video layer */
+    MM_VIDEO_LAYER_OVERLAY,             /**< Overlay of the video layer */
+    MM_VIDEO_LAYER_NUM                  /**< Number of the video layer */
+  } MMVideoLayerType;
+
+/**
+ * Enumerations of Pixel formats
+ */
+  typedef enum
+  {
+    MM_PIXEL_FORMAT_INVALID = -1,       /**< Invalid pixel format */
+    MM_PIXEL_FORMAT_NV12,               /**< NV12 pixel format */
+    MM_PIXEL_FORMAT_NV12T,              /**< NV12 Tiled pixel format */
+    MM_PIXEL_FORMAT_NV16,               /**< NV16 pixel format */
+    MM_PIXEL_FORMAT_NV21,               /**< NV21 pixel format */
+    MM_PIXEL_FORMAT_YUYV,               /**< YUYV(YUY2) pixel format */
+    MM_PIXEL_FORMAT_UYVY,               /**< UYVY pixel format */
+    MM_PIXEL_FORMAT_422P,               /**< YUV422(Y:U:V) planar pixel format */
+    MM_PIXEL_FORMAT_I420,               /**< I420 pixel format */
+    MM_PIXEL_FORMAT_YV12,               /**< YV12 pixel format */
+    MM_PIXEL_FORMAT_RGB565,             /**< RGB565 pixel format */
+    MM_PIXEL_FORMAT_RGB888,             /**< RGB888 pixel format */
+    MM_PIXEL_FORMAT_RGBA,               /**< RGBA pixel format */
+    MM_PIXEL_FORMAT_ARGB,               /**< ARGB pixel format */
+    MM_PIXEL_FORMAT_ENCODED,            /**< Encoded pixel format : JPEG */
+    MM_PIXEL_FORMAT_ITLV_JPEG_UYVY,     /**< FIXME: JPEG+UYVY Interleaved format */
+    MM_PIXEL_FORMAT_ENCODED_H264,       /**< Encoded pixel format : H.264 */
+    MM_PIXEL_FORMAT_NUM                 /**< Number of the pixel format */
+  } MMPixelFormatType;
+
+/**
+ * Enumerations of video input rotation type.
+ */
+  typedef enum
+  {
+    MM_VIDEO_INPUT_ROTATION_NONE,       /**< No rotation of the display */
+    MM_VIDEO_INPUT_ROTATION_90,                 /**< 90 degree rotation */
+    MM_VIDEO_INPUT_ROTATION_180,        /**< 180 degree rotation */
+    MM_VIDEO_INPUT_ROTATION_270,        /**< 270 degree rotation */
+    MM_VIDEO_INPUT_ROTATION_NUM                 /**< Number of the rotation */
+  } MMVideoInputRotationType;
+
+/**
+ * Enumerations of display rotation type.
+ */
+  typedef enum
+  {
+    MM_DISPLAY_ROTATION_NONE,           /**< No rotation of the display */
+    MM_DISPLAY_ROTATION_90,             /**< 90 degree rotation */
+    MM_DISPLAY_ROTATION_180,            /**< 180 degree rotation */
+    MM_DISPLAY_ROTATION_270,            /**< 270 degree rotation */
+    MM_DISPLAY_ROTATION_NUM             /**< Number of the rotation */
+  } MMDisplayRotationType;
+
+/**
+ * Enumerations of flip type.
+ */
+  typedef enum
+  {
+    MM_FLIP_NONE,                       /**< No Flip */
+    MM_FLIP_HORIZONTAL,                 /**< Horizontal flip */
+    MM_FLIP_VERTICAL,                   /**< Vertical flip */
+    MM_FLIP_BOTH,                       /**< Horizontal and Vertical flip */
+    MM_FLIP_NUM                         /**< Number of flip */
+  } MMFlipType;
+
+/**
+ * Enumerations of streaming type.
+ */
+  typedef enum
+  {
+    STREAMING_SERVICE_VOD,                      /**< Streaming is vod */
+    STREAMING_SERVICE_LIVE,                     /**< Streaming is live stream */
+    STREAMING_SERVICE_NONE,                     /**< Not an streaming */
+    STREAMING_SERVICE_NUM,                      /**< Number of the streaming type */
+  } MMStreamingType;
+
+/**
+ * Resolution
+ */
+  typedef struct
+  {
+    int width;                  /**< width */
+    int height;                 /**< height */
+  } MMResolutionType;
+
+/**
+ * Type definition of rectangle.
+ * This will be deprecated.
+ */
+  typedef struct
+  {
+    unsigned int x;             /**< Start x point */
+    unsigned int y;             /**< Start y point */
+    unsigned int width;         /**< width */
+    unsigned int height;        /**< Height */
+  } MMRectType;
+
+#define BT_ADDR_LEN 18          /**< Length of BT address */
+/**
+ * bluetooth information.
+ */
+  typedef struct
+  {
+    int mode;                                                   /**< BT enable/disable */
+    char addr[BT_ADDR_LEN];                     /**< BT device address */
+  } MMBluetoothType;
+
+
+/**
+ * Enumerations of bluetooth mode
+ */
+  enum MMBluetoothMode
+  {
+    MM_BLUETOOTH_DISABLE = 0,
+    MM_BLUETOOTH_ENABLE
+  };
+
+/*
+ * Enumerations of sound path policy
+ */
+  enum MMAudioRoutePolicy
+  {
+    MM_AUDIOROUTE_USE_EXTERNAL_SETTING = -1,
+    MM_AUDIOROUTE_PLAYBACK_NORMAL,
+    MM_AUDIOROUTE_PLAYBACK_ALERT,
+    MM_AUDIOROUTE_PLAYBACK_HEADSET_ONLY,
+    MM_AUDIOROUTE_CAPTURE_NORMAL = 0,
+    MM_AUDIOROUTE_CAPTURE_MAINMIC_ONLY,
+    MM_AUDIOROUTE_CAPTURE_STEREOMIC_ONLY,
+  };
+
+/*
+ * Enumerations of display geometry method
+ */
+  typedef enum
+  {
+    MM_DISPLAY_METHOD_LETTER_BOX = 0,
+    MM_DISPLAY_METHOD_ORIGIN_SIZE,
+    MM_DISPLAY_METHOD_FULL_SCREEN,
+    MM_DISPLAY_METHOD_CROPPED_FULL,
+    MM_DISPLAY_METHOD_ORIGIN_OR_LETTER,
+    MM_DISPLAY_METHOD_CUSTOM_ROI,
+  } MMDisplayGeometryMethod;
+
+/*
+ * Enumerations of ROI mode of display geometry method
+ */
+  typedef enum
+  {
+    MM_DISPLAY_METHOD_CUSTOM_ROI_FULL_SCREEN = 0,
+    MM_DISPLAY_METHOD_CUSTOM_ROI_LETER_BOX
+  } MMDisplayGeometryMethodRoiMode;
+
+
+#define MM_VIDEO_BUFFER_PLANE_MAX   4   /**< Max num of video buffer plane */
+/*
+ * Enumerations of multimedia video buffer type
+ */
+  typedef enum
+  {
+    MM_VIDEO_BUFFER_TYPE_PHYSICAL_ADDRESS = 0,
+    MM_VIDEO_BUFFER_TYPE_DMABUF_FD,
+    MM_VIDEO_BUFFER_TYPE_TBM_BO,
+    MM_VIDEO_BUFFER_TYPE_GEM,
+  } MMVideoBufferType;
+
+  typedef struct
+  {
+    void *paddr[MM_VIDEO_BUFFER_PLANE_MAX];             /**< physical address */
+    int dmabuf_fd[MM_VIDEO_BUFFER_PLANE_MAX];           /**< dmabuf fd */
+    void *bo[MM_VIDEO_BUFFER_PLANE_MAX];                /**< TBM bo */
+    int gem[MM_VIDEO_BUFFER_PLANE_MAX];                 /**< GEM handle */
+  } MMVideoBufferHandle;
+
+/*
+ * Type definition of multimedia video buffer
+ */
+  typedef struct
+  {
+    MMVideoBufferType type;                                     /**< buffer type
+                                                                     - The field of handle that type indicates should be filled,
+                                                                       and other fields of handle are optional. */
+    MMPixelFormatType format;                                   /**< buffer type */
+    int plane_num;                                              /**< number of planes */
+    int width[MM_VIDEO_BUFFER_PLANE_MAX];                       /**< width of buffer */
+    int height[MM_VIDEO_BUFFER_PLANE_MAX];                      /**< height of buffer */
+    int stride_width[MM_VIDEO_BUFFER_PLANE_MAX];                /**< stride width of buffer */
+    int stride_height[MM_VIDEO_BUFFER_PLANE_MAX];               /**< stride height of buffer */
+    int size[MM_VIDEO_BUFFER_PLANE_MAX];                        /**< size of planes */
+    void *data[MM_VIDEO_BUFFER_PLANE_MAX];                      /**< data pointer(user address) of planes */
+    int handle_num;                                             /**< number of buffer handle */
+    int handle_size[MM_VIDEO_BUFFER_PLANE_MAX];                 /**< size of handles */
+    MMVideoBufferHandle handle;                                 /**< handle of buffer */
+    int is_secured;                                             /**< secured buffer flag. ex) TrustZone memory, user can not access it. */
+    int flush_request;                                          /**< flush request flag
+                                                                     - If this flag is TRUE, sink element will make copy of last buffer,
+                                                                       and it will return all buffers from src element.
+                                                                       Then, src element can restart without changing pipeline state. */
+    int buffer_index;
+  } MMVideoBuffer;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif                          /* __MM_TYPES_H__ */
diff --git a/src/nx_video_alloc.c b/src/nx_video_alloc.c
new file mode 100644 (file)
index 0000000..9bf84f4
--- /dev/null
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2016  Nexell Co., Ltd.
+ * Author: SeongO, Park <ray@nexell.co.kr>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>           //      PROT_READ/PROT_WRITE/MAP_SHARED/mmap/munmap
+
+#include <nexell/nexell_drm.h>
+#include <nx_video_alloc.h>
+
+#include <libdrm/drm_fourcc.h>
+#include <linux/videodev2.h>
+#include <linux/videodev2_nxp_media.h>
+
+#define DRM_DEVICE_NAME "/dev/dri/card0"
+
+#define DRM_IOCTL_NR(n)         _IOC_NR(n)
+#define DRM_IOC_VOID            _IOC_NONE
+#define DRM_IOC_READ            _IOC_READ
+#define DRM_IOC_WRITE           _IOC_WRITE
+#define DRM_IOC_READWRITE       _IOC_READ|_IOC_WRITE
+#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
+
+static int
+drm_ioctl (int32_t drm_fd, uint32_t request, void *arg)
+{
+  int ret;
+
+  do {
+    ret = ioctl (drm_fd, request, arg);
+  } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
+  return ret;
+}
+
+static int
+drm_command_write_read (int fd, uint32_t command_index,
+    void *data, uint32_t size)
+{
+  uint32_t request;
+
+  request = DRM_IOC (DRM_IOC_READ | DRM_IOC_WRITE, DRM_IOCTL_BASE,
+      DRM_COMMAND_BASE + command_index, size);
+  if (drm_ioctl (fd, request, data))
+    return -errno;
+  return 0;
+}
+
+/**
+ * return gem_fd
+ */
+static int
+alloc_gem (int drm_fd, int size, int flags)
+{
+  struct nx_drm_gem_create arg = { 0, };
+  int ret;
+
+  arg.size = (uint32_t) size;
+  arg.flags = flags;
+
+  ret = drm_command_write_read (drm_fd, DRM_NX_GEM_CREATE, &arg, sizeof (arg));
+  if (ret) {
+    perror ("drm_command_write_read\n");
+    return ret;
+  }
+  //printf("[DRM ALLOC] gem %d, size %d, flags 0x%x\n", arg.handle, size, flags);
+
+  return arg.handle;
+}
+
+static void
+free_gem (int drm_fd, int gem)
+{
+  struct drm_gem_close arg = { 0, };
+
+  arg.handle = gem;
+  drm_ioctl (drm_fd, DRM_IOCTL_GEM_CLOSE, &arg);
+}
+
+/**
+ * return dmabuf fd
+ */
+static int
+gem_to_dmafd (int drm_fd, int gem_fd)
+{
+  int ret;
+  struct drm_prime_handle arg = { 0, };
+
+  arg.handle = gem_fd;
+  ret = drm_ioctl (drm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &arg);
+  if (0 != ret) {
+    return -1;
+  }
+  return arg.fd;
+}
+
+static uint32_t
+get_flink_name (int fd, int gem)
+{
+  struct drm_gem_flink arg = { 0, };
+
+  arg.handle = gem;
+  if (drm_ioctl (fd, DRM_IOCTL_GEM_FLINK, &arg)) {
+    printf ("fail : get flink from gem:%d (DRM_IOCTL_GEM_FLINK)\n", gem);
+    return 0;
+  }
+  return arg.name;
+}
+
+static uint32_t
+gem_from_flink (int fd, uint32_t flink_name)
+{
+  struct drm_gem_open arg = { 0, };
+  /* struct nx_drm_gem_info info = { 0, }; */
+
+  arg.name = flink_name;
+  if (drm_ioctl (fd, DRM_IOCTL_GEM_OPEN, &arg)) {
+    printf ("fail : cannot open gem name=%d\n", flink_name);
+    return -EINVAL;
+  }
+  return arg.handle;
+}
+
+
+//
+//      Nexell Private Video Memory Allocator for DRM
+//
+
+#ifndef ALIGN
+#define        ALIGN(X,N)      ( (X+N-1) & (~(N-1)) )
+#endif
+
+#define        ALIGNED16(X)    ALIGN(X,16)
+
+
+//      Nexell Private Memory Allocator
+NX_MEMORY_INFO *
+NX_AllocateMemory (int size, int align)
+{
+  int gemFd = -1;
+  int dmaFd = -1;
+  int32_t flags = 0;
+  NX_MEMORY_INFO *pMem;
+
+  int drmFd = open (DRM_DEVICE_NAME, O_RDWR);
+  if (drmFd < 0)
+    return NULL;
+
+  drmDropMaster (drmFd);
+
+  gemFd = alloc_gem (drmFd, size, flags);
+  if (gemFd < 0)
+    goto ErrorExit;
+
+  dmaFd = gem_to_dmafd (drmFd, gemFd);
+  if (dmaFd < 0)
+    goto ErrorExit;
+
+  pMem = (NX_MEMORY_INFO *) calloc (1, sizeof (NX_MEMORY_INFO));
+  pMem->drmFd = drmFd;
+  pMem->dmaFd = dmaFd;
+  pMem->gemFd = gemFd;
+  pMem->flink = get_flink_name (drmFd, gemFd);
+  pMem->size = size;
+  pMem->align = align;
+  return pMem;
+
+ErrorExit:
+  if (gemFd > 0) {
+    free_gem (drmFd, gemFd);
+  }
+  if (drmFd > 0)
+    close (drmFd);
+  return NULL;
+}
+
+void
+NX_FreeMemory (NX_MEMORY_INFO * pMem)
+{
+  if (pMem) {
+    if (pMem->pBuffer) {
+      munmap (pMem->pBuffer, pMem->size);
+    }
+
+    free_gem (pMem->drmFd, pMem->gemFd);
+    close (pMem->dmaFd);
+    close (pMem->drmFd);
+    free (pMem);
+  }
+}
+
+
+//      Video Specific Allocator Wrapper
+//
+//      Suport Format & Planes
+//              YUV420 Format :
+//                      1 Plane : I420, NV12
+//                      2 Plane : NV12
+//                      3 Plane : I420
+//
+NX_VID_MEMORY_INFO *
+NX_AllocateVideoMemory (int width, int height, int32_t planes, uint32_t format,
+    int align)
+{
+  int gemFd[NX_MAX_PLANES] = { 0, };
+  int dmaFd[NX_MAX_PLANES] = { 0, };
+  int32_t flags = 0, i = 0;
+  int32_t luStride, cStride;
+  int32_t luVStride, cVStride;
+  int32_t stride[NX_MAX_PLANES];
+  int32_t size[NX_MAX_PLANES];
+  uint32_t flink[NX_MAX_PLANES];
+
+  NX_VID_MEMORY_INFO *pVidMem;
+
+  int drmFd = open (DRM_DEVICE_NAME, O_RDWR);
+  if (drmFd < 0)
+    return NULL;
+
+  drmDropMaster (drmFd);
+
+  //      Luma
+  luStride = ALIGN (width, 32);
+  luVStride = ALIGN (height, 16);
+
+  //      Chroma
+  switch (format) {
+    case DRM_FORMAT_YUV420:
+    case DRM_FORMAT_NV12:
+    case DRM_FORMAT_NV21:
+    case V4L2_PIX_FMT_YUV420M:
+    case V4L2_PIX_FMT_NV12M:
+    case V4L2_PIX_FMT_NV21M:
+      cStride = luStride / 2;
+      cVStride = ALIGN (height / 2, 16);
+      break;
+
+    case DRM_FORMAT_YUV422:
+    case DRM_FORMAT_NV16:
+    case DRM_FORMAT_NV61:
+    case V4L2_PIX_FMT_YUV422M:
+#if 0                           // Disabled by DIGNSYS
+    case V4L2_PIX_FMT_NV16M:
+    case V4L2_PIX_FMT_NV61M:
+#endif
+      cStride = luStride / 2;
+      cVStride = luVStride;
+      break;
+
+    case DRM_FORMAT_YUV444:
+      //case DRM_FORMAT_NV24:
+      //case DRM_FORMAT_NV42:
+    case V4L2_PIX_FMT_YUV444M:
+    case V4L2_PIX_FMT_NV24M:
+    case V4L2_PIX_FMT_NV42M:
+      cStride = luStride;
+      cVStride = luVStride;
+      break;
+
+    case V4L2_PIX_FMT_GREY:
+      cStride = 0;
+      cVStride = 0;
+      break;
+    default:
+      printf ("Unknown format type\n");
+      goto ErrorExit;
+  }
+
+  //      Decide Memory Size
+  switch (planes) {
+    case 1:
+      size[0] = luStride * luVStride + cStride * cVStride * 2;
+      stride[0] = luStride;
+      gemFd[0] = alloc_gem (drmFd, size[0], flags);
+      if (gemFd[0] < 0)
+        goto ErrorExit;
+      dmaFd[0] = gem_to_dmafd (drmFd, gemFd[0]);
+      if (dmaFd[0] < 0)
+        goto ErrorExit;
+      flink[0] = get_flink_name (drmFd, gemFd[0]);
+      break;
+    case 2:
+      //      Buffer 1
+      size[0] = luStride * luVStride;
+      stride[0] = luStride;
+      gemFd[0] = alloc_gem (drmFd, size[0], flags);
+      if (gemFd[0] < 0)
+        goto ErrorExit;
+      dmaFd[0] = gem_to_dmafd (drmFd, gemFd[0]);
+      if (dmaFd[0] < 0)
+        goto ErrorExit;
+      flink[0] = get_flink_name (drmFd, gemFd[0]);
+
+      //      Buffer 2
+      size[1] = cStride * cVStride * 2;
+      stride[1] = cStride * 2;
+      gemFd[1] = alloc_gem (drmFd, size[1], flags);
+      if (gemFd[1] < 0)
+        goto ErrorExit;
+      dmaFd[1] = gem_to_dmafd (drmFd, gemFd[1]);
+      if (dmaFd[1] < 0)
+        goto ErrorExit;
+      flink[1] = get_flink_name (drmFd, gemFd[1]);
+      break;
+    case 3:
+      //      Buffer 1
+      size[0] = luStride * luVStride;
+      stride[0] = luStride;
+      gemFd[0] = alloc_gem (drmFd, size[0], flags);
+      if (gemFd[0] < 0)
+        goto ErrorExit;
+      dmaFd[0] = gem_to_dmafd (drmFd, gemFd[0]);
+      if (dmaFd[0] < 0)
+        goto ErrorExit;
+      flink[0] = get_flink_name (drmFd, gemFd[0]);
+
+      //      Buffer 2
+      size[1] = cStride * cVStride;
+      stride[1] = cStride;
+      gemFd[1] = alloc_gem (drmFd, size[1], flags);
+      if (gemFd[1] < 0)
+        goto ErrorExit;
+      dmaFd[1] = gem_to_dmafd (drmFd, gemFd[1]);
+      if (dmaFd[1] < 0)
+        goto ErrorExit;
+      flink[1] = get_flink_name (drmFd, gemFd[1]);
+
+      //      Buffer 3
+      size[2] = cStride * cVStride;
+      stride[2] = cStride;
+      gemFd[2] = alloc_gem (drmFd, size[2], flags);
+      if (gemFd[2] < 0)
+        goto ErrorExit;
+      dmaFd[2] = gem_to_dmafd (drmFd, gemFd[2]);
+      if (dmaFd[2] < 0)
+        goto ErrorExit;
+      flink[2] = get_flink_name (drmFd, gemFd[2]);
+      break;
+      break;
+  }
+
+  pVidMem = (NX_VID_MEMORY_INFO *) calloc (1, sizeof (NX_VID_MEMORY_INFO));
+  pVidMem->width = width;
+  pVidMem->height = height;
+  pVidMem->align = align;
+  pVidMem->planes = planes;
+  pVidMem->format = format;
+  pVidMem->drmFd = drmFd;
+  for (i = 0; i < planes; i++) {
+    pVidMem->dmaFd[i] = dmaFd[i];
+    pVidMem->gemFd[i] = gemFd[i];
+    pVidMem->size[i] = size[i];
+    pVidMem->stride[i] = stride[i];
+    pVidMem->flink[i] = flink[i];
+  }
+  return pVidMem;
+
+ErrorExit:
+  for (i = 0; i < planes; i++) {
+    if (gemFd[i] > 0) {
+      free_gem (drmFd, gemFd[i]);
+    }
+    if (dmaFd[i] > 0) {
+      close (dmaFd[i]);
+    }
+  }
+  if (drmFd > 0)
+    close (drmFd);
+
+  return NULL;
+}
+
+void
+NX_FreeVideoMemory (NX_VID_MEMORY_INFO * pMem)
+{
+  int32_t i;
+  if (pMem) {
+    for (i = 0; i < pMem->planes; i++) {
+      if (pMem->pBuffer[i]) {
+        munmap (pMem->pBuffer[i], pMem->size[i]);
+      }
+      free_gem (pMem->drmFd, pMem->gemFd[i]);
+      close (pMem->dmaFd[i]);
+    }
+    close (pMem->drmFd);
+    free (pMem);
+  }
+}
+
+
+//
+//              Memory Mapping/Unmapping Memory
+//
+int
+NX_MapMemory (NX_MEMORY_INFO * pMem)
+{
+  void *pBuf;
+  if (!pMem)
+    return -1;
+
+  //      Already Mapped
+  if (pMem->pBuffer)
+    return -1;
+
+  pBuf =
+      mmap (0, pMem->size, PROT_READ | PROT_WRITE, MAP_SHARED, pMem->dmaFd, 0);
+  if (pBuf == MAP_FAILED) {
+    return -1;
+  }
+  pMem->pBuffer = pBuf;
+  return 0;
+}
+
+
+int
+NX_UnmapMemory (NX_MEMORY_INFO * pMem)
+{
+  if (!pMem)
+    return -1;
+
+  if (!pMem->pBuffer)
+    return -1;
+
+  if (0 != munmap (pMem->pBuffer, pMem->size))
+    return -1;
+
+  pMem->pBuffer = NULL;
+  return 0;
+}
+
+int
+NX_MapVideoMemory (NX_VID_MEMORY_INFO * pMem)
+{
+  int32_t i;
+  void *pBuf;
+  if (!pMem)
+    return -1;
+
+  //      Already Mapped
+  for (i = 0; i < pMem->planes; i++) {
+    if (pMem->pBuffer[i])
+      return -1;
+    else {
+      pBuf =
+          mmap (0, pMem->size[i], PROT_READ | PROT_WRITE, MAP_SHARED,
+          pMem->dmaFd[i], 0);
+      if (pBuf == MAP_FAILED) {
+        return -1;
+      }
+    }
+    pMem->pBuffer[i] = pBuf;
+  }
+  return 0;
+}
+
+int
+NX_UnmapVideoMemory (NX_VID_MEMORY_INFO * pMem)
+{
+  int32_t i;
+  if (!pMem)
+    return -1;
+  for (i = 0; i < pMem->planes; i++) {
+    if (pMem->pBuffer[i]) {
+      munmap (pMem->pBuffer[i], pMem->size[i]);
+    } else
+      return -1;
+  }
+  return 0;
+}
+
+int
+NX_GetGEMHandles (int drmFd, NX_VID_MEMORY_INFO * pMem,
+    uint32_t handles[NX_MAX_PLANES])
+{
+  int32_t i;
+  memset (handles, 0, sizeof (uint32_t) * NX_MAX_PLANES);
+
+  for (i = 0; i < pMem->planes; i++) {
+    handles[i] = gem_from_flink (drmFd, pMem->flink[i]);
+    if (0 > (int) handles[i]) {
+      return -1;
+    }
+  }
+  return 0;
+}
+
+int
+NX_GetGemHandle (int drmFd, NX_VID_MEMORY_INFO * pMem, int32_t plane)
+{
+  if (plane >= NX_MAX_PLANES || plane < 0)
+    return -1;
+
+  return gem_from_flink (drmFd, pMem->flink[plane]);
+}
diff --git a/src/nx_video_alloc.h b/src/nx_video_alloc.h
new file mode 100644 (file)
index 0000000..a612a4b
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016  Nexell Co., Ltd.
+ * Author: SeongO, Park <ray@nexell.co.kr>
+ */
+
+#ifndef __NX_VIDEO_ALLOC_H__
+#define __NX_VIDEO_ALLOC_H__
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+#define        NX_MAX_PLANES   4
+
+//
+//      Nexell Private Memory Type
+//
+  typedef struct
+  {
+    int drmFd;                  //      DRM Device Handle
+    int dmaFd;                  //      DMA Memory Handle
+    int gemFd;                  //      GEM Handle
+    uint32_t flink;             //      flink name
+    int32_t size;               //      Allocate Size
+    int32_t align;              //      Start Address Align
+    void *pBuffer;              //      Virtual Address Pointer
+    uint32_t reserved;
+  } NX_MEMORY_INFO, *NX_MEMORY_HANDLE;
+
+
+//
+//      Nexell Private Video Memory Type
+//
+  typedef struct
+  {
+    int32_t width;              //      Video Image's Width
+    int32_t height;             //      Video Image's Height
+    int32_t align;              //      Start address align
+    int32_t planes;             //      Number of valid planes
+    uint32_t format;            //      Pixel Format(N/A)
+
+    int drmFd;                  //      Drm Device Handle
+    int dmaFd[NX_MAX_PLANES];   //      DMA memory Handle
+    int gemFd[NX_MAX_PLANES];   //      GEM Handle
+    uint32_t flink[NX_MAX_PLANES];      //      flink name
+    int32_t size[NX_MAX_PLANES];        //      Each plane's size.
+    int32_t stride[NX_MAX_PLANES];      //      Each plane's stride.
+    void *pBuffer[NX_MAX_PLANES];       //      virtual address.
+    uint32_t reserved[NX_MAX_PLANES];   //      for debugging or future user.
+  } NX_VID_MEMORY_INFO, *NX_VID_MEMORY_HANDLE;
+
+//      Nexell Private Memory Allocator
+  NX_MEMORY_INFO *NX_AllocateMemory (int size, int align);
+  void NX_FreeMemory (NX_MEMORY_INFO * pMem);
+
+//      Video Specific Allocator Wrapper
+  NX_VID_MEMORY_INFO *NX_AllocateVideoMemory (int width, int height,
+      int32_t planes, uint32_t format, int align);
+  void NX_FreeVideoMemory (NX_VID_MEMORY_INFO * pMem);
+
+  int NX_MapMemory (NX_MEMORY_INFO * pMem);
+  int NX_UnmapMemory (NX_MEMORY_INFO * pMem);
+
+  int NX_MapVideoMemory (NX_VID_MEMORY_INFO * pMem);
+  int NX_UnmapVideoMemory (NX_VID_MEMORY_INFO * pMem);
+
+  int NX_GetGEMHandles (int drmFd, NX_VID_MEMORY_INFO * pMem,
+      uint32_t handles[NX_MAX_PLANES]);
+  int NX_GetGemHandle (int drmFd, NX_VID_MEMORY_INFO * pMem, int32_t plane);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif //      __NX_VIDEO_ALLOC_H__
diff --git a/src/nx_video_api.h b/src/nx_video_api.h
new file mode 100644 (file)
index 0000000..2174e4e
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ *     Copyright (C) 2016 Nexell Co. All Rights Reserved
+ *     Nexell Co. Proprietary & Confidential
+ *
+ *     NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE
+ *  AND        WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING
+ *  BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
+ *  FOR A PARTICULAR PURPOSE.
+ *
+ *     File            : nx_video_api.h
+ *     Brief           : V4L2 Video En/Decoder
+ *     Author          : SungWon Jo (doriya@nexell.co.kr)
+ *     History         : 2016.04.25 : Create
+ */
+
+#ifndef __NX_VIDEO_API_H__
+#define __NX_VIDEO_API_H__
+
+#include <stdint.h>
+#include <nx_video_alloc.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define MAX_FRAME_BUFFER_NUM           32
+#define MAX_IMAGE_WIDTH                                1920
+#define MAX_IMAGE_HEIGHT                       1088
+
+
+  typedef struct NX_V4L2ENC_INFO *NX_V4L2ENC_HANDLE;
+  typedef struct NX_V4L2DEC_INFO *NX_V4L2DEC_HANDLE;
+
+  enum
+  {
+    PIC_TYPE_I = 0,
+    PIC_TYPE_P = 1,
+    PIC_TYPE_B = 2,
+    PIC_TYPE_VC1_BI = 3,
+    PIC_TYPE_SKIP = 5,
+    PIC_TYPE_IDR = 6,
+#if 0
+    /* TBD */
+    PIC_TYPE_VC1_B = 3,
+    PIC_TYPE_D = 3,             /* D picture in mpeg2, and is only composed of DC codfficients */
+    PIC_TYPE_S = 3,             /* S picture in mpeg4, and is an acronym of Sprite. and used for GMC */
+    PIC_TYPE_MP4_P_SKIP_NOT_CODED = 4,  /* Not Coded P Picture at mpeg4 packed mode */
+#endif
+    PIC_TYPE_UNKNOWN = 0xff,
+  };
+
+  enum
+  {
+    NONE_FIELD = 0,
+    FIELD_INTERLACED = 1,
+    TOP_FIELD_FIRST = 2,
+    BOTTOM_FIELD_FIRST = 3,
+  };
+
+  enum
+  {
+    DECODED_FRAME = 0,
+    DISPLAY_FRAME = 1
+  };
+
+  typedef enum
+  {
+    VID_CHG_KEYFRAME = (1 << 1),        /* Key frame interval */
+    VID_CHG_BITRATE = (1 << 2), /* Bit Rate */
+    VID_CHG_FRAMERATE = (1 << 3),       /* Frame Rate */
+    VID_CHG_INTRARF = (1 << 4), /* Intra Refresh */
+  } VID_ENC_CHG_PARA_E;
+
+  typedef struct
+  {
+    uint32_t dispLeft;          /* Specifies the x-coordinate of the upper-left corner of the frame memory */
+    uint32_t dispTop;           /* Specifies the y-coordinate of the upper-left corner of the frame memory */
+    uint32_t dispRight;         /* Specifies the x-coordinate of the lower-right corner of the frame memory */
+    uint32_t dispBottom;        /* Specifies the y-coordinate of the lower-right corner of the frame memory */
+  } IMG_DISP_INFO;
+
+  typedef struct tNX_V4L2ENC_PARA
+  {
+    int32_t width;              /* Width of image */
+    int32_t height;             /* Height of image */
+    int32_t keyFrmInterval;     /* Size of key frame interval */
+    int32_t fpsNum;             /* Frame per second */
+    int32_t fpsDen;
+
+    uint32_t profile;
+
+    /* Rate Control Parameters (They are valid only when CBR.) */
+    uint32_t bitrate;           /* Target bitrate in bits per second */
+    int32_t maximumQp;          /* Maximum quantization parameter in CBR */
+    /* In MPEG-4/H.263 mode, available range is 3 to 31. In H.264 mode, the allowed range is 13 to 51. */
+    int32_t disableSkip;        /* Disable rate control automatic skip frame */
+    int32_t RCDelay;            /* Reference decoder initial buffer removal delay in mili-second(ms) */
+    /* Valid value is 0 ~ 0x7FFF. */
+    /* 0 does not check reference decoder buffer delay constraint. */
+    uint32_t rcVbvSize;         /* Reference decoder buffer size in bits */
+    /* This value is ignored if RCDelay is 0. */
+    /* Valid value is 0 ~ 0x7FFFFFFF. */
+    /* 0 dose not check Reference decoder buffer size constraint. */
+    int32_t gammaFactor;        /* A gamma is the smoothing factor in the estimation. A value for gamma is factor * 32768, factor value is selected from the 0 <= factor >= 1. */
+    /* If the factor value getting close to 0, Qp will be changed slowly. If the factor value getting close to 1, Qp will be chgnged quickly. */
+    /* Default gamma value is 0.75 * 32768. */
+    int32_t initialQp;          /* Initial quantization parameter */
+
+    int32_t numIntraRefreshMbs; /* Intra MB refresh number(Cyclic Intra Refresh) */
+    /* It must be less than encoded Mbs(width * height / 256) */
+    int32_t searchRange;        /* search range of motion estimaiton(0 : 128 x 64, 1 : 64 x 32, 2 : 32 x 16, 3 : 16 x 16) */
+
+    /* for H.264 Encoder */
+    int32_t enableAUDelimiter;  /* Insert Access Unit Delimiter before NAL unit. */
+
+    uint32_t imgFormat;         /* Fourcc of Input Image */
+    uint32_t imgBufferNum;      /* Number of Input Image Buffer */
+    uint32_t imgPlaneNum;       /* Number of Input Image Plane */
+
+    /* for JPEG Specific Parameter */
+    int32_t rotAngle;
+    int32_t mirDirection;       /* 0 : not mir, 1 : horizontal mir, 2 : vertical mir, 3 : horizontal & vertical mir */
+
+    int32_t jpgQuality;         /* 1 ~ 100 */
+  } NX_V4L2ENC_PARA;
+
+  typedef struct tNX_V4L2ENC_IN
+  {
+    NX_VID_MEMORY_HANDLE pImage;        /* Original captured frame's pointer */
+    int32_t imgIndex;
+    uint64_t timeStamp;         /* Time stamp */
+    int32_t forcedIFrame;       /* Flag of forced intra frame */
+    int32_t forcedSkipFrame;    /* Flag of forced skip frame */
+    int32_t quantParam;         /* User quantization parameter(It is valid only when VBR.) */
+  } NX_V4L2ENC_IN;
+
+  typedef struct tNX_V4L2ENC_OUT
+  {
+    uint8_t *strmBuf;           /* compressed stream's pointer */
+    int32_t strmSize;           /* compressed stream's size */
+    int32_t frameType;          /* Frame type */
+    NX_VID_MEMORY_INFO reconImg;        /* TBD. Reconstructed image's pointer */
+  } NX_V4L2ENC_OUT;
+
+  typedef struct tNX_V4L2ENC_CHG_PARA
+  {
+    int32_t chgFlg;
+    int32_t keyFrmInterval;     /* Size of key frame interval */
+    int32_t bitrate;            /* Target bitrate in bits/second */
+    int32_t fpsNum;             /* Frame per second */
+    int32_t fpsDen;
+    int32_t disableSkip;        /* Disable skip frame mode */
+    int32_t numIntraRefreshMbs; /* Intra MB refresh number(Cyclic Intra Refresh) */
+  } NX_V4L2ENC_CHG_PARA;
+
+  typedef struct tNX_V4L2DEC_SEQ_IN
+  {
+    uint32_t imgFormat;         /* Fourcc for Decoded Image */
+    uint32_t imgPlaneNum;       /* Number of Input Image Plane */
+
+    uint8_t *seqBuf;            /* Sequence header's pointer */
+    int32_t seqSize;            /* Sequence header's size */
+
+    uint64_t timeStamp;
+
+    int32_t width;
+    int32_t height;
+
+    /* for External Buffer(optional) */
+    NX_VID_MEMORY_HANDLE *pMemHandle;   /* Frame buffer for external buffer mode */
+
+    int32_t numBuffers;         /* Internal buffer mode : number of extra buffer */
+    /* External buffer mode : number of external frame buffer */
+
+    /* for JPEG Decoder */
+    int32_t thumbnailMode;      /* 0 : jpeg mode, 1 : thumbnail mode */
+  } NX_V4L2DEC_SEQ_IN;
+
+  typedef struct tNX_V4L2DEC_SEQ_OUT
+  {
+    int32_t minBuffers;         /* Needed minimum number for decoder */
+    int32_t width;
+    int32_t height;
+    int32_t interlace;
+
+    int32_t frameRateNum;       /* Frame Rate Numerator */
+    int32_t frameRateDen;       /* Frame Rate Denominator (-1 : no information) */
+
+    int32_t imgFourCC;          /* FourCC according to decoded image type */
+    int32_t thumbnailWidth;     /* Width of thumbnail image */
+    int32_t thumbnailHeight;    /* Height of thumbnail image */
+
+    uint32_t usedByte;
+
+    IMG_DISP_INFO dispInfo;
+  } NX_V4L2DEC_SEQ_OUT;
+
+  typedef struct tNX_V4L2DEC_IN
+  {
+    uint8_t *strmBuf;           /* A compressed stream's pointer */
+    int32_t strmSize;           /* A compressed stream's size */
+    uint64_t timeStamp;         /* Time stamp */
+    int32_t eos;
+
+    /* for JPEG Decoder */
+    int32_t downScaleWidth;     /* 0 : No scaling, 1 : 1/2 down scaling, 2 : 1/4 down scaling, 3 : 1/8 down scaling */
+    int32_t downScaleHeight;    /* 0 : No scaling, 1 : 1/2 down scaling, 2 : 1/4 down scaling, 3 : 1/8 down scaling      */
+  } NX_V4L2DEC_IN;
+
+  typedef struct tNX_V4L2DEC_OUT
+  {
+    NX_VID_MEMORY_INFO hImg;    /* Decoded frame's pointer */
+    IMG_DISP_INFO dispInfo;
+
+    int32_t decIdx;             /* Decode Index */
+    int32_t dispIdx;            /* Display Index */
+
+    uint32_t usedByte;
+    int32_t picType[2];         /* Picture Type */
+    uint64_t timeStamp[2];      /* Time stamp */
+    int32_t interlace[2];
+    int32_t outFrmReliable_0_100[2];    /* Percentage of MB's are reliable ranging from 0[all damage] to 100 [all clear] */
+  } NX_V4L2DEC_OUT;
+
+
+/*
+ *     V4L2 Encoder
+ */
+  NX_V4L2ENC_HANDLE NX_V4l2EncOpen (uint32_t codecType);
+  int32_t NX_V4l2EncClose (NX_V4L2ENC_HANDLE hEnc);
+  int32_t NX_V4l2EncInit (NX_V4L2ENC_HANDLE hEnc, NX_V4L2ENC_PARA * pEncPara);
+  int32_t NX_V4l2EncGetSeqInfo (NX_V4L2ENC_HANDLE hEnc, uint8_t ** ppSeqBuf,
+      int32_t * iSeqSize);
+  int32_t NX_V4l2EncEncodeFrame (NX_V4L2ENC_HANDLE hEnc, NX_V4L2ENC_IN * pEncIn,
+      NX_V4L2ENC_OUT * pEncOut);
+  int32_t NX_V4L2EncChangeParameter (NX_V4L2ENC_HANDLE hEnc,
+      NX_V4L2ENC_CHG_PARA * pChgPara);
+
+
+/*
+ *     V4L2 Decoder
+ */
+  NX_V4L2DEC_HANDLE NX_V4l2DecOpen (uint32_t codecType);
+  int32_t NX_V4l2DecClose (NX_V4L2DEC_HANDLE hDec);
+  int32_t NX_V4l2DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec,
+      NX_V4L2DEC_SEQ_IN * pSeqIn, NX_V4L2DEC_SEQ_OUT * pSeqOut);
+  int32_t NX_V4l2DecInit (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn);
+  int32_t NX_V4l2DecDecodeFrame (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
+      NX_V4L2DEC_OUT * pDecOut);
+  int32_t NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec,
+      NX_VID_MEMORY_HANDLE hFrameBuf, int32_t iFrameIdx);
+  int32_t NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec);
+  int32_t NX_DecGetFrameType (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
+      uint32_t codecType, int32_t * piFrameType);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                          /* __NX_VIDEO_API_H__ */
diff --git a/src/nx_video_dec.c b/src/nx_video_dec.c
new file mode 100644 (file)
index 0000000..cfb013a
--- /dev/null
@@ -0,0 +1,1357 @@
+/*
+ *     Copyright (C) 2016 Nexell Co. All Rights Reserved
+ *     Nexell Co. Proprietary & Confidential
+ *
+ *     NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE
+ *  AND        WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING
+ *  BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
+ *  FOR A PARTICULAR PURPOSE.
+ *
+ *     File            : nx_video_api.c
+ *     Brief           : V4L2 Video Decoder
+ *     Author          : SungWon Jo (doriya@nexell.co.kr)
+ *     History         : 2016.04.25 : Create
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <linux/videodev2.h>
+#include <linux/videodev2_nxp_media.h>
+
+#include <nx_video_alloc.h>
+#include <nx_video_api.h>
+
+
+/*----------------------------------------------------------------------------*/
+#define NX_V4L2_DEC_NAME               "nx-vpu-dec"
+#define VIDEODEV_MINOR_MAX             63
+#define STREAM_BUFFER_NUM              1
+
+
+struct NX_V4L2DEC_INFO
+{
+  int fd;
+  uint32_t codecType;
+  int32_t width;
+  int32_t height;
+
+  int32_t useExternalFrameBuffer;
+  int32_t numFrameBuffers;
+  NX_VID_MEMORY_HANDLE hImage[MAX_FRAME_BUFFER_NUM];
+
+  NX_MEMORY_HANDLE hStream[STREAM_BUFFER_NUM];
+
+  /* Initialize Output Information        */
+  uint8_t pSeqData[1024];       /* SPS PPS (H.264) or Decoder Specific Information(for MPEG4) */
+  int32_t seqDataSize;
+
+  IMG_DISP_INFO dispInfo;
+
+  int32_t planesNum;
+
+  int32_t frameCnt;
+
+  /* For MPEG4 */
+  int vopTimeBits;
+
+  /* For VC1 */
+  int32_t iInterlace;
+};
+
+
+/*
+ *             Find Device Node
+ */
+
+/*----------------------------------------------------------------------------*/
+static int32_t
+V4l2DecOpen (void)
+{
+  int fd = -1;
+
+  bool found = false;
+  struct stat s;
+  FILE *stream_fd;
+  char filename[64], name[64];
+  int32_t i = 0;
+
+  while (!found && (i <= VIDEODEV_MINOR_MAX)) {
+    /* video device node */
+    sprintf (filename, "/dev/video%d", i);
+
+    /* if the node is video device */
+    if ((lstat (filename, &s) == 0) && S_ISCHR (s.st_mode)
+        && ((int) ((unsigned short) (s.st_rdev) >> 8) == 81)) {
+      /* open sysfs entry */
+      sprintf (filename, "/sys/class/video4linux/video%d/name", i);
+      stream_fd = fopen (filename, "r");
+      if (stream_fd == NULL) {
+        printf ("failed to open sysfs entry for videodev \n");
+        i++;
+        continue;
+      }
+
+      /* read sysfs entry for device name */
+      if (fgets (name, sizeof (name), stream_fd) == 0) {
+        printf ("failed to read sysfs entry for videodev\n");
+      } else {
+        if (strncmp (name, NX_V4L2_DEC_NAME, strlen (NX_V4L2_DEC_NAME)) == 0) {
+          printf ("node found for device %s: /dev/video%d \n", NX_V4L2_DEC_NAME,
+              i);
+          found = true;
+        }
+      }
+
+      fclose (stream_fd);
+    }
+
+    i++;
+  }
+
+  if (found) {
+    sprintf (filename, "/dev/video%d", i - 1);
+    fd = open (filename, O_RDWR);
+  }
+
+  return fd;
+}
+
+
+#ifndef MKTAG
+#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
+#endif
+
+#ifndef PUT_LE32
+#define PUT_LE32(_p, _var) \
+       *_p++ = (uint8_t)((_var) >> 0); \
+       *_p++ = (uint8_t)((_var) >> 8); \
+       *_p++ = (uint8_t)((_var) >> 16); \
+       *_p++ = (uint8_t)((_var) >> 24);
+#endif
+
+#ifndef PUT_BE32
+#define PUT_BE32(_p, _var) \
+       *_p++ = (uint8_t)((_var) >> 24); \
+       *_p++ = (uint8_t)((_var) >> 16); \
+       *_p++ = (uint8_t)((_var) >> 8); \
+       *_p++ = (uint8_t)((_var) >> 0);
+#endif
+
+#ifndef PUT_LE16
+#define PUT_LE16(_p, _var) \
+       *_p++ = (uint8_t)((_var) >> 0); \
+       *_p++ = (uint8_t)((_var) >> 8);
+#endif
+
+#ifndef PUT_BE16
+#define PUT_BE16(_p, _var) \
+       *_p++ = (uint8_t)((_var) >> 8); \
+       *_p++ = (uint8_t)((_var) >> 0);
+#endif
+
+
+typedef struct
+{
+  uint32_t dwUsedBits;
+  uint8_t *pbyStart;
+  uint32_t dwPktSize;
+} VLD_STREAM;
+
+static int32_t
+vld_count_leading_zero (uint32_t dwWord)
+{
+  int32_t iLZ = 0;
+
+  if ((dwWord >> (32 - 16)) == 0)
+    iLZ = 16;
+  if ((dwWord >> (32 - 8 - iLZ)) == 0)
+    iLZ += 8;
+  if ((dwWord >> (32 - 4 - iLZ)) == 0)
+    iLZ += 4;
+  if ((dwWord >> (32 - 2 - iLZ)) == 0)
+    iLZ += 2;
+  if ((dwWord >> (32 - 1 - iLZ)) == 0)
+    iLZ += 1;
+
+  return iLZ;
+}
+
+static uint32_t
+vld_show_bits (VLD_STREAM * pstVldStm, int32_t iBits)
+{
+  uint32_t dwUsedBits = pstVldStm->dwUsedBits;
+  int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
+  uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
+  uint32_t dwRead;
+
+  dwRead = *pbyRead++ << 24;
+  if (iBits > iBitCnt) {
+    dwRead += *pbyRead++ << 16;
+    if (iBits > iBitCnt + 8) {
+      dwRead += *pbyRead++ << 8;
+      if (iBits > iBitCnt + 16)
+        dwRead += *pbyRead++;
+    }
+  }
+
+  return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
+}
+
+static uint32_t
+vld_get_bits (VLD_STREAM * pstVldStm, int32_t iBits)
+{
+  uint32_t dwUsedBits = pstVldStm->dwUsedBits;
+  int32_t iBitCnt = 8 - (dwUsedBits & 0x7);
+  uint8_t *pbyRead = (uint8_t *) pstVldStm->pbyStart + (dwUsedBits >> 3);
+  uint32_t dwRead;
+
+  pstVldStm->dwUsedBits += iBits;
+
+  dwRead = *pbyRead++ << 24;
+  if (iBits > iBitCnt) {
+    dwRead += *pbyRead++ << 16;
+    if (iBits > iBitCnt + 8) {
+      dwRead += *pbyRead++ << 8;
+      if (iBits > iBitCnt + 16)
+        dwRead += *pbyRead++;
+    }
+  }
+
+  return (dwRead << (8 - iBitCnt)) >> (32 - iBits);
+}
+
+static void
+vld_flush_bits (VLD_STREAM * pstVldStm, int iBits)
+{
+  pstVldStm->dwUsedBits += iBits;
+}
+
+static uint32_t
+vld_get_uev (VLD_STREAM * pstVldStm)
+{
+  int32_t iLZ = vld_count_leading_zero (vld_show_bits (pstVldStm, 32));
+
+  vld_flush_bits (pstVldStm, iLZ);
+  return (vld_get_bits (pstVldStm, iLZ + 1) - 1);
+}
+
+static void
+Mp4DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
+    int32_t iStreamSize)
+{
+  uint8_t *pbyStrm = pbyStream;
+  uint32_t uPreFourByte = (uint32_t) - 1;
+
+  hDec->vopTimeBits = 0;
+
+  do {
+    if (pbyStrm >= (pbyStream + iStreamSize))
+      break;
+
+    uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
+
+    if (uPreFourByte >= 0x00000120 && uPreFourByte <= 0x0000012F) {
+      VLD_STREAM stStrm = { 0, pbyStrm, iStreamSize };
+      int32_t i;
+
+      vld_flush_bits (&stStrm, 1 + 8);  /* random_accessible_vol, video_object_type_indication */
+      if (vld_get_bits (&stStrm, 1))    /* is_object_layer_identifier */
+        vld_flush_bits (&stStrm, 4 + 3);        /* video_object_layer_verid, video_object_layer_priority */
+
+      if (vld_get_bits (&stStrm, 4) == 0xF)     /* aspect_ratio_info */
+        vld_flush_bits (&stStrm, 8 + 8);        /* par_width, par_height */
+
+      if (vld_get_bits (&stStrm, 1)) {  /* vol_control_parameters */
+        if (vld_get_bits (&stStrm, 2 + 1 + 1) & 1) {    /* chroma_format, low_delay, vbv_parameters */
+          vld_flush_bits (&stStrm, 15 + 1);     /* first_half_bit_rate, marker_bit */
+          vld_flush_bits (&stStrm, 15 + 1);     /* latter_half_bit_rate, marker_bit */
+          vld_flush_bits (&stStrm, 15 + 1);     /* first_half_vbv_buffer_size, marker_bit */
+          vld_flush_bits (&stStrm, 3 + 11 + 1); /* latter_half_vbv_buffer_size, first_half_vbv_occupancy, marker_bit */
+          vld_flush_bits (&stStrm, 15 + 1);     /* latter_half_vbv_occupancy, marker_bit */
+        }
+      }
+
+      vld_flush_bits (&stStrm, 2 + 1);  /* video_object_layer_shape, marker_bit */
+
+      for (i = 0; i < 16; i++)  /* vop_time_increment_resolution */
+        if (vld_get_bits (&stStrm, 1))
+          break;
+      hDec->vopTimeBits = 16 - i;
+      break;
+    }
+  } while (1);
+}
+
+static int32_t
+Mp4DecParseFrameHeader (NX_V4L2DEC_HANDLE hDec, uint8_t * pbyStream,
+    int32_t iStreamSize)
+{
+  VLD_STREAM stStrm = { 0, pbyStream, iStreamSize };
+  int32_t iSize = iStreamSize;
+
+  if (vld_get_bits (&stStrm, 32) == 0x000001B6) {
+    vld_flush_bits (&stStrm, 2);        /* vop_coding_type */
+
+    do {
+      if (vld_get_bits (&stStrm, 1) == 0)
+        break;
+    } while (stStrm.dwUsedBits < ((uint32_t) iStreamSize << 3));
+
+    vld_flush_bits (&stStrm, 1 + hDec->vopTimeBits + 1);        /* marker_bits, vop_time_increment, marker_bits */
+
+    if (vld_get_bits (&stStrm, 1) == 0) /* vop_coded */
+      iSize = 0;
+  }
+
+  return iSize;
+}
+
+static int32_t
+GetSequenceHeader (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
+{
+  uint8_t *pbySrc = pSeqIn->seqBuf;
+  uint8_t *pbyDst = (uint8_t *) hDec->hStream[0]->pBuffer;
+  int32_t iSize = pSeqIn->seqSize;
+
+  switch (hDec->codecType) {
+    case V4L2_PIX_FMT_H264:
+      if (pSeqIn->seqSize > 0) {
+        memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
+
+        if ((pbySrc[2] == 0) && (pbySrc[7] > 51))
+          pbyDst[7] = 51;
+        else if ((pbySrc[2] == 1) && (pbySrc[6] > 51))
+          pbyDst[6] = 51;
+        break;
+      } else
+        return -1;
+
+    case V4L2_PIX_FMT_DIV3:
+      if (pSeqIn->seqSize == 0) {
+        if ((pSeqIn->width > 0) && (pSeqIn->height > 0)) {
+          PUT_LE32 (pbyDst, MKTAG ('C', 'N', 'M', 'V'));
+          PUT_LE16 (pbyDst, 0x00);      /* version */
+          PUT_LE16 (pbyDst, 0x20);      /* length of header in bytes */
+          PUT_LE32 (pbyDst, MKTAG ('D', 'I', 'V', '3'));        /* codec FourCC */
+          PUT_LE16 (pbyDst, pSeqIn->width);
+          PUT_LE16 (pbyDst, pSeqIn->height);
+          PUT_LE32 (pbyDst, 0); /* frame rate */
+          PUT_LE32 (pbyDst, 0); /* time scale(?) */
+          PUT_LE32 (pbyDst, 0); /* number of frames in file */
+          PUT_LE32 (pbyDst, 0); /* unused */
+          iSize += 32;
+        } else
+          return -1;
+      } else {
+        PUT_BE32 (pbyDst, pSeqIn->seqSize);
+        iSize += 4;
+        memcpy (pbyDst, pbyDst, pSeqIn->seqSize);
+      }
+      break;
+
+    case V4L2_PIX_FMT_WMV9:
+      if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
+#ifdef RCV_V2
+        PUT_LE32 (pbyDst, (0xC5 << 24) | 0x00); /* version */
+#else
+        /* RCV_V1 */
+        PUT_LE32 (pbyDst, (0x85 << 24) | 0x00);
+#endif
+
+        PUT_LE32 (pbyDst, pSeqIn->seqSize);
+        memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
+        pbyDst += pSeqIn->seqSize;
+        PUT_LE32 (pbyDst, pSeqIn->height);
+        PUT_LE32 (pbyDst, pSeqIn->width);
+        iSize += 16;
+#ifdef RCV_V2
+        PUT_LE32 (pbyDst, 12);
+        /* STRUCT_B_FRIST (LEVEL:3|CBR:1:RESERVE:4:HRD_BUFFER|24) */
+        PUT_LE32 (pbyDst, 2 << 29 | 1 << 28 | 0x80 << 24 | 1 << 0);
+        PUT_LE32 (pbyDst, 0);   /* bitrate */
+        PUT_LE32 (pbyDst, 0);   /* framerate */
+        iSize += 16;
+#endif
+        break;
+      } else
+        return -1;
+
+    case V4L2_PIX_FMT_RV8:
+    case V4L2_PIX_FMT_RV9:
+      if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
+        iSize += 26;
+
+        PUT_BE32 (pbyDst, iSize);       /* Length */
+        PUT_LE32 (pbyDst, MKTAG ('V', 'I', 'D', 'O'));  /* MOFTag */
+
+        if (hDec->codecType == V4L2_PIX_FMT_RV8) {
+          PUT_LE32 (pbyDst, MKTAG ('R', 'V', '3', '0'));
+        } else {
+          PUT_LE32 (pbyDst, MKTAG ('R', 'V', '4', '0'));
+        }
+
+        PUT_BE16 (pbyDst, pSeqIn->width);
+        PUT_BE16 (pbyDst, pSeqIn->height);
+        PUT_BE16 (pbyDst, 0x0c);        /* BitCount */
+        PUT_BE16 (pbyDst, 0x00);        /* PadWidth */
+        PUT_BE16 (pbyDst, 0x00);        /* PadHeight */
+        PUT_LE32 (pbyDst, 0);   /* framerate */
+        memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
+        break;
+      } else
+        return -1;
+
+    case V4L2_PIX_FMT_VP8:
+      if ((pSeqIn->seqSize > 0) && (pSeqIn->width > 0) && (pSeqIn->height > 0)) {
+        PUT_LE32 (pbyDst, MKTAG ('D', 'K', 'I', 'F'));  /* signature 'DKIF' */
+        PUT_LE16 (pbyDst, 0x00);        /* version */
+        PUT_LE16 (pbyDst, 0x20);        /* length of header in bytes */
+        PUT_LE32 (pbyDst, MKTAG ('V', 'P', '8', '0'));  /* codec FourCC */
+        PUT_LE16 (pbyDst, pSeqIn->width);       /* width */
+        PUT_LE16 (pbyDst, pSeqIn->height);      /* height */
+        PUT_LE32 (pbyDst, 0);   /* frame rate */
+        PUT_LE32 (pbyDst, 0);   /* time scale(?) */
+        PUT_LE32 (pbyDst, 0);   /* number of frames in file */
+        PUT_LE32 (pbyDst, 0);   /* unused */
+        iSize += 32;
+
+        PUT_LE32 (pbyDst, pSeqIn->seqSize);
+        PUT_LE32 (pbyDst, 0);
+        PUT_LE32 (pbyDst, 0);
+        memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
+        iSize += 12;
+        break;
+      } else
+        return -1;
+
+    case V4L2_PIX_FMT_XVID:
+    case V4L2_PIX_FMT_DIVX:
+    case V4L2_PIX_FMT_DIV4:
+    case V4L2_PIX_FMT_DIV5:
+    case V4L2_PIX_FMT_DIV6:
+    case V4L2_PIX_FMT_MPEG4:
+      Mp4DecParseVideoCfg (hDec, pbySrc, pSeqIn->seqSize);
+
+    default:
+      if (pSeqIn->seqSize > 0)
+        memcpy (pbyDst, pbySrc, pSeqIn->seqSize);
+      else
+        return -1;
+  }
+
+  return iSize;
+}
+
+static int32_t
+GetFrameStream (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn, int32_t * idx)
+{
+  int32_t iSize = pDecIn->strmSize;
+  uint8_t *pbySrc = pDecIn->strmBuf;
+  uint8_t *pbyDst;
+
+  if (iSize <= 0)
+    return 0;
+
+  *idx = hDec->frameCnt % STREAM_BUFFER_NUM;
+  pbyDst = (uint8_t *) hDec->hStream[*idx]->pBuffer;
+
+  switch (hDec->codecType) {
+    case V4L2_PIX_FMT_H264:
+      memcpy (pbyDst, pbySrc, iSize);
+      if (iSize > 8) {
+        if ((pbySrc[2] == 0) && ((pbySrc[4] & 0x1F) == 7) && (pbySrc[7] > 51))
+          pbyDst[7] = 51;
+        else if ((pbySrc[2] == 1) && ((pbySrc[3] & 0x1F) == 7)
+            && (pbySrc[6] > 51))
+          pbyDst[6] = 51;
+      }
+      break;
+
+    case V4L2_PIX_FMT_WVC1:
+      /* check start code as prefix (0x00, 0x00, 0x01) */
+      if (pbySrc[0] != 0 || pbySrc[1] != 0 || pbySrc[2] != 1) {
+        *pbyDst++ = 0x00;
+        *pbyDst++ = 0x00;
+        *pbyDst++ = 0x01;
+        *pbyDst++ = 0x0D;
+        memcpy (pbyDst, pbySrc, iSize);
+        iSize += 4;
+      } else {
+        /* no extra header size, there is start code in input stream */
+        memcpy (pbyDst, pbySrc, iSize);
+      }
+      break;
+
+    case V4L2_PIX_FMT_WMV9:
+      PUT_LE32 (pbyDst, iSize | 0);     /* Key Frame = 0x80000000 */
+      iSize += 4;
+
+#ifdef RCV_V2
+      PUT_LE32 (pbyDst, 0);
+      iSize += 4;
+#endif
+
+      memcpy (pbyDst, pbySrc, pDecIn->strmSize);
+      break;
+
+    case V4L2_PIX_FMT_RV8:
+    case V4L2_PIX_FMT_RV9:
+    {
+      int32_t cSlice, nSlice;
+      int32_t i, val, offset;
+
+      cSlice = pbySrc[0] + 1;
+      nSlice = iSize - 1 - (cSlice * 8);
+
+      PUT_BE32 (pbyDst, nSlice);
+      PUT_LE32 (pbyDst, 0);
+      PUT_BE16 (pbyDst, 0);     /* frame number */
+      PUT_BE16 (pbyDst, 0x02);  /* Flags */
+      PUT_BE32 (pbyDst, 0x00);  /* LastPacket */
+      PUT_BE32 (pbyDst, cSlice);        /* NumSegments */
+
+      offset = 1;
+      for (i = 0; i < cSlice; i++) {
+        val =
+            (pbySrc[offset + 3] << 24) | (pbySrc[offset +
+                2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
+        PUT_BE32 (pbyDst, val); /* isValid */
+        offset += 4;
+        val =
+            (pbySrc[offset + 3] << 24) | (pbySrc[offset +
+                2] << 16) | (pbySrc[offset + 1] << 8) | pbySrc[offset];
+        PUT_BE32 (pbyDst, val); /* Offset */
+        offset += 4;
+      }
+
+      memcpy (pbyDst, pbySrc + (1 + (cSlice * 8)), nSlice);
+      iSize = 20 + (cSlice * 8) + nSlice;
+    }
+      break;
+
+    case V4L2_PIX_FMT_DIV3:
+    case V4L2_PIX_FMT_VP8:
+      PUT_LE32 (pbyDst, iSize);
+      PUT_LE32 (pbyDst, 0);
+      PUT_LE32 (pbyDst, 0);
+      memcpy (pbyDst, pbySrc, iSize);
+      iSize += 12;
+      break;
+
+    case V4L2_PIX_FMT_XVID:
+    case V4L2_PIX_FMT_DIVX:
+    case V4L2_PIX_FMT_DIV4:
+    case V4L2_PIX_FMT_DIV5:
+    case V4L2_PIX_FMT_DIV6:
+    case V4L2_PIX_FMT_MPEG4:
+      /* For PB Frame */
+      if (hDec->vopTimeBits > 0) {
+        iSize = Mp4DecParseFrameHeader (hDec, pbySrc, iSize);
+      }
+
+    default:
+      memcpy ((void *) pbyDst, (void *) pbySrc, iSize);
+  }
+
+  return iSize;
+}
+
+
+/*
+ *             V4L2 Decoder
+ */
+
+/*----------------------------------------------------------------------------*/
+NX_V4L2DEC_HANDLE
+NX_V4l2DecOpen (uint32_t codecType)
+{
+  NX_V4L2DEC_HANDLE hDec =
+      (NX_V4L2DEC_HANDLE) malloc (sizeof (struct NX_V4L2DEC_INFO));
+
+  memset (hDec, 0, sizeof (struct NX_V4L2DEC_INFO));
+
+  hDec->fd = V4l2DecOpen ();
+  if (hDec->fd <= 0) {
+    printf ("Failed to open video decoder device\n");
+    goto ERROR_EXIT;
+  }
+
+  /* Query capabilities of Device */
+  {
+    struct v4l2_capability cap;
+
+    memset (&cap, 0, sizeof (cap));
+
+    if (ioctl (hDec->fd, VIDIOC_QUERYCAP, &cap) != 0) {
+      printf ("failed to ioctl: VIDIOC_QUERYCAP\n");
+      goto ERROR_EXIT;
+    }
+  }
+
+  hDec->codecType = codecType;
+
+  return hDec;
+
+ERROR_EXIT:
+  free (hDec);
+
+  return NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2DecClose (NX_V4L2DEC_HANDLE hDec)
+{
+  int32_t ret = 0, i;
+
+  if (NULL == hDec) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  {
+    enum v4l2_buf_type type;
+
+    type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
+      printf ("failed to ioctl: VIDIOC_STREAMOFF(Stream)\n");
+      return -1;
+    }
+
+    type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
+      printf ("failed to ioctl: VIDIOC_STREAMOFF(Image)\n");
+      return -1;
+    }
+
+    for (i = 0; i < STREAM_BUFFER_NUM; i++)
+      NX_FreeMemory (hDec->hStream[i]);
+
+    close (hDec->fd);
+  }
+
+  if (hDec->useExternalFrameBuffer == 0) {
+    for (i = 0; i < hDec->numFrameBuffers; i++) {
+      if (hDec->hImage[i]) {
+        NX_FreeVideoMemory (hDec->hImage[i]);
+        hDec->hImage[i] = NULL;
+      }
+    }
+  }
+
+  free (hDec);
+
+  return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2DecParseVideoCfg (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn,
+    NX_V4L2DEC_SEQ_OUT * pSeqOut)
+{
+  int32_t imgWidth = pSeqIn->width;
+  int32_t imgHeight = pSeqIn->height;
+
+  memset (pSeqOut, 0, sizeof (NX_V4L2DEC_SEQ_OUT));
+
+  if (NULL == hDec) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  hDec->seqDataSize = (pSeqIn->seqSize < 1024) ? (pSeqIn->seqSize) : (1024);
+  memcpy (hDec->pSeqData, pSeqIn->seqBuf, hDec->seqDataSize);
+
+  /* Set Stream Formet */
+  {
+    struct v4l2_format fmt;
+
+    memset (&fmt, 0, sizeof (fmt));
+
+    fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    fmt.fmt.pix_mp.pixelformat = hDec->codecType;
+
+    if ((imgWidth == 0) || (imgHeight == 0))
+      fmt.fmt.pix_mp.plane_fmt[0].sizeimage =
+          MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4;
+    else
+      fmt.fmt.pix_mp.plane_fmt[0].sizeimage = imgWidth * imgHeight * 3 / 4;
+
+    fmt.fmt.pix_mp.width = imgWidth;
+    fmt.fmt.pix_mp.height = imgHeight;
+    fmt.fmt.pix_mp.num_planes = 1;
+
+    if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
+      printf ("Failed to ioctx : VIDIOC_S_FMT(Input Stream)\n");
+      return -1;
+    }
+  }
+
+  /* Malloc Stream Buffer */
+  {
+    struct v4l2_requestbuffers req;
+    int32_t i, buffCnt = STREAM_BUFFER_NUM;
+
+    /* IOCTL : VIDIOC_REQBUFS For Input Stream */
+    memset (&req, 0, sizeof (req));
+    req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    req.count = buffCnt;
+    req.memory = V4L2_MEMORY_DMABUF;
+
+    if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
+      printf ("failed to ioctl: VIDIOC_REQBUFS(Input Stream)\n");
+      return -1;
+    }
+
+    for (i = 0; i < buffCnt; i++) {
+      hDec->hStream[i] =
+          NX_AllocateMemory (MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4, 4096);
+      if (hDec->hStream[i] == NULL) {
+        printf ("Failed to allocate stream buffer(%d, %d)\n", i,
+            MAX_IMAGE_WIDTH * MAX_IMAGE_HEIGHT * 3 / 4);
+        return -1;
+      }
+
+      if (NX_MapMemory (hDec->hStream[i]) != 0) {
+        printf ("Stream memory Mapping Failed\n");
+        return -1;
+      }
+    }
+  }
+
+  /* Set Parameter */
+  {
+    if (hDec->codecType == V4L2_PIX_FMT_MJPEG) {
+      struct v4l2_control ctrl;
+
+      ctrl.id = V4L2_CID_MPEG_VIDEO_THUMBNAIL_MODE;
+      ctrl.value = pSeqIn->thumbnailMode;
+
+      if (ioctl (hDec->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+        printf ("failed to ioctl: Set Thumbnail Mode\n");
+        return -1;
+      }
+    }
+  }
+
+  /* Parser Sequence Header */
+  {
+    struct v4l2_plane planes[1];
+    struct v4l2_buffer buf;
+    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    int32_t iSeqSize = GetSequenceHeader (hDec, pSeqIn);
+
+    if (iSeqSize <= 0) {
+      printf ("Fail, input data has error!!");
+      return -1;
+    }
+
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    buf.m.planes = planes;
+    buf.length = 1;
+    buf.memory = V4L2_MEMORY_DMABUF;
+    buf.index = 0;
+
+    buf.m.planes[0].m.userptr = (unsigned long) hDec->hStream[0]->pBuffer;
+    buf.m.planes[0].m.fd = hDec->hStream[0]->dmaFd;
+    buf.m.planes[0].length = hDec->hStream[0]->size;
+    buf.m.planes[0].bytesused = iSeqSize;
+    buf.m.planes[0].data_offset = 0;
+
+    buf.timestamp.tv_sec = pSeqIn->timeStamp / 1000;
+    buf.timestamp.tv_usec = (pSeqIn->timeStamp % 1000) * 1000;
+
+    if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
+      printf ("failed to ioctl: VIDIOC_QBUF(Header Stream)\n");
+      return -1;
+    }
+
+    if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
+      return -1;
+    }
+
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    buf.m.planes = planes;
+    buf.length = 1;
+    buf.memory = V4L2_MEMORY_DMABUF;
+
+    if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
+      printf ("failed to ioctl: VIDIOC_DQBUF(Header Stream)\n");
+      return -1;
+    }
+
+    pSeqOut->usedByte = buf.bytesused;
+
+    if (buf.field == V4L2_FIELD_NONE)
+      pSeqOut->interlace = NONE_FIELD;
+    else if (V4L2_FIELD_INTERLACED)
+      pSeqOut->interlace = FIELD_INTERLACED;
+
+    hDec->iInterlace = pSeqOut->interlace;
+  }
+
+  /* Get Image Information */
+  {
+    struct v4l2_format fmt;
+    struct v4l2_crop crop;
+
+    memset (&fmt, 0, sizeof (fmt));
+    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+    if (ioctl (hDec->fd, VIDIOC_G_FMT, &fmt) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_G_FMT.\n");
+      return -1;
+    }
+
+    pSeqOut->imgFourCC = fmt.fmt.pix_mp.pixelformat;
+    pSeqOut->width = fmt.fmt.pix_mp.width;
+    pSeqOut->height = fmt.fmt.pix_mp.height;
+    pSeqOut->minBuffers = fmt.fmt.pix_mp.reserved[1];
+    hDec->numFrameBuffers = pSeqOut->minBuffers;
+
+    memset (&crop, 0, sizeof (crop));
+    crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+    if (ioctl (hDec->fd, VIDIOC_G_CROP, &crop) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_G_CROP\n");
+      return -1;
+    }
+
+    pSeqOut->dispInfo.dispLeft = crop.c.left;
+    pSeqOut->dispInfo.dispTop = crop.c.top;
+    pSeqOut->dispInfo.dispRight = crop.c.left + crop.c.width;
+    pSeqOut->dispInfo.dispBottom = crop.c.top + crop.c.height;
+  }
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2DecInit (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_SEQ_IN * pSeqIn)
+{
+  /* Set Output Image */
+  {
+    struct v4l2_format fmt;
+
+    memset (&fmt, 0, sizeof (fmt));
+    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    fmt.fmt.pix_mp.pixelformat = pSeqIn->imgFormat;
+    fmt.fmt.pix_mp.width = pSeqIn->width;
+    fmt.fmt.pix_mp.height = pSeqIn->height;
+    fmt.fmt.pix_mp.num_planes = pSeqIn->imgPlaneNum;
+
+    if (ioctl (hDec->fd, VIDIOC_S_FMT, &fmt) != 0) {
+      printf ("failed to ioctl: VIDIOC_S_FMT(Output Yuv)\n");
+      return -1;
+    }
+
+    hDec->planesNum = pSeqIn->imgPlaneNum;
+  }
+
+  /* Malloc Output Image */
+  {
+    struct v4l2_requestbuffers req;
+    struct v4l2_plane planes[3];
+    struct v4l2_buffer buf;
+    enum v4l2_buf_type type;
+    int32_t imgBuffCnt, i, j;
+
+    /* Calculate Buffer Number */
+    if (pSeqIn->pMemHandle == NULL) {
+      hDec->useExternalFrameBuffer = false;
+      imgBuffCnt = hDec->numFrameBuffers + pSeqIn->numBuffers;
+    } else {
+      hDec->useExternalFrameBuffer = true;
+      if (2 > pSeqIn->numBuffers - hDec->numFrameBuffers)
+        printf ("External Buffer too small.(min=%d, buffers=%d)\n",
+            hDec->numFrameBuffers, pSeqIn->numBuffers);
+
+      imgBuffCnt = pSeqIn->numBuffers;
+    }
+    hDec->numFrameBuffers = imgBuffCnt;
+
+    /* Request Output Buffer */
+    memset (&req, 0, sizeof (req));
+    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    req.count = imgBuffCnt;
+    req.memory = V4L2_MEMORY_DMABUF;
+
+    if (ioctl (hDec->fd, VIDIOC_REQBUFS, &req) != 0) {
+      printf ("failed to ioctl: VIDIOC_REQBUFS(Output YUV)\n");
+      return -1;
+    }
+
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    buf.m.planes = planes;
+    buf.length = pSeqIn->imgPlaneNum;
+    buf.memory = V4L2_MEMORY_DMABUF;
+
+    /* Allocate Buffer(Internal or External) */
+    for (i = 0; i < imgBuffCnt; i++) {
+      if (true == hDec->useExternalFrameBuffer) {
+        hDec->hImage[i] = pSeqIn->pMemHandle[i];
+      } else {
+        hDec->hImage[i] =
+            NX_AllocateVideoMemory (pSeqIn->width, pSeqIn->height,
+            pSeqIn->imgPlaneNum, pSeqIn->imgFormat, 4096);
+        if (hDec->hImage[i] == NULL) {
+          printf ("Failed to allocate image buffer(%d, %d, %d)\n", i,
+              pSeqIn->width, pSeqIn->height);
+          return -1;
+        }
+
+        if (NX_MapVideoMemory (hDec->hImage[i]) != 0) {
+          printf ("Video Memory Mapping Failed\n");
+          return -1;
+        }
+      }
+
+      buf.index = i;
+
+      for (j = 0; j < (int32_t) pSeqIn->imgPlaneNum; j++) {
+        buf.m.planes[j].m.fd = hDec->hImage[i]->dmaFd[j];
+        buf.m.planes[j].length = hDec->hImage[i]->size[j];
+      }
+
+      if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
+        printf ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
+        return -1;
+      }
+    }
+
+    type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
+      printf ("failed to ioctl: VIDIOC_STREAMON\n");
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2DecDecodeFrame (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
+    NX_V4L2DEC_OUT * pDecOut)
+{
+  struct v4l2_buffer buf;
+  struct v4l2_plane planes[3];
+  int idx;
+  int32_t iStrmSize;
+  int32_t frameType;
+
+  if (NULL == hDec) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  iStrmSize = GetFrameStream (hDec, pDecIn, &idx);
+
+  /* Queue Input Buffer */
+  memset (&buf, 0, sizeof (buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  buf.m.planes = planes;
+  buf.length = 1;
+  buf.memory = V4L2_MEMORY_DMABUF;
+  buf.index = idx;
+  buf.timestamp.tv_sec = pDecIn->timeStamp / 1000;
+  buf.timestamp.tv_usec = (pDecIn->timeStamp % 1000) * 1000;
+  buf.flags = pDecIn->eos ? 1 : 0;
+
+  /* buf.m.planes[0].m.userptr = (unsigned long)hStream->pBuffer; */
+  buf.m.planes[0].m.fd = hDec->hStream[idx]->dmaFd;
+  buf.m.planes[0].length = hDec->hStream[idx]->size;
+  buf.m.planes[0].bytesused = iStrmSize;
+  buf.m.planes[0].data_offset = 0;
+
+  if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_QBUF.(Input)\n");
+    return -1;
+  }
+
+  if (iStrmSize > 0) {
+    /* Dequeue Input ES Buffer -> Get Decoded Order Result */
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    buf.m.planes = planes;
+    buf.length = 1;
+    buf.memory = V4L2_MEMORY_DMABUF;
+
+    if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_DQBUF.(Input)\n");
+      return -1;
+    }
+
+    pDecOut->decIdx = buf.index;
+    pDecOut->usedByte = buf.bytesused;
+    pDecOut->outFrmReliable_0_100[DECODED_FRAME] = buf.reserved;
+    pDecOut->timeStamp[DECODED_FRAME] =
+        ((uint64_t) buf.timestamp.tv_sec) * 1000 + buf.timestamp.tv_usec / 1000;
+    frameType = buf.flags;
+
+    if (frameType & V4L2_BUF_FLAG_KEYFRAME)
+      pDecOut->picType[DECODED_FRAME] = PIC_TYPE_I;
+    else if (frameType & V4L2_BUF_FLAG_PFRAME)
+      pDecOut->picType[DECODED_FRAME] = PIC_TYPE_P;
+    else if (frameType & V4L2_BUF_FLAG_BFRAME)
+      pDecOut->picType[DECODED_FRAME] = PIC_TYPE_B;
+    else
+      pDecOut->picType[DECODED_FRAME] = PIC_TYPE_UNKNOWN;
+
+    if (buf.field == V4L2_FIELD_NONE)
+      pDecOut->interlace[DECODED_FRAME] = NONE_FIELD;
+    else if (buf.field == V4L2_FIELD_SEQ_TB)
+      pDecOut->interlace[DECODED_FRAME] = TOP_FIELD_FIRST;
+    else if (buf.field == V4L2_FIELD_SEQ_BT)
+      pDecOut->interlace[DECODED_FRAME] = BOTTOM_FIELD_FIRST;
+  } else if (pDecIn->strmSize > 0) {
+    pDecOut->usedByte = pDecIn->strmSize;
+  }
+
+  /* Dequeue Output YUV Buffer -> Get Display Order Result */
+  memset (&buf, 0, sizeof (buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  buf.m.planes = planes;
+  buf.length = hDec->planesNum;
+  buf.memory = V4L2_MEMORY_DMABUF;
+
+  if (ioctl (hDec->fd, VIDIOC_DQBUF, &buf) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_DQBUF(Output)\n");
+    return -100;
+  }
+
+  pDecOut->dispIdx = buf.index;
+  // pDecOut->dispInfo = &hDec->dispInfo;         // TBD.
+
+  if (pDecOut->dispIdx >= 0) {
+    pDecOut->hImg = *hDec->hImage[buf.index];
+    pDecOut->timeStamp[DISPLAY_FRAME] =
+        ((uint64_t) buf.timestamp.tv_sec) * 1000 + buf.timestamp.tv_usec / 1000;
+    pDecOut->outFrmReliable_0_100[DISPLAY_FRAME] = buf.reserved;
+    frameType = buf.flags;
+
+    if (frameType & V4L2_BUF_FLAG_KEYFRAME)
+      pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_I;
+    else if (frameType & V4L2_BUF_FLAG_PFRAME)
+      pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_P;
+    else if (frameType & V4L2_BUF_FLAG_BFRAME)
+      pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_B;
+    else
+      pDecOut->picType[DISPLAY_FRAME] = PIC_TYPE_UNKNOWN;
+
+    if (buf.field == V4L2_FIELD_NONE)
+      pDecOut->interlace[DISPLAY_FRAME] = NONE_FIELD;
+    else if (buf.field == V4L2_FIELD_SEQ_TB)
+      pDecOut->interlace[DISPLAY_FRAME] = TOP_FIELD_FIRST;
+    else if (buf.field == V4L2_FIELD_SEQ_BT)
+      pDecOut->interlace[DISPLAY_FRAME] = BOTTOM_FIELD_FIRST;
+  }
+
+  hDec->frameCnt++;
+
+  if (pDecOut->dispIdx == -1)
+    return -1;
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2DecClrDspFlag (NX_V4L2DEC_HANDLE hDec, NX_VID_MEMORY_HANDLE hFrameBuf,
+    int32_t iFrameIdx)
+{
+  struct v4l2_buffer buf;
+  struct v4l2_plane planes[3];
+  int32_t index = -1;
+  int32_t i;
+
+  if (NULL == hDec) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  if (iFrameIdx >= 0) {
+    index = iFrameIdx;
+  } else {
+    /* Search Buffer Index */
+    if (hFrameBuf != NULL) {
+      for (i = 0; i < hDec->numFrameBuffers; i++) {
+        if (hFrameBuf == hDec->hImage[i]) {
+          index = i;
+          break;
+        }
+      }
+    }
+  }
+
+  if (index < 0) {
+    printf ("Fail, Invalid FrameBuffer or FrameIndex.\n");
+    return -1;
+  }
+
+  memset (&buf, 0, sizeof (buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  buf.index = index;
+  buf.m.planes = planes;
+  buf.length = hDec->planesNum;
+  buf.memory = V4L2_MEMORY_DMABUF;
+
+  for (i = 0; i < hDec->planesNum; i++) {
+    buf.m.planes[i].m.fd = hDec->hImage[index]->dmaFd[i];
+    buf.m.planes[i].length = hDec->hImage[index]->size[i];
+  }
+
+  /* Queue Output Buffer */
+  if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_QBUF.(Clear Display Index, index = %d)\n",
+        index);
+    return -1;
+  }
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2DecFlush (NX_V4L2DEC_HANDLE hDec)
+{
+  enum v4l2_buf_type type;
+
+  if (NULL == hDec) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
+    printf ("failed to ioctl: VIDIOC_STREAMOFF(Stream)\n");
+    return -1;
+  }
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  if (ioctl (hDec->fd, VIDIOC_STREAMOFF, &type) != 0) {
+    printf ("failed to ioctl: VIDIOC_STREAMOFF(Image)\n");
+    return -1;
+  }
+
+  type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_STREAMON. (Input)\n");
+    return -1;
+  }
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  if (ioctl (hDec->fd, VIDIOC_STREAMON, &type) != 0) {
+    printf ("failed to ioctl: VIDIOC_STREAMON\n");
+    return -1;
+  }
+
+  {
+    struct v4l2_plane planes[3];
+    struct v4l2_buffer buf;
+    int32_t i, j;
+
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    buf.m.planes = planes;
+    buf.length = hDec->planesNum;
+    buf.memory = V4L2_MEMORY_DMABUF;
+
+    for (i = 0; i < hDec->numFrameBuffers; i++) {
+      buf.index = i;
+
+      for (j = 0; j < (int32_t) hDec->planesNum; j++) {
+        buf.m.planes[j].m.fd = hDec->hImage[i]->dmaFd[j];
+        buf.m.planes[j].length = hDec->hImage[i]->size[j];
+      }
+
+      if (ioctl (hDec->fd, VIDIOC_QBUF, &buf) != 0) {
+        printf ("failed to ioctl: VIDIOC_QBUF(Output YUV - %d)\n", i);
+        return -1;
+      }
+    }
+  }
+
+  return 0;
+}
+
+/* Optional Function */
+int32_t
+NX_DecGetFrameType (NX_V4L2DEC_HANDLE hDec, NX_V4L2DEC_IN * pDecIn,
+    uint32_t codecType, int32_t * piFrameType)
+{
+  uint8_t *pbyStrm = pDecIn->strmBuf;
+  uint32_t uPreFourByte = (uint32_t) - 1;
+  int32_t iFrmType = PIC_TYPE_UNKNOWN;
+
+  if ((pbyStrm == NULL) || (piFrameType == NULL))
+    return -1;
+
+  if (!codecType)
+    codecType = hDec->codecType;
+
+  switch (codecType) {
+    case V4L2_PIX_FMT_H264:
+      do {
+        if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
+          return -1;
+
+        uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
+
+        if ((uPreFourByte == 0x00000001) || (uPreFourByte << 8 == 0x00000100)) {
+          int32_t iNaluType = pbyStrm[0] & 0x1F;
+
+          /* Slice start code */
+          if (iNaluType == 5) {
+            iFrmType = PIC_TYPE_IDR;
+            break;
+          } else if (iNaluType == 1) {
+            VLD_STREAM stStrm = { 8, pbyStrm, pDecIn->strmSize };
+
+            vld_get_uev (&stStrm);      /* First_mb_in_slice */
+            iFrmType = vld_get_uev (&stStrm);   /* Slice type */
+
+            if (iFrmType == 0 || iFrmType == 5)
+              iFrmType = PIC_TYPE_P;
+            else if (iFrmType == 1 || iFrmType == 6)
+              iFrmType = PIC_TYPE_B;
+            else if (iFrmType == 2 || iFrmType == 7)
+              iFrmType = PIC_TYPE_I;
+            break;
+          }
+        }
+      } while (1);
+      break;
+
+    case V4L2_PIX_FMT_MPEG2:
+      do {
+        if (pbyStrm >= (pDecIn->strmBuf + pDecIn->strmSize))
+          return -1;
+
+        uPreFourByte = (uPreFourByte << 8) + *pbyStrm++;
+
+        /* Picture start code */
+        if (uPreFourByte == 0x00000100) {
+          VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
+
+          vld_flush_bits (&stStrm, 10); /* temporal_reference */
+          iFrmType = vld_get_bits (&stStrm, 3); /* picture_coding_type */
+
+          if (iFrmType == 1)
+            iFrmType = PIC_TYPE_I;
+          else if (iFrmType == 2)
+            iFrmType = PIC_TYPE_P;
+          else if (iFrmType == 3)
+            iFrmType = PIC_TYPE_B;
+          break;
+        }
+      } while (1);
+      break;
+
+    case V4L2_PIX_FMT_WVC1:
+      if (hDec == NULL || hDec->seqDataSize == 0)
+        return -1;
+
+      {
+        VLD_STREAM stStrm = { 0, pbyStrm, pDecIn->strmSize };
+
+        if (hDec->iInterlace != NONE_FIELD) {
+          /* FCM */
+          if (vld_get_bits (&stStrm, 1) == 1)
+            vld_flush_bits (&stStrm, 1);
+        }
+
+        iFrmType = vld_get_bits (&stStrm, 1);
+        if (iFrmType == 0) {
+          iFrmType = PIC_TYPE_P;
+        } else {
+          iFrmType = vld_get_bits (&stStrm, 1);
+          if (iFrmType == 0) {
+            iFrmType = PIC_TYPE_B;
+          } else {
+            iFrmType = vld_get_bits (&stStrm, 1);
+            if (iFrmType == 0) {
+              iFrmType = PIC_TYPE_I;
+            } else {
+              iFrmType = vld_get_bits (&stStrm, 1);
+              if (iFrmType == 0)
+                iFrmType = PIC_TYPE_VC1_BI;
+              else
+                iFrmType = PIC_TYPE_SKIP;
+            }
+          }
+        }
+      }
+      break;
+
+    case V4L2_PIX_FMT_WMV9:
+      if (hDec == NULL || hDec->seqDataSize == 0)
+        return -1;
+
+      {
+        int32_t rangeRed;
+        int32_t fInterPFlag;
+        int32_t maxBframes;
+        VLD_STREAM stStrm = { 24, hDec->pSeqData, hDec->seqDataSize };
+
+        /* Parse Sequece Header */
+        rangeRed = vld_get_bits (&stStrm, 1);
+        maxBframes = vld_get_bits (&stStrm, 3);
+        vld_flush_bits (&stStrm, 2);
+        fInterPFlag = vld_get_bits (&stStrm, 1);
+
+        /* Parse Frame Header */
+        stStrm.dwUsedBits = 0;
+        stStrm.pbyStart = pbyStrm;
+        stStrm.dwPktSize = pDecIn->strmSize;
+
+        if (fInterPFlag == 1)
+          vld_flush_bits (&stStrm, 1);  /* INTERPFRM */
+
+        vld_flush_bits (&stStrm, 2);    /* FRMCNT */
+
+        if (rangeRed == 1)
+          vld_flush_bits (&stStrm, 1);  /* RANGEREDFRM */
+
+        iFrmType = vld_get_bits (&stStrm, 1);
+        if (maxBframes > 0) {
+          if (iFrmType == 1) {
+            iFrmType = PIC_TYPE_P;
+          } else {
+            iFrmType = vld_get_bits (&stStrm, 1);
+            if (iFrmType == 1)
+              iFrmType = PIC_TYPE_I;
+            else if (iFrmType == 0)
+              iFrmType = PIC_TYPE_B;    /* or BI */
+          }
+        } else {
+          if (iFrmType == 0)
+            iFrmType = PIC_TYPE_I;
+          else if (iFrmType == 1)
+            iFrmType = PIC_TYPE_P;
+        }
+
+      }
+      break;
+
+    default:
+      return -1;
+  }
+
+  *piFrameType = iFrmType;
+
+  return 0;
+}
diff --git a/src/nx_video_enc.c b/src/nx_video_enc.c
new file mode 100644 (file)
index 0000000..234d185
--- /dev/null
@@ -0,0 +1,661 @@
+/*
+ *     Copyright (C) 2016 Nexell Co. All Rights Reserved
+ *     Nexell Co. Proprietary & Confidential
+ *
+ *     NEXELL INFORMS THAT THIS CODE AND INFORMATION IS PROVIDED "AS IS" BASE
+ *  AND        WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING
+ *  BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS
+ *  FOR A PARTICULAR PURPOSE.
+ *
+ *     File            : nx_video_enc.c
+ *     Brief           : V4L2 Video Encoder
+ *     Author          : SungWon Jo (doriya@nexell.co.kr)
+ *     History         : 2016.04.25 : Create
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+
+#include <linux/videodev2.h>
+#include <linux/videodev2_nxp_media.h>
+
+#include <nx_video_alloc.h>
+#include <nx_video_api.h>
+
+/*----------------------------------------------------------------------------*/
+#define NX_V4L2_ENC_NAME               "nx-vpu-enc"
+#define VIDEODEV_MINOR_MAX             63
+#define MAX_CTRL_NUM                   32
+#define STREAM_BUFFER_NUM              1
+
+
+struct NX_V4L2ENC_INFO
+{
+  int fd;
+  uint32_t codecType;
+  int32_t planesNum;
+  int32_t outBuffCnt;
+  int32_t frameCnt;
+  uint8_t *pSeqBuf;
+  int32_t seqSize;
+  NX_MEMORY_HANDLE hBitStream[STREAM_BUFFER_NUM];
+  NX_VID_MEMORY_HANDLE hImg[MAX_FRAME_BUFFER_NUM];
+};
+
+
+/*
+ *             Find Device Node
+ */
+
+/*----------------------------------------------------------------------------*/
+static int
+V4l2EncOpen (void)
+{
+  int fd = -1;
+
+  bool found = false;
+  struct stat s;
+  FILE *stream_fd;
+  char filename[64], name[64];
+  int i = 0;
+
+  while (!found && (i <= VIDEODEV_MINOR_MAX)) {
+    /* video device node */
+    sprintf (filename, "/dev/video%d", i);
+
+    /* if the node is video device */
+    if ((lstat (filename, &s) == 0) && S_ISCHR (s.st_mode)
+        && ((int) ((unsigned short) (s.st_rdev) >> 8) == 81)) {
+      /* open sysfs entry */
+      sprintf (filename, "/sys/class/video4linux/video%d/name", i);
+      stream_fd = fopen (filename, "r");
+      if (stream_fd == NULL) {
+        printf ("failed to open sysfs entry for videodev \n");
+        i++;
+        continue;
+      }
+
+      /* read sysfs entry for device name */
+      if (fgets (name, sizeof (name), stream_fd) == 0) {
+        printf ("failed to read sysfs entry for videodev\n");
+      } else {
+        if (strncmp (name, NX_V4L2_ENC_NAME, strlen (NX_V4L2_ENC_NAME)) == 0) {
+          printf ("node found for device %s: /dev/video%d\n", NX_V4L2_ENC_NAME,
+              i);
+          found = true;
+        }
+      }
+
+      fclose (stream_fd);
+    }
+
+    i++;
+  }
+
+  if (found) {
+    sprintf (filename, "/dev/video%d", i - 1);
+    fd = open (filename, O_RDWR);
+  }
+
+  return fd;
+}
+
+/*
+ *     V4L2 Encoder
+ */
+
+/*----------------------------------------------------------------------------*/
+NX_V4L2ENC_HANDLE
+NX_V4l2EncOpen (uint32_t codecType)
+{
+  NX_V4L2ENC_HANDLE hEnc =
+      (NX_V4L2ENC_HANDLE) malloc (sizeof (struct NX_V4L2ENC_INFO));
+
+  memset (hEnc, 0, sizeof (struct NX_V4L2ENC_INFO));
+
+  hEnc->fd = V4l2EncOpen ();
+  if (hEnc->fd <= 0) {
+    printf ("failed to open video encoder device\n");
+    goto ERROR_EXIT;
+  }
+
+  /* Query capabilities of Device */
+  {
+    struct v4l2_capability cap;
+
+    memset (&cap, 0, sizeof (cap));
+
+    if (ioctl (hEnc->fd, VIDIOC_QUERYCAP, &cap) != 0) {
+      printf ("failed to ioctl: VIDIOC_QUERYCAP\n");
+      goto ERROR_EXIT;
+    }
+  }
+
+  hEnc->codecType = codecType;
+
+  return hEnc;
+
+ERROR_EXIT:
+  free (hEnc);
+
+  return NULL;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2EncClose (NX_V4L2ENC_HANDLE hEnc)
+{
+  enum v4l2_buf_type type;
+  int32_t ret = 0;
+  int i;
+
+  if (NULL == hEnc) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+  if (ioctl (hEnc->fd, VIDIOC_STREAMOFF, &type) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_STREAMOFF - Stream\n");
+    ret = -1;
+  }
+
+  type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  if (ioctl (hEnc->fd, VIDIOC_STREAMOFF, &type) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_STREAMOFF - Image\n");
+    ret = -1;
+  }
+
+  for (i = 0; i < hEnc->outBuffCnt; i++)
+    NX_FreeMemory (hEnc->hBitStream[i]);
+
+  if (hEnc->pSeqBuf)
+    free (hEnc->pSeqBuf);
+
+  close (hEnc->fd);
+
+  free (hEnc);
+
+  return ret;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2EncInit (NX_V4L2ENC_HANDLE hEnc, NX_V4L2ENC_PARA * pEncPara)
+{
+  int inWidth = pEncPara->width;
+  int inHeight = pEncPara->height;
+  int i;
+
+  if (NULL == hEnc) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  /* Set Stream Format */
+  {
+    struct v4l2_format fmt;
+
+    memset (&fmt, 0, sizeof (fmt));
+
+    fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    fmt.fmt.pix_mp.pixelformat = hEnc->codecType;
+    fmt.fmt.pix_mp.plane_fmt[0].sizeimage = inWidth * inHeight * 3 / 4;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_FMT, &fmt) != 0) {
+      printf ("failed to ioctl: VIDIOC_S_FMT(Stream)\n");
+      return -1;
+    }
+  }
+
+  /* Set Image Format */
+  {
+    struct v4l2_format fmt;
+
+    memset (&fmt, 0, sizeof (fmt));
+
+    fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    fmt.fmt.pix_mp.pixelformat = pEncPara->imgFormat;
+    fmt.fmt.pix_mp.width = inWidth;
+    fmt.fmt.pix_mp.height = inHeight;
+    fmt.fmt.pix_mp.num_planes = pEncPara->imgPlaneNum;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_FMT, &fmt) != 0) {
+      printf ("Failed to s_fmt : YUV \n");
+      return -1;
+    }
+
+    hEnc->planesNum = pEncPara->imgPlaneNum;
+  }
+
+  /* Set Encoder Parameter */
+  {
+    if (hEnc->codecType != V4L2_PIX_FMT_MJPEG) {
+      struct v4l2_ext_control ext_ctrl[MAX_CTRL_NUM];
+      struct v4l2_ext_controls ext_ctrls;
+
+      ext_ctrl[0].id = V4L2_CID_MPEG_VIDEO_FPS_NUM;
+      ext_ctrl[0].value = pEncPara->fpsNum;
+      ext_ctrl[1].id = V4L2_CID_MPEG_VIDEO_FPS_DEN;
+      ext_ctrl[1].value = pEncPara->fpsDen;
+      ext_ctrl[2].id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+      ext_ctrl[2].value = pEncPara->keyFrmInterval;
+
+      ext_ctrl[3].id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
+      ext_ctrl[3].value = pEncPara->numIntraRefreshMbs;
+      ext_ctrl[4].id = V4L2_CID_MPEG_VIDEO_SEARCH_RANGE;
+      ext_ctrl[4].value = pEncPara->searchRange;
+
+      ext_ctrl[5].id = V4L2_CID_MPEG_VIDEO_FRAME_RC_ENABLE;
+      ext_ctrl[5].value = (pEncPara->bitrate) ? (1) : (0);
+      ext_ctrl[6].id = V4L2_CID_MPEG_VIDEO_BITRATE;
+      ext_ctrl[6].value = pEncPara->bitrate;
+      ext_ctrl[7].id = V4L2_CID_MPEG_VIDEO_VBV_SIZE;
+      ext_ctrl[7].value = pEncPara->rcVbvSize;
+      ext_ctrl[8].id = V4L2_CID_MPEG_VIDEO_RC_DELAY;
+      ext_ctrl[8].value = pEncPara->RCDelay;
+      ext_ctrl[9].id = V4L2_CID_MPEG_VIDEO_RC_GAMMA_FACTOR;
+      ext_ctrl[9].value = pEncPara->gammaFactor;
+      ext_ctrl[10].id = V4L2_CID_MPEG_VIDEO_FRAME_SKIP_MODE;
+      ext_ctrl[10].value = pEncPara->disableSkip;
+
+      if (hEnc->codecType == V4L2_PIX_FMT_H264) {
+        ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_H264_AUD_INSERT;
+        ext_ctrl[11].value = pEncPara->enableAUDelimiter;
+        ext_ctrl[12].id = V4L2_CID_MPEG_VIDEO_H264_MAX_QP;
+        ext_ctrl[12].value = pEncPara->maximumQp;
+
+        ext_ctrls.count = 13;
+
+        if ((pEncPara->bitrate == 0) || (pEncPara->initialQp > 0)) {
+          ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_H264_I_FRAME_QP;
+          ext_ctrl[13].value = pEncPara->initialQp;
+          ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
+          ext_ctrl[14].value = pEncPara->initialQp;
+
+          ext_ctrls.count += 2;
+        }
+        //ext_ctrl[15].id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
+        //ext_ctrl[15].value = ;
+      } else if (hEnc->codecType == V4L2_PIX_FMT_MPEG4) {
+        ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_MPEG4_MAX_QP;
+        ext_ctrl[11].value = pEncPara->maximumQp;
+
+        ext_ctrls.count = 12;
+
+        if ((pEncPara->bitrate == 0) || (pEncPara->initialQp > 0)) {
+          ext_ctrl[12].id = V4L2_CID_MPEG_VIDEO_MPEG4_I_FRAME_QP;
+          ext_ctrl[12].value = pEncPara->initialQp;
+          ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
+          ext_ctrl[13].value = pEncPara->initialQp;
+
+          ext_ctrls.count += 2;
+        }
+      } else if (hEnc->codecType == V4L2_PIX_FMT_H263) {
+        ext_ctrl[11].id = V4L2_CID_MPEG_VIDEO_H263_PROFILE;
+        ext_ctrl[11].value = pEncPara->profile;
+        ext_ctrl[12].id = V4L2_CID_MPEG_VIDEO_H263_MAX_QP;
+        ext_ctrl[12].value = pEncPara->maximumQp;
+
+        ext_ctrls.count = 13;
+
+        if ((pEncPara->bitrate == 0) || (pEncPara->initialQp > 0)) {
+          ext_ctrl[13].id = V4L2_CID_MPEG_VIDEO_H263_I_FRAME_QP;
+          ext_ctrl[13].value = pEncPara->initialQp;
+          ext_ctrl[14].id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
+          ext_ctrl[14].value = pEncPara->initialQp;
+
+          ext_ctrls.count += 2;
+        }
+      }
+
+      ext_ctrls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
+      ext_ctrls.controls = ext_ctrl;
+
+      if (ioctl (hEnc->fd, VIDIOC_S_EXT_CTRLS, &ext_ctrls) != 0) {
+        printf ("Fail, ioctl(): VIDIOC_S_EXT_CTRLS\n");
+        return -1;
+      }
+    } else {
+      struct v4l2_control ctrl;
+
+      ctrl.id = V4L2_CID_JPEG_COMPRESSION_QUALITY;
+      ctrl.value = pEncPara->jpgQuality;
+
+      if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+        printf ("Fail, ioctl(): VIDIOC_S_CTRL\n");
+        return -1;
+      }
+    }
+  }
+
+  /* Malloc Input Image Buffer */
+  {
+    struct v4l2_requestbuffers req;
+    int32_t bufferCount = pEncPara->imgBufferNum;
+
+    /* IOCTL : VIDIOC_REQBUFS For Input Yuv */
+    memset (&req, 0, sizeof (req));
+    req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    req.count = bufferCount;
+    req.memory = V4L2_MEMORY_DMABUF;    /* V4L2_MEMORY_USERPTR, V4L2_MEMORY_DMABUF, V4L2_MEMORY_MMAP */
+
+    if (ioctl (hEnc->fd, VIDIOC_REQBUFS, &req) != 0) {
+      printf ("failed to ioctl: VIDIOC_REQBUFS(Input YUV)\n");
+      return -1;
+    }
+  }
+
+  /* Malloc Output Stream Buffer */
+  {
+    struct v4l2_requestbuffers req;
+    int bufferCount = STREAM_BUFFER_NUM;
+
+    /* IOCTL : VIDIOC_REQBUFS For Output Stream */
+    memset (&req, 0, sizeof (req));
+    req.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    req.count = bufferCount;
+    req.memory = V4L2_MEMORY_DMABUF;
+
+    if (ioctl (hEnc->fd, VIDIOC_REQBUFS, &req) != 0) {
+      printf ("failed to ioctl: VIDIOC_REQBUFS(Output ES)\n");
+      return -1;
+    }
+
+    /* Allocate Output Buffer */
+    for (i = 0; i < bufferCount; i++) {
+      hEnc->hBitStream[i] =
+          NX_AllocateMemory (inWidth * inHeight * 3 / 4, 4096);
+      if (hEnc->hBitStream[i] == NULL) {
+        printf ("Failed to allocate stream buffer(%d, %d)\n", i,
+            inWidth * inHeight * 3 / 4);
+        return -1;
+      }
+
+      if (NX_MapMemory (hEnc->hBitStream[i]) != 0) {
+        printf ("Stream memory Mapping Failed\n");
+        return -1;
+      }
+    }
+
+    hEnc->outBuffCnt = bufferCount;
+  }
+
+  /* Get Sequence header */
+  {
+    struct v4l2_plane planes[1];
+    struct v4l2_buffer buf;
+    enum v4l2_buf_type type;
+
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    buf.m.planes = planes;
+    buf.length = 1;
+    buf.memory = V4L2_MEMORY_DMABUF;
+    buf.index = 0;
+
+    buf.m.planes[0].m.fd = hEnc->hBitStream[0]->dmaFd;
+    //buf.m.planes[0].m.userptr = (unsigned long)hEnc->hBitStream[0]->pBuffer;
+    buf.m.planes[0].length = hEnc->hBitStream[0]->size;
+    buf.m.planes[0].bytesused = hEnc->hBitStream[0]->size;
+    buf.m.planes[0].data_offset = 0;
+
+    if (ioctl (hEnc->fd, VIDIOC_QBUF, &buf) != 0) {
+      printf ("failed to ioctl: VIDIOC_QBUF(Header)\n");
+      return -1;
+    }
+
+    type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    if (ioctl (hEnc->fd, VIDIOC_STREAMON, &type) != 0) {
+      printf ("failed to ioctl: VIDIOC_STREAMON\n");
+      return -1;
+    }
+
+    if (ioctl (hEnc->fd, VIDIOC_DQBUF, &buf) != 0) {
+      printf ("failed to ioctl: VIDIOC_DQBUF(Header)\n");
+      return -1;
+    }
+
+    if (buf.m.planes[0].bytesused > 0) {
+      hEnc->seqSize = buf.m.planes[0].bytesused;
+      hEnc->pSeqBuf = (uint8_t *) malloc (hEnc->seqSize);
+      memcpy (hEnc->pSeqBuf, (void *) hEnc->hBitStream[buf.index]->pBuffer,
+          hEnc->seqSize);
+    }
+  }
+
+  /* Input Image Stream On */
+  {
+    enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+
+    if (ioctl (hEnc->fd, VIDIOC_STREAMON, &type) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_STREAMON(Image)\n");
+      return -1;
+    }
+  }
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2EncGetSeqInfo (NX_V4L2ENC_HANDLE hEnc, uint8_t ** ppSeqBuf,
+    int32_t * iSeqSize)
+{
+  if (hEnc == NULL) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  *ppSeqBuf = hEnc->pSeqBuf;
+  *iSeqSize = hEnc->seqSize;
+
+  return 0;
+}
+
+/*----------------------------------------------------------------------------*/
+int32_t
+NX_V4l2EncEncodeFrame (NX_V4L2ENC_HANDLE hEnc, NX_V4L2ENC_IN * pEncIn,
+    NX_V4L2ENC_OUT * pEncOut)
+{
+  struct v4l2_plane planes[3];
+  struct v4l2_buffer buf;
+  int i;
+
+  if (hEnc == NULL) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  memset (pEncOut, 0, sizeof (NX_V4L2ENC_OUT));
+
+  /* Set Encode Parameter */
+  if (hEnc->codecType != V4L2_PIX_FMT_MJPEG) {
+    struct v4l2_control ctrl;
+
+    ctrl.id = V4L2_CID_MPEG_VIDEO_FORCE_I_FRAME;
+    ctrl.value = pEncIn->forcedIFrame;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Forced Intra Frame\n");
+      return -1;
+    }
+
+    ctrl.id = V4L2_CID_MPEG_VIDEO_FORCE_SKIP_FRAME;
+    ctrl.value = pEncIn->forcedSkipFrame;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Forced Skip Frame\n");
+      return -1;
+    }
+
+    if (hEnc->codecType == V4L2_PIX_FMT_H264)
+      ctrl.id = V4L2_CID_MPEG_VIDEO_H264_P_FRAME_QP;
+    else if (hEnc->codecType == V4L2_PIX_FMT_MPEG4)
+      ctrl.id = V4L2_CID_MPEG_VIDEO_MPEG4_P_FRAME_QP;
+    else if (hEnc->codecType == V4L2_PIX_FMT_H263)
+      ctrl.id = V4L2_CID_MPEG_VIDEO_H263_P_FRAME_QP;
+
+    ctrl.value = pEncIn->quantParam;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Forced QP\n");
+      return -1;
+    }
+  }
+
+  /* Queue Input Buffer */
+  memset (&buf, 0, sizeof (buf));
+  buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+  buf.m.planes = planes;
+  buf.length = hEnc->planesNum;
+  buf.memory = V4L2_MEMORY_DMABUF;
+  buf.index = pEncIn->imgIndex;
+
+  for (i = 0; i < hEnc->planesNum; i++) {
+    buf.m.planes[i].m.fd = pEncIn->pImage->dmaFd[i];
+    buf.m.planes[i].length = pEncIn->pImage->size[i];
+  }
+
+  if (ioctl (hEnc->fd, VIDIOC_QBUF, &buf) != 0) {
+    printf ("Fail, ioctl(): VIDIOC_QBUF(Image)\n");
+    return -1;
+  }
+
+  /* Queue Output Bitstream Buffer */
+  {
+    int idx = hEnc->frameCnt % hEnc->outBuffCnt;
+
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    buf.m.planes = planes;
+    buf.length = 1;
+    buf.memory = V4L2_MEMORY_DMABUF;
+    buf.index = idx;
+
+    buf.m.planes[0].m.fd = hEnc->hBitStream[idx]->dmaFd;
+    //buf.m.planes[0].m.userptr = (unsigned long)hBitStream[idx]->pBuffer;
+    buf.m.planes[0].length = hEnc->hBitStream[idx]->size;
+    buf.m.planes[0].bytesused = hEnc->hBitStream[idx]->size;
+    buf.m.planes[0].data_offset = 0;
+
+    if (ioctl (hEnc->fd, VIDIOC_QBUF, &buf) != 0) {
+      printf ("failed to ioctl: VIDIOC_QBUF(Stream)\n");
+      return -1;
+    }
+  }
+
+  /* Dequeue Input Image Buffer */
+  {
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
+    buf.m.planes = planes;
+    buf.length = hEnc->planesNum;
+    buf.memory = V4L2_MEMORY_DMABUF;
+
+    if (ioctl (hEnc->fd, VIDIOC_DQBUF, &buf) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_DQBUF(Input Image)\n");
+      return -1;
+    }
+  }
+
+  /* Dequeue Output Stream Buffer */
+  {
+    memset (&buf, 0, sizeof (buf));
+    buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
+    buf.m.planes = planes;
+    buf.length = 1;
+    buf.memory = V4L2_MEMORY_DMABUF;    //V4L2_MEMORY_USERPTR;
+
+    if (ioctl (hEnc->fd, VIDIOC_DQBUF, &buf) != 0) {
+      printf ("Fail, ioctl(): VIDIOC_DQBUF(Compressed Stream)\n");
+      return -1;
+    }
+
+    pEncOut->strmBuf = (uint8_t *) hEnc->hBitStream[buf.index]->pBuffer;
+    pEncOut->strmSize = buf.m.planes[0].bytesused;
+
+    if (buf.flags & V4L2_BUF_FLAG_KEYFRAME)
+      pEncOut->frameType = PIC_TYPE_I;
+    else if (buf.flags & V4L2_BUF_FLAG_PFRAME)
+      pEncOut->frameType =
+          (pEncIn->forcedSkipFrame == 0) ? (PIC_TYPE_P) : (PIC_TYPE_SKIP);
+    else if (buf.flags & V4L2_BUF_FLAG_BFRAME)
+      pEncOut->frameType = PIC_TYPE_B;
+    else
+      pEncOut->frameType = PIC_TYPE_UNKNOWN;
+  }
+
+  hEnc->frameCnt++;
+
+  return 0;
+}
+
+int32_t
+NX_V4l2EncChangeParameter (NX_V4L2ENC_HANDLE hEnc,
+    NX_V4L2ENC_CHG_PARA * pChgPara)
+{
+  struct v4l2_control ctrl;
+
+  if (hEnc == NULL) {
+    printf ("Fail, Invalid Handle.\n");
+    return -1;
+  }
+
+  if (pChgPara->chgFlg & VID_CHG_KEYFRAME) {
+    ctrl.id = V4L2_CID_MPEG_VIDEO_GOP_SIZE;
+    ctrl.value = pChgPara->keyFrmInterval;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Change Key Frame Interval\n");
+      return -1;
+    }
+  }
+
+  if (pChgPara->chgFlg & VID_CHG_BITRATE) {
+    ctrl.id = V4L2_CID_MPEG_VIDEO_BITRATE;
+    ctrl.value = pChgPara->bitrate;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Change Bitrate\n");
+      return -1;
+    }
+  }
+
+  if (pChgPara->chgFlg & VID_CHG_FRAMERATE) {
+    ctrl.id = V4L2_CID_MPEG_VIDEO_FPS_NUM;
+    ctrl.value = pChgPara->fpsNum;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Change Fps Number\n");
+      return -1;
+    }
+
+    ctrl.id = V4L2_CID_MPEG_VIDEO_FPS_DEN;
+    ctrl.value = pChgPara->fpsDen;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Change Fps Density\n");
+      return -1;
+    }
+  }
+
+  if (pChgPara->chgFlg & VID_CHG_INTRARF) {
+    ctrl.id = V4L2_CID_MPEG_VIDEO_CYCLIC_INTRA_REFRESH_MB;
+    ctrl.value = pChgPara->numIntraRefreshMbs;
+
+    if (ioctl (hEnc->fd, VIDIOC_S_CTRL, &ctrl) != 0) {
+      printf ("failed to ioctl: Change Intra Refresh Mbs\n");
+      return -1;
+    }
+  }
+
+  return 0;
+}