--- /dev/null
+ 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!
--- /dev/null
+SUBDIRS = src
+
+EXTRA_DIST = autogen.sh
--- /dev/null
+################################################################################
+#
+# 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
--- /dev/null
+#! /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
--- /dev/null
+#########################################################################
+# 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 $@ $<
--- /dev/null
+# -*- 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
--- /dev/null
+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+
--- /dev/null
+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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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]);
+}
--- /dev/null
+/*
+ * 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__
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}