diff options
-rw-r--r-- | camera/Android.mk | 32 | ||||
-rw-r--r-- | camera/MODULE_LICENSE_GPL | 0 | ||||
-rw-r--r-- | camera/NOTICE | 674 | ||||
-rw-r--r-- | camera/exynos_camera.c | 3887 | ||||
-rw-r--r-- | camera/exynos_camera.h | 674 | ||||
-rw-r--r-- | camera/exynos_exif.c (renamed from camera/smdk4x12_exif.c) | 283 | ||||
-rw-r--r-- | camera/exynos_ion.c (renamed from camera/smdk4x12_ion.c) | 38 | ||||
-rw-r--r-- | camera/exynos_jpeg.c (renamed from camera/smdk4x12_jpeg.c) | 58 | ||||
-rw-r--r-- | camera/exynos_param.c (renamed from camera/smdk4x12_param.c) | 140 | ||||
-rw-r--r-- | camera/exynos_utils.c (renamed from camera/smdk4x12_utils.c) | 36 | ||||
-rw-r--r-- | camera/exynos_v4l2.c | 802 | ||||
-rw-r--r-- | camera/exynos_v4l2_output.c (renamed from camera/smdk4x12_v4l2_output.c) | 94 | ||||
-rw-r--r-- | camera/include/fimc.h | 405 | ||||
-rw-r--r-- | camera/include/linux/ion.h (renamed from camera/include/ion.h) | 0 | ||||
-rw-r--r-- | camera/include/linux/s5c73m3.h (renamed from camera/include/s5c73m3.h) | 0 | ||||
-rw-r--r-- | camera/include/linux/videodev2_exynos_camera.h | 2047 | ||||
-rw-r--r-- | camera/include/linux/videodev2_exynos_media.h | 225 | ||||
-rw-r--r-- | camera/smdk4x12_camera.c | 4530 | ||||
-rw-r--r-- | camera/smdk4x12_camera.h | 695 | ||||
-rw-r--r-- | camera/smdk4x12_v4l2.c | 739 |
20 files changed, 8651 insertions, 6708 deletions
diff --git a/camera/Android.mk b/camera/Android.mk index 60bd5d7..a830b3d 100644 --- a/camera/Android.mk +++ b/camera/Android.mk @@ -1,4 +1,5 @@ -# Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> +# +# Copyright (C) 2013 Paul Kocialkowski # # 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 @@ -21,26 +22,31 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES := \ - smdk4x12_camera.c \ - smdk4x12_exif.c \ - smdk4x12_jpeg.c \ - smdk4x12_param.c \ - smdk4x12_utils.c \ - smdk4x12_v4l2.c \ - smdk4x12_v4l2_output.c \ - smdk4x12_ion.c + exynos_camera.c \ + exynos_exif.c \ + exynos_jpeg.c \ + exynos_param.c \ + exynos_utils.c \ + exynos_v4l2.c \ + exynos_v4l2_output.c LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ system/media/camera/include \ hardware/samsung/exynos4/hal/include -LOCAL_CFLAGS += -DEXYNOS_ION - -LOCAL_SHARED_LIBRARIES := libutils libcutils liblog libcamera_client libhardware libhwjpeg +LOCAL_SHARED_LIBRARIES := libutils libcutils liblog libcamera_client libhardware LOCAL_PRELINK_MODULE := false -LOCAL_MODULE := camera.smdk4x12 +ifeq ($(TARGET_SOC),exynos4x12) + LOCAL_SHARED_LIBRARIES += libhwjpeg + LOCAL_CFLAGS += -DEXYNOS_JPEG_HW + + LOCAL_SRC_FILES += exynos_ion.c + LOCAL_CFLAGS += -DEXYNOS_ION +endif + +LOCAL_MODULE := camera.$(TARGET_BOOTLOADER_BOARD_NAME) LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/hw LOCAL_MODULE_TAGS := optional diff --git a/camera/MODULE_LICENSE_GPL b/camera/MODULE_LICENSE_GPL new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/camera/MODULE_LICENSE_GPL diff --git a/camera/NOTICE b/camera/NOTICE new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/camera/NOTICE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them 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 prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If 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 convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state 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 program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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 3 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/>. + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + <program> Copyright (C) <year> <name of author> + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +<http://www.gnu.org/licenses/>. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +<http://www.gnu.org/philosophy/why-not-lgpl.html>. diff --git a/camera/exynos_camera.c b/camera/exynos_camera.c new file mode 100644 index 0000000..12360ae --- /dev/null +++ b/camera/exynos_camera.c @@ -0,0 +1,3887 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * Based on crespo libcamera and exynos4 hal libcamera: + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * 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 3 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/>. + */ + +#include <fcntl.h> +#include <unistd.h> +#include <stdlib.h> +#include <time.h> +#include <errno.h> +#include <malloc.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#include <asm/types.h> + +#define LOG_TAG "exynos_camera" +#include <utils/Log.h> +#include <utils/Timers.h> + +#include "exynos_camera.h" + +#define BIG2LITTLE_ENDIAN(big) ((big & 0xff) << 24 | (big & 0xff00) << 8 | (big & 0xff0000) >> 8 | (big & 0xff000000) >> 24) + +/* + * Devices configurations + */ + +struct exynos_camera_mbus_resolution exynos_camera_mbus_resolutions_s5k6a3_smdk4x12[] = { + // 16:9 ratio + { 1280, 720, 1344, 756 }, + // 4:3 ratio + { 1280, 960, 1392, 1044 }, + { 960, 720, 1392, 1044 }, + { 640, 480, 1392, 1044 }, + { 320, 240, 1392, 1044 }, + // 1:1 ratio + { 1392, 1392, 1392, 1392 }, + { 704, 704, 1392, 1392 }, + { 320, 320, 1392, 1392 }, +}; + +struct exynos_camera_videosnapshot_resolution exynos_camera_videosnapshot_resolutions_s5c73m3[] = { + //Capture Size - Snapshot Size + { 1920, 1080, 3264, 1836 }, + { 1280, 720, 3264, 1836 }, + { 720, 480, 3264, 2176 }, + { 640, 480, 3264, 2488 }, + { 352, 288, 3264, 2488 }, + { 320, 240, 3264, 2488 }, + { 176, 144, 3264, 2488 }, +}; + +struct exynos_camera_preset exynos_camera_presets_smdk4x12[] = { + { + .name = "S5C73M3", + .facing = CAMERA_FACING_BACK, + .orientation = 90, + .rotation = 0, + .hflip = 0, + .vflip = 0, + .capture_format = V4L2_PIX_FMT_INTERLEAVED, + .picture_format = V4L2_PIX_FMT_JPEG, + .fimc_is = 0, + .focal_length = 3.7f, + .horizontal_view_angle = 63.0f, + .vertical_view_angle = 49.3f, + .metering = METERING_CENTER, + .params = { + .preview_size_values = "960x720,1280x720,1184x666,960x640,704x576,640x480,352x288,320x240", + .preview_size = "960x720", + .preview_format_values = "yuv420sp,yuv420p,rgb565", + .preview_format = "rgb565", + .preview_frame_rate_values = "30,20,15", + .preview_frame_rate = 30, + .preview_fps_range_values = "(15000,15000),(15000,30000),(30000,30000)", + .preview_fps_range = "15000,30000", + + .picture_size_values = "640x480,1024x768,1280x720,1600x1200,2560x1920,3264x2448,2048x1536,3264x1836,2048x1152,3264x2176", + .picture_size = "3264x2448", + .picture_format_values = "jpeg", + .picture_format = "jpeg", + .jpeg_thumbnail_size_values = "160x120,160x90,144x96", + .jpeg_thumbnail_width = 160, + .jpeg_thumbnail_height = 120, + .jpeg_thumbnail_quality = 100, + .jpeg_quality = 90, + + .video_snapshot_supported = 1, + .full_video_snap_supported = 0, + + .recording_size = "1280x720", + .recording_size_values = "1280x720,1920x1080,720x480,640x480,352x288,320x240,176x144", + .recording_format = "yuv420sp", + + .focus_mode = "auto", + .focus_mode_values = "auto,infinity,macro,fixed,continuous-picture,continuous-video", + .focus_distances = "0.15,1.20,Infinity", + .focus_areas = "(0,0,0,0,0)", + .max_num_focus_areas = 1, + + .max_detected_faces = 15, + + .zoom_supported = 1, + .smooth_zoom_supported = 0, + .zoom_ratios = "100,102,104,109,111,113,119,121,124,131,134,138,146,150,155,159,165,170,182,189,200,213,222,232,243,255,283,300,319,364,400", + .zoom = 0, + .max_zoom = 30, + + .auto_exposure_lock_supported = 1, + .auto_exposure_lock = 0, + + .auto_white_balance_lock_supported = 1, + .auto_white_balance_lock = 0, + + .flash_mode = "off", + .flash_mode_values = "off,auto,on,torch", + + .exposure_compensation = 0, + .exposure_compensation_step = 0.5, + .min_exposure_compensation = -4, + .max_exposure_compensation = 4, + + .whitebalance = "auto", + .whitebalance_values = "auto,incandescent,fluorescent,daylight,cloudy-daylight", + + .antibanding = "auto", + .antibanding_values = "off,auto,50hz,60hz", + + .scene_mode = "auto", + .scene_mode_values = "auto,portrait,landscape,night,beach,snow,sunset,fireworks,action,party,candlelight,dusk-dawn,fall-color,text,back-light,high-sensitivity", + + .effect = "none", + .effect_values = "none,mono,negative,sepia,solarize,posterize,washed,vintage-warm,vintage-cold,point-blue,point-red-yellow,point-green", + + .iso = "auto", + .iso_values = "auto,ISO100,ISO200,ISO400,ISO800", + + .image_stabilization = "off", + .image_stabilization_values = "on,off", + }, + .mbus_resolutions = NULL, + .mbus_resolutions_count = 0, + + .videosnapshot_resolutions = (struct exynos_camera_videosnapshot_resolution *) &exynos_camera_videosnapshot_resolutions_s5c73m3, + .videosnapshot_resolutions_count = 7, + }, + { + .name = "S5K6A3", + .facing = CAMERA_FACING_FRONT, + .orientation = 270, + .rotation = 0, + .hflip = 0, + .vflip = 0, + .capture_format = V4L2_PIX_FMT_UYVY, + .picture_format = V4L2_PIX_FMT_JPEG, + .fimc_is = 1, + .focal_length = 2.73f, + .horizontal_view_angle = 52.58f, + .vertical_view_angle = 52.58f, + .metering = METERING_CENTER, + .params = { + .preview_size_values = "1280x720,960x720,640x480,320x240,704x704,320x320", + .preview_size = "960x720", + .preview_format_values = "yuv420sp,yuv420p,rgb565", + .preview_format = "rgb565", + .preview_frame_rate_values = "30,20,15,8", + .preview_frame_rate = 30, + .preview_fps_range_values = "(8000,8000),(15000,15000),(15000,30000),(30000,30000)", + .preview_fps_range = "15000,30000", + + .picture_size_values = "1280x960,1392x1392,640x480,1280x720,720x480,320x240", + .picture_size = "1280x960", + .picture_format_values = "jpeg", + .picture_format = "jpeg", + .jpeg_thumbnail_size_values = "160x120,160x160,160x90,144x96", + .jpeg_thumbnail_width = 160, + .jpeg_thumbnail_height = 120, + .jpeg_thumbnail_quality = 100, + .jpeg_quality = 90, + + .video_snapshot_supported = 1, + .full_video_snap_supported = 1, + + .recording_size = "1280x720", + .recording_size_values = "1280x720,720x480,640x480,352x288,320x320,320x240,176x144", + .recording_format = "yuv420sp", + + .focus_mode = "fixed", + .focus_mode_values = "infinity,fixed", + .focus_distances = "0.20,0.25,Infinity", + .focus_areas = NULL, + .max_num_focus_areas = 0, + + .zoom_supported = 0, + + .auto_exposure_lock_supported = 0, + .auto_exposure_lock = 0, + + .auto_white_balance_lock_supported = 0, + .auto_white_balance_lock = 0, + + .flash_mode = NULL, + .flash_mode_values = NULL, + + .max_detected_faces = 5, + + .exposure_compensation = 0, + .exposure_compensation_step = 0.5, + .min_exposure_compensation = -4, + .max_exposure_compensation = 4, + + .whitebalance = "auto", + .whitebalance_values = "auto,incandescent,fluorescent,daylight,cloudy-daylight", + + .antibanding = NULL, + .antibanding_values = NULL, + + .scene_mode = NULL, + .scene_mode_values = NULL, + + .effect = "none", + .effect_values = "none,mono,negative,sepia,solarize,posterize,washed,vintage-warm,vintage-cold,point-blue,point-red-yellow,point-green", + + .iso = "auto", + .iso_values = "auto", + + .image_stabilization = "off", + .image_stabilization_values = "off", + }, + .mbus_resolutions = (struct exynos_camera_mbus_resolution *) &exynos_camera_mbus_resolutions_s5k6a3_smdk4x12, + .mbus_resolutions_count = 8, + }, +}; + +struct exynos_v4l2_node exynos_v4l2_nodes_smdk4x12[] = { + { // FIMC0 is used for capture + .id = 0, + .node = "/dev/video0", + }, + { // FIMC1 is used for preview output + .id = 1, + .node = "/dev/video1", + }, + { // FIMC2 is used for picture output + .id = 2, + .node = "/dev/video2", + }, + { // FIMC3 is used for recording output + .id = 3, + .node = "/dev/video3", + }, +}; + +struct exynox_camera_config exynos_camera_config_smdk4x12 = { + .presets = (struct exynos_camera_preset *) &exynos_camera_presets_smdk4x12, + .presets_count = 2, + .v4l2_nodes = (struct exynos_v4l2_node *) &exynos_v4l2_nodes_smdk4x12, + .v4l2_nodes_count = 4, +}; + +/* + * Exynos Camera + */ + +struct exynox_camera_config *exynos_camera_config = + &exynos_camera_config_smdk4x12; + +int exynos_camera_start(struct exynos_camera *exynos_camera, int id) +{ + int rc; + + if (exynos_camera == NULL || id >= exynos_camera->config->presets_count) + return -EINVAL; + + // ION + +#ifdef EXYNOS_ION + rc = exynos_ion_init(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to init ION", __func__); + goto error; + } + + rc = exynos_ion_open(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to open ION", __func__); + goto error; + } +#endif + + // V4L2 + + rc = exynos_v4l2_init(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to init v4l2", __func__); + goto error; + } + + // FIMC0 + + rc = exynos_v4l2_open(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to open v4l2 device", __func__); + goto error; + } + + rc = exynos_v4l2_querycap_cap(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to query capabilities", __func__); + goto error; + } + + rc = exynos_v4l2_enum_input(exynos_camera, 0, id); + if (rc < 0) { + ALOGE("%s: Unable to enumerate input", __func__); + goto error; + } + + rc = exynos_v4l2_s_input(exynos_camera, 0, id); + if (rc < 0) { + ALOGE("%s: Unable to set inputs", __func__); + goto error; + } + + // Recording + + exynos_camera->recording_metadata = 1; + + // Params + + rc = exynos_camera_params_init(exynos_camera, id); + if (rc < 0) { + ALOGE("%s: Unable to init params", __func__); + goto error; + } + + // Gralloc + + rc = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const struct hw_module_t **) &exynos_camera->gralloc); + if (rc) + ALOGE("%s: Unable to get gralloc module", __func__); + + rc = 0; + goto complete; + +error: + exynos_v4l2_close(exynos_camera, 0); + +#ifdef EXYNOS_ION + exynos_ion_close(exynos_camera); +#endif + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_stop(struct exynos_camera *exynos_camera) +{ + int i; + int id; + + if (exynos_camera == NULL || exynos_camera->config == NULL) + return; + + exynos_v4l2_close(exynos_camera, 0); + +#ifdef EXYNOS_ION + exynos_ion_close(exynos_camera); +#endif +} + +// Params + +int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id) +{ + int rc; + + if (exynos_camera == NULL || id >= exynos_camera->config->presets_count) + return -EINVAL; + + // Camera params + + exynos_camera->camera_rotation = exynos_camera->config->presets[id].rotation; + exynos_camera->camera_hflip = exynos_camera->config->presets[id].hflip; + exynos_camera->camera_vflip = exynos_camera->config->presets[id].vflip; + exynos_camera->camera_capture_format = exynos_camera->config->presets[id].capture_format; + exynos_camera->camera_picture_format = exynos_camera->config->presets[id].picture_format; + exynos_camera->camera_fimc_is = exynos_camera->config->presets[id].fimc_is; + exynos_camera->camera_focal_length = (int) (exynos_camera->config->presets[id].focal_length * 100); + exynos_camera->camera_metering = exynos_camera->config->presets[id].metering; + + exynos_camera->camera_mbus_resolutions = exynos_camera->config->presets[id].mbus_resolutions; + exynos_camera->camera_mbus_resolutions_count = exynos_camera->config->presets[id].mbus_resolutions_count; + + exynos_camera->camera_videosnapshot_resolutions = exynos_camera->config->presets[id].videosnapshot_resolutions; + exynos_camera->camera_videosnapshot_resolutions_count = exynos_camera->config->presets[id].videosnapshot_resolutions_count; + + + // Recording preview + + exynos_param_string_set(exynos_camera, "preferred-preview-size-for-video", + exynos_camera->config->presets[id].params.preview_size); + + // Preview + + exynos_param_string_set(exynos_camera, "preview-size-values", + exynos_camera->config->presets[id].params.preview_size_values); + exynos_param_string_set(exynos_camera, "preview-size", + exynos_camera->config->presets[id].params.preview_size); + exynos_param_string_set(exynos_camera, "preview-format-values", + exynos_camera->config->presets[id].params.preview_format_values); + exynos_param_string_set(exynos_camera, "preview-format", + exynos_camera->config->presets[id].params.preview_format); + exynos_param_string_set(exynos_camera, "preview-frame-rate-values", + exynos_camera->config->presets[id].params.preview_frame_rate_values); + exynos_param_int_set(exynos_camera, "preview-frame-rate", + exynos_camera->config->presets[id].params.preview_frame_rate); + exynos_param_string_set(exynos_camera, "preview-fps-range-values", + exynos_camera->config->presets[id].params.preview_fps_range_values); + exynos_param_string_set(exynos_camera, "preview-fps-range", + exynos_camera->config->presets[id].params.preview_fps_range); + + // Picture + + exynos_param_string_set(exynos_camera, "picture-size-values", + exynos_camera->config->presets[id].params.picture_size_values); + exynos_param_string_set(exynos_camera, "picture-size", + exynos_camera->config->presets[id].params.picture_size); + exynos_param_string_set(exynos_camera, "picture-format-values", + exynos_camera->config->presets[id].params.picture_format_values); + exynos_param_string_set(exynos_camera, "picture-format", + exynos_camera->config->presets[id].params.picture_format); + exynos_param_string_set(exynos_camera, "jpeg-thumbnail-size-values", + exynos_camera->config->presets[id].params.jpeg_thumbnail_size_values); + exynos_param_int_set(exynos_camera, "jpeg-thumbnail-width", + exynos_camera->config->presets[id].params.jpeg_thumbnail_width); + exynos_param_int_set(exynos_camera, "jpeg-thumbnail-height", + exynos_camera->config->presets[id].params.jpeg_thumbnail_height); + exynos_param_int_set(exynos_camera, "jpeg-thumbnail-quality", + exynos_camera->config->presets[id].params.jpeg_thumbnail_quality); + exynos_param_int_set(exynos_camera, "jpeg-quality", + exynos_camera->config->presets[id].params.jpeg_quality); + + if (exynos_camera->config->presets[id].params.video_snapshot_supported == 1) + exynos_param_string_set(exynos_camera, "video-snapshot-supported", "true"); + if (exynos_camera->config->presets[id].params.full_video_snap_supported == 1) + exynos_param_string_set(exynos_camera, "full-video-snap-supported", "true"); + + // Recording + + exynos_param_string_set(exynos_camera, "video-size", + exynos_camera->config->presets[id].params.recording_size); + exynos_param_string_set(exynos_camera, "video-size-values", + exynos_camera->config->presets[id].params.recording_size_values); + exynos_param_string_set(exynos_camera, "video-frame-format", + exynos_camera->config->presets[id].params.recording_format); + + // Focus + + exynos_param_string_set(exynos_camera, "focus-mode", + exynos_camera->config->presets[id].params.focus_mode); + exynos_param_string_set(exynos_camera, "focus-mode-values", + exynos_camera->config->presets[id].params.focus_mode_values); + exynos_param_string_set(exynos_camera, "focus-distances", + exynos_camera->config->presets[id].params.focus_distances); + if (exynos_camera->config->presets[id].params.max_num_focus_areas > 0) { + exynos_param_string_set(exynos_camera, "focus-areas", + exynos_camera->config->presets[id].params.focus_areas); + sprintf(exynos_camera->raw_focus_areas,"%s", + exynos_camera->config->presets[id].params.focus_areas); + exynos_param_int_set(exynos_camera, "max-num-focus-areas", + exynos_camera->config->presets[id].params.max_num_focus_areas); + } + + // Face Detection + exynos_camera->max_detected_faces = exynos_camera->config->presets[id].params.max_detected_faces; + exynos_param_int_set(exynos_camera, "max-num-detected-faces-hw", + exynos_camera->max_detected_faces); + + // Zoom + + if (exynos_camera->config->presets[id].params.zoom_supported == 1) { + exynos_param_string_set(exynos_camera, "zoom-supported", "true"); + + if (exynos_camera->config->presets[id].params.smooth_zoom_supported == 1) + exynos_param_string_set(exynos_camera, "smooth-zoom-supported", "true"); + + if (exynos_camera->config->presets[id].params.zoom_ratios != NULL) + exynos_param_string_set(exynos_camera, "zoom-ratios", exynos_camera->config->presets[id].params.zoom_ratios); + + exynos_param_int_set(exynos_camera, "zoom", exynos_camera->config->presets[id].params.zoom); + exynos_param_int_set(exynos_camera, "max-zoom", exynos_camera->config->presets[id].params.max_zoom); + + } else { + exynos_param_string_set(exynos_camera, "zoom-supported", "false"); + } + + // AE lock + + if (exynos_camera->config->presets[id].params.auto_exposure_lock_supported == 1) { + exynos_param_string_set(exynos_camera, "auto-exposure-lock-supported", "true"); + + if (exynos_camera->config->presets[id].params.auto_exposure_lock) + exynos_param_string_set(exynos_camera, "auto-exposure-lock", "true"); + else + exynos_param_string_set(exynos_camera, "auto-exposure-lock", "false"); + } + + // AWB lock + + if (exynos_camera->config->presets[id].params.auto_white_balance_lock_supported == 1) { + exynos_param_string_set(exynos_camera, "auto-whitebalance-lock-supported", "true"); + + if (exynos_camera->config->presets[id].params.auto_white_balance_lock) + exynos_param_string_set(exynos_camera, "auto-whitebalance-lock", "true"); + else + exynos_param_string_set(exynos_camera, "auto-whitebalance-lock", "false"); + } + + // Flash + + exynos_param_string_set(exynos_camera, "flash-mode", + exynos_camera->config->presets[id].params.flash_mode); + exynos_param_string_set(exynos_camera, "flash-mode-values", + exynos_camera->config->presets[id].params.flash_mode_values); + + // Exposure + + exynos_param_int_set(exynos_camera, "exposure-compensation", + exynos_camera->config->presets[id].params.exposure_compensation); + exynos_param_float_set(exynos_camera, "exposure-compensation-step", + exynos_camera->config->presets[id].params.exposure_compensation_step); + exynos_param_int_set(exynos_camera, "min-exposure-compensation", + exynos_camera->config->presets[id].params.min_exposure_compensation); + exynos_param_int_set(exynos_camera, "max-exposure-compensation", + exynos_camera->config->presets[id].params.max_exposure_compensation); + + // Antibanding + + exynos_param_string_set(exynos_camera, "antibanding", + exynos_camera->config->presets[id].params.antibanding); + exynos_param_string_set(exynos_camera, "antibanding-values", + exynos_camera->config->presets[id].params.antibanding_values); + + // WB + + exynos_param_string_set(exynos_camera, "whitebalance", + exynos_camera->config->presets[id].params.whitebalance); + exynos_param_string_set(exynos_camera, "whitebalance-values", + exynos_camera->config->presets[id].params.whitebalance_values); + + // Scene mode + + exynos_param_string_set(exynos_camera, "scene-mode", + exynos_camera->config->presets[id].params.scene_mode); + exynos_param_string_set(exynos_camera, "scene-mode-values", + exynos_camera->config->presets[id].params.scene_mode_values); + + // Effect + + exynos_param_string_set(exynos_camera, "effect", + exynos_camera->config->presets[id].params.effect); + exynos_param_string_set(exynos_camera, "effect-values", + exynos_camera->config->presets[id].params.effect_values); + + // ISO + + exynos_param_string_set(exynos_camera, "iso", + exynos_camera->config->presets[id].params.iso); + exynos_param_string_set(exynos_camera, "iso-values", + exynos_camera->config->presets[id].params.iso_values); + + // Image stabilization (Anti-shake) + + exynos_param_string_set(exynos_camera, "image-stabilization", + exynos_camera->config->presets[id].params.image_stabilization); + exynos_param_string_set(exynos_camera, "image-stabilization-values", + exynos_camera->config->presets[id].params.image_stabilization_values); + + // Camera + + exynos_param_float_set(exynos_camera, "focal-length", + exynos_camera->config->presets[id].focal_length); + exynos_param_float_set(exynos_camera, "horizontal-view-angle", + exynos_camera->config->presets[id].horizontal_view_angle); + exynos_param_float_set(exynos_camera, "vertical-view-angle", + exynos_camera->config->presets[id].vertical_view_angle); + + rc = exynos_camera_params_apply(exynos_camera, 1); + if (rc < 0) { + ALOGE("%s: Unable to apply params", __func__); + return -1; + } + + return 0; +} + +static int validate_focus_areas(int l, int t, int r, int b, int w) { + if (!(l || r || t || b || w)) { + // All zeros is a valid area + return 0; + } + + // If existing, a focus area must be contained between -1000 and 1000, + // on both dimensions + if (l < -1000 || t < -1000 || r > 1000 || b > 1000) { + return -EINVAL; + } + // No superimposed or reverted edges + if (l >= r || t >= b) { + return -EINVAL; + } + // If there's an area defined, weight must be positive and up to 1000 + if ((l !=0 || r !=0) && (w < 1 || w > 1000)) { + return -EINVAL; + } + return 0; +} + +int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force) +{ + char *recording_hint_string; + char *recording_preview_size_string; + + char *preview_size_string; + int preview_width = 0; + int preview_height = 0; + char *preview_format_string; + int preview_format; + int preview_fps; + + char *picture_size_string; + int picture_width = 0; + int picture_height = 0; + char *picture_format_string; + int picture_format; + + int jpeg_thumbnail_width; + int jpeg_thumbnail_height; + int jpeg_thumbnail_quality; + int jpeg_quality; + + char *video_size_string; + int recording_width = 0; + int recording_height = 0; + char *video_frame_format_string; + int recording_format; + int camera_sensor_mode; + int fimc_is_mode = 0; + + char *focus_mode_string; + int focus_mode = FOCUS_MODE_DEFAULT; + char *focus_areas_string; + int focus_left, focus_top, focus_right, focus_bottom, focus_weight; + int focus_x; + int focus_y; + + char *zoom_supported_string; + int zoom, max_zoom; + + char *ae_lock_supported_string; + char *ae_lock_string; + int ae_lock = 0; + + char *awb_lock_supported_string; + char *awb_lock_string; + int awb_lock = 0; + int aeawb = 0; + + char *flash_mode_string; + int flash_mode = 0; + + int exposure_compensation; + int min_exposure_compensation; + int max_exposure_compensation; + + char *antibanding_string; + int antibanding; + + char *whitebalance_string; + int whitebalance; + + char *scene_mode_string; + int scene_mode; + + char *effect_string; + int effect; + + char *iso_string; + int iso; + + char *image_stabilization_string; + int image_stabilization; + + int w, h; + char *k; + int rc, i; + + if (exynos_camera == NULL) + return -EINVAL; + + // Preview + + preview_size_string = exynos_param_string_get(exynos_camera, "preview-size"); + if (preview_size_string != NULL) { + sscanf(preview_size_string, "%dx%d", &preview_width, &preview_height); + + if (preview_width < 0 && preview_height < 0) { + char reset_preview[128]; + sprintf(reset_preview, "%dx%d", exynos_camera->preview_width, exynos_camera->preview_height); + exynos_param_string_set(exynos_camera, "preview-size", + reset_preview); + return -EINVAL; + } + if (preview_width != 0 && preview_width != exynos_camera->preview_width) + exynos_camera->preview_width = preview_width; + if (preview_height != 0 && preview_height != exynos_camera->preview_height) + exynos_camera->preview_height = preview_height; + } + + preview_format_string = exynos_param_string_get(exynos_camera, "preview-format"); + if (preview_format_string != NULL) { + if (strcmp(preview_format_string, "yuv420sp") == 0) { + preview_format = V4L2_PIX_FMT_NV21; + } else if (strcmp(preview_format_string, "yuv420p") == 0) { + preview_format = V4L2_PIX_FMT_YUV420; + } else if (strcmp(preview_format_string, "rgb565") == 0) { + preview_format = V4L2_PIX_FMT_RGB565; + } else if (strcmp(preview_format_string, "rgb8888") == 0) { + preview_format = V4L2_PIX_FMT_RGB32; + } else { + ALOGE("%s: Unsupported preview format: %s", __func__, preview_format_string); + preview_format = V4L2_PIX_FMT_NV21; + } + + if (preview_format != exynos_camera->preview_format) + exynos_camera->preview_format = preview_format; + } + + preview_fps = exynos_param_int_get(exynos_camera, "preview-frame-rate"); + if (preview_fps > 0) + exynos_camera->preview_fps = preview_fps; + else + exynos_camera->preview_fps = 0; + + // Picture + + picture_format_string = exynos_param_string_get(exynos_camera, "picture-format"); + if (picture_format_string != NULL) { + if (strcmp(picture_format_string, "jpeg") == 0) { + picture_format = V4L2_PIX_FMT_JPEG; + } else { + ALOGE("%s: Unsupported picture format: %s", __func__, picture_format_string); + picture_format = V4L2_PIX_FMT_JPEG; + } + + if (picture_format != exynos_camera->picture_format) + exynos_camera->picture_format = picture_format; + } + + jpeg_thumbnail_width = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-width"); + if (jpeg_thumbnail_width > 0) + exynos_camera->jpeg_thumbnail_width = jpeg_thumbnail_width; + + jpeg_thumbnail_height = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-height"); + if (jpeg_thumbnail_height > 0) + exynos_camera->jpeg_thumbnail_height = jpeg_thumbnail_height; + + jpeg_thumbnail_quality = exynos_param_int_get(exynos_camera, "jpeg-thumbnail-quality"); + if (jpeg_thumbnail_quality > 0) + exynos_camera->jpeg_thumbnail_quality = jpeg_thumbnail_quality; + + jpeg_quality = exynos_param_int_get(exynos_camera, "jpeg-quality"); + if (jpeg_quality <= 100 && jpeg_quality >= 0 && (jpeg_quality != exynos_camera->jpeg_quality || force)) { + exynos_camera->jpeg_quality = jpeg_quality; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality); + if (rc < 0) + ALOGE("%s: Unable to set jpeg quality", __func__); + } + + // Recording + + video_size_string = exynos_param_string_get(exynos_camera, "video-size"); + if (video_size_string == NULL) + video_size_string = exynos_param_string_get(exynos_camera, "preview-size"); + + if (video_size_string != NULL) { + sscanf(video_size_string, "%dx%d", &recording_width, &recording_height); + + if (recording_width != 0 && recording_width != exynos_camera->recording_width) + exynos_camera->recording_width = recording_width; + if (recording_height != 0 && recording_height != exynos_camera->recording_height) + exynos_camera->recording_height = recording_height; + } + + video_frame_format_string = exynos_param_string_get(exynos_camera, "video-frame-format"); + if (video_frame_format_string != NULL) { + if (strcmp(video_frame_format_string, "yuv420sp") == 0) { + recording_format = V4L2_PIX_FMT_NV12; + } else if (strcmp(video_frame_format_string, "yuv420p") == 0) { + recording_format = V4L2_PIX_FMT_YUV420; + } else if (strcmp(video_frame_format_string, "rgb565") == 0) { + recording_format = V4L2_PIX_FMT_RGB565; + } else if (strcmp(video_frame_format_string, "rgb8888") == 0) { + recording_format = V4L2_PIX_FMT_RGB32; + } else { + ALOGE("%s: Unsupported recording format: %s", __func__, video_frame_format_string); + recording_format = V4L2_PIX_FMT_NV12; + } + + if (recording_format != exynos_camera->recording_format) + exynos_camera->recording_format = recording_format; + } + + recording_hint_string = exynos_param_string_get(exynos_camera, "recording-hint"); + if (recording_hint_string != NULL && strcmp(recording_hint_string, "true") == 0) { + camera_sensor_mode = SENSOR_MOVIE; + + k = exynos_param_string_get(exynos_camera, "preview-size-values"); + while (recording_width != 0 && recording_height != 0) { + if (k == NULL) + break; + + sscanf(k, "%dx%d", &w, &h); + + // Look for same aspect ratio + if ((recording_width * h) / recording_height == w) { + preview_width = w; + preview_height = h; + break; + } + + k = strchr(k, ','); + if (k == NULL) + break; + + k++; + } + + if (preview_width != 0 && preview_width != exynos_camera->preview_width) + exynos_camera->preview_width = preview_width; + if (preview_height != 0 && preview_height != exynos_camera->preview_height) + exynos_camera->preview_height = preview_height; + + if (exynos_camera->camera_fimc_is) + fimc_is_mode = IS_MODE_PREVIEW_VIDEO; + } else { + camera_sensor_mode = SENSOR_CAMERA; + + if (exynos_camera->camera_fimc_is) + fimc_is_mode = IS_MODE_PREVIEW_STILL; + } + + // Picture size and Video Snapshot Resolution + picture_size_string = exynos_param_string_get(exynos_camera, "picture-size"); + if (picture_size_string != NULL) { + sscanf(picture_size_string, "%dx%d", &picture_width, &picture_height); + + if (camera_sensor_mode == SENSOR_MOVIE) { + //Set Video Recording SnapShot Resolutions + if (exynos_camera->camera_videosnapshot_resolutions != NULL) { + //Back Camera + if (!exynos_camera->camera_fimc_is) { + for (i = 0; i < exynos_camera->camera_videosnapshot_resolutions_count; i++) { + if (exynos_camera->camera_videosnapshot_resolutions[i].video_width == exynos_camera->recording_width && exynos_camera->camera_videosnapshot_resolutions[i].video_height == exynos_camera->recording_height) { + picture_width = exynos_camera->camera_videosnapshot_resolutions[i].snapshot_width; + picture_height = exynos_camera->camera_videosnapshot_resolutions[i].snapshot_height; + break; + } + } + } else { + //Front Facing Camera - Use Recording size as Snapshot size + picture_width = exynos_camera->recording_width; + picture_height = exynos_camera->recording_height; + } + } + } + + if (picture_width != 0 && picture_height != 0 && (picture_width != exynos_camera->picture_width || picture_height != exynos_camera->picture_height)) { + exynos_camera->picture_width = picture_width; + exynos_camera->picture_height = picture_height; + + if (!exynos_camera->camera_fimc_is) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_JPEG_RESOLUTION, (picture_width & 0xffff) << 16 | (picture_height & 0xffff)); + if (rc < 0) + ALOGE("%s: Unable to set jpeg resolution", __func__); + } + } + } + + // Switching modes + + if (camera_sensor_mode != exynos_camera->camera_sensor_mode) { + exynos_camera->camera_sensor_mode = camera_sensor_mode; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SENSOR_MODE, camera_sensor_mode); + if (rc < 0) + ALOGE("%s: Unable to set sensor mode", __func__); + } + + if (exynos_camera->camera_fimc_is && fimc_is_mode != exynos_camera->fimc_is_mode) { + exynos_camera->fimc_is_mode = fimc_is_mode; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_S_FORMAT_SCENARIO, exynos_camera->fimc_is_mode); + if (rc < 0) + ALOGE("%s: Unable to set FIMC-IS scenario", __func__); + } + + // Focus + + focus_areas_string = exynos_param_string_get(exynos_camera, "focus-areas"); + if (focus_areas_string != NULL) { + focus_left = focus_top = focus_right = focus_bottom = focus_weight = 0; + + rc = sscanf(focus_areas_string, "(%d,%d,%d,%d,%d)", + &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weight); + if (rc != 5) { + ALOGE("%s: Unable to scan focus areas", __func__); + } else if (validate_focus_areas(focus_left, focus_top, focus_right, focus_bottom, focus_weight) != 0 || strstr(focus_areas_string, "),(")) { + exynos_param_string_set(exynos_camera, "focus-areas", + exynos_camera->raw_focus_areas); + return -EINVAL; + } else if ((focus_left != 0 || focus_right != 0) && (focus_top != 0 || focus_bottom != 0)) { + sprintf(exynos_camera->raw_focus_areas,"%s",focus_areas_string); + focus_x = (((focus_left + focus_right) / 2) + 1000) * preview_width / 2000; + focus_y = (((focus_top + focus_bottom) / 2) + 1000) * preview_height / 2000; + + if (focus_x != exynos_camera->focus_x || force) { + exynos_camera->focus_x = focus_x; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_X, focus_x); + if (rc < 0) + ALOGE("%s: Unable to set object x position", __func__); + } + + if (focus_y != exynos_camera->focus_y || force) { + exynos_camera->focus_y = focus_y; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_Y, focus_y); + if (rc < 0) + ALOGE("%s: Unable to set object y position", __func__); + } + + /* After taking a picture, focus-areas is reseted by stock camera app to the center of the screen */ + if (! ( (focus_x == (preview_width / 2)) && (focus_y == (preview_height / 2)) )) { + //ALOGV("%s focus_mode changed to %d due to focus-areas='%s'", __func__, focus_mode, focus_areas_string); + focus_mode = FOCUS_MODE_TOUCH; + } + } + + } + + // Zoom + + zoom_supported_string = exynos_param_string_get(exynos_camera, "zoom-supported"); + if (zoom_supported_string != NULL && strcmp(zoom_supported_string, "true") == 0) { + zoom = exynos_param_int_get(exynos_camera, "zoom"); + max_zoom = exynos_param_int_get(exynos_camera, "max-zoom"); + if (zoom <= max_zoom && zoom >= 0 && (zoom != exynos_camera->zoom || force)) { + exynos_camera->zoom = zoom; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ZOOM, zoom); + if (rc < 0) + ALOGE("%s: Unable to set camera zoom", __func__); + } else if (zoom > max_zoom) { + exynos_param_int_set(exynos_camera, "zoom", max_zoom); + return -EINVAL; + } + + } + + // AE lock + + ae_lock_supported_string = exynos_param_string_get(exynos_camera, "auto-exposure-lock-supported"); + ae_lock_string = exynos_param_string_get(exynos_camera, "auto-exposure-lock"); + if (ae_lock_supported_string != NULL && ae_lock_string != NULL && strcmp(ae_lock_supported_string, "true") == 0 && strcmp(ae_lock_string, "true") == 0) + ae_lock = 1; + else + ae_lock = 0; + + // AWB lock + + awb_lock_supported_string = exynos_param_string_get(exynos_camera, "auto-whitebalance-lock-supported"); + awb_lock_string = exynos_param_string_get(exynos_camera, "auto-whitebalance-lock"); + if (awb_lock_supported_string != NULL && awb_lock_string != NULL && strcmp(awb_lock_supported_string, "true") == 0 && strcmp(awb_lock_string, "true") == 0) + awb_lock = 1; + else + awb_lock = 0; + + // Scene mode + + scene_mode_string = exynos_param_string_get(exynos_camera, "scene-mode"); + if (scene_mode_string != NULL) { + if (strcmp(scene_mode_string, "auto") == 0) + scene_mode = SCENE_MODE_NONE; + else if (strcmp(scene_mode_string, "portrait") == 0) { + scene_mode = SCENE_MODE_PORTRAIT; + flash_mode = FLASH_MODE_AUTO; + } else if (strcmp(scene_mode_string, "landscape") == 0) + scene_mode = SCENE_MODE_LANDSCAPE; + else if (strcmp(scene_mode_string, "night") == 0) + scene_mode = SCENE_MODE_NIGHTSHOT; + else if (strcmp(scene_mode_string, "beach") == 0) + scene_mode = SCENE_MODE_BEACH_SNOW; + else if (strcmp(scene_mode_string, "snow") == 0) + scene_mode = SCENE_MODE_BEACH_SNOW; + else if (strcmp(scene_mode_string, "sunset") == 0) + scene_mode = SCENE_MODE_SUNSET; + else if (strcmp(scene_mode_string, "fireworks") == 0) + scene_mode = SCENE_MODE_FIREWORKS; + else if (strcmp(scene_mode_string, "action") == 0) + scene_mode = SCENE_MODE_SPORTS; + else if (strcmp(scene_mode_string, "party") == 0) { + scene_mode = SCENE_MODE_PARTY_INDOOR; + flash_mode = FLASH_MODE_AUTO; + } else if (strcmp(scene_mode_string, "candlelight") == 0) + scene_mode = SCENE_MODE_CANDLE_LIGHT; + else if (strcmp(scene_mode_string, "dusk-dawn") == 0) + scene_mode = SCENE_MODE_DUSK_DAWN; + else if (strcmp(scene_mode_string, "fall-color") == 0) + scene_mode = SCENE_MODE_FALL_COLOR; + else if (strcmp(scene_mode_string, "back-light") == 0) + scene_mode = SCENE_MODE_BACK_LIGHT; + else if (strcmp(scene_mode_string, "text") == 0) + scene_mode = SCENE_MODE_TEXT; + else if (strcmp(scene_mode_string, "high-sensitivity") == 0) + scene_mode = SCENE_MODE_LOW_LIGHT; + else + scene_mode = SCENE_MODE_NONE; + + if (scene_mode != exynos_camera->scene_mode || force) { + exynos_camera->scene_mode = scene_mode; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, scene_mode); + if (rc < 0) + ALOGE("%s: Unable to set scene mode", __func__); + } + + if (scene_mode != SCENE_MODE_NONE && !flash_mode && focus_mode == FOCUS_MODE_DEFAULT) { + flash_mode = FLASH_MODE_OFF; + focus_mode = FOCUS_MODE_AUTO; + } + } + + // Flash + + flash_mode_string = exynos_param_string_get(exynos_camera, "flash-mode"); + if (flash_mode_string != NULL) { + if (flash_mode == 0) { + if (strcmp(flash_mode_string, "off") == 0) + flash_mode = FLASH_MODE_OFF; + else if (strcmp(flash_mode_string, "auto") == 0) + flash_mode = FLASH_MODE_AUTO; + else if (strcmp(flash_mode_string, "on") == 0) + flash_mode = FLASH_MODE_ON; + else if (strcmp(flash_mode_string, "torch") == 0) + flash_mode = FLASH_MODE_TORCH; + else { + exynos_param_string_set(exynos_camera, "flash-mode", + exynos_camera->raw_flash_mode); + return -EINVAL; + } + } + + if (flash_mode != exynos_camera->flash_mode || force) { + exynos_camera->flash_mode = flash_mode; + sprintf(exynos_camera->raw_flash_mode, "%s", flash_mode_string); + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FLASH_MODE, flash_mode); + if (rc < 0) + ALOGE("%s:Unable to set flash mode", __func__); + } + } + + // Lock Auto Exposure and White Balance only when Flash is OFF + if ((ae_lock != exynos_camera->ae_lock || awb_lock != exynos_camera->awb_lock || force) && + exynos_camera->flash_mode == FLASH_MODE_OFF) { + exynos_camera->ae_lock = ae_lock; + exynos_camera->awb_lock = awb_lock; + aeawb = (ae_lock ? 0x1 : 0x0) | (awb_lock ? 0x2 : 0x0); + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, aeawb); + if (rc < 0) + ALOGE("%s: Unable to set AEAWB lock", __func__); + } + + focus_mode_string = exynos_param_string_get(exynos_camera, "focus-mode"); + if (focus_mode_string != NULL) { + if (focus_mode == FOCUS_MODE_DEFAULT) { + if (strcmp(focus_mode_string, "auto") == 0) + focus_mode = FOCUS_MODE_AUTO; + else if (strcmp(focus_mode_string, "infinity") == 0) + focus_mode = FOCUS_MODE_INFINITY; + else if (strcmp(focus_mode_string, "macro") == 0) + focus_mode = FOCUS_MODE_MACRO; + else if (strcmp(focus_mode_string, "fixed") == 0) + focus_mode = FOCUS_MODE_FIXED; + else if (strcmp(focus_mode_string, "facedetect") == 0) + focus_mode = FOCUS_MODE_FACEDETECT; + else if (strcmp(focus_mode_string, "continuous-video") == 0) + focus_mode = FOCUS_MODE_CONTINOUS_VIDEO; + else if (strcmp(focus_mode_string, "continuous-picture") == 0) + focus_mode = FOCUS_MODE_CONTINOUS_PICTURE; + else { + exynos_param_string_set(exynos_camera, "focus-mode", + exynos_camera->raw_focus_mode); + return -EINVAL; + } + } + + if (focus_mode != exynos_camera->focus_mode || force) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode); + if (rc < 0) + ALOGE("%s: Unable to set focus mode", __func__); + } + + exynos_camera->focus_mode = focus_mode; + sprintf(exynos_camera->raw_focus_mode, "%s", focus_mode_string); + } + + // Exposure + + exposure_compensation = exynos_param_int_get(exynos_camera, "exposure-compensation"); + min_exposure_compensation = exynos_param_int_get(exynos_camera, "min-exposure-compensation"); + max_exposure_compensation = exynos_param_int_get(exynos_camera, "max-exposure-compensation"); + + if (exposure_compensation <= max_exposure_compensation && exposure_compensation >= min_exposure_compensation && + (exposure_compensation != exynos_camera->exposure_compensation || force)) { + exynos_camera->exposure_compensation = exposure_compensation; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_BRIGHTNESS, exposure_compensation); + if (rc < 0) + ALOGE("%s: Unable to set exposure", __func__); + } + + // Antibanding + + antibanding_string = exynos_param_string_get(exynos_camera, "antibanding"); + if (antibanding_string != NULL) { + if (strcmp(antibanding_string, "auto") == 0) + antibanding = ANTI_BANDING_AUTO; + else if (strcmp(antibanding_string, "50hz") == 0) + antibanding = ANTI_BANDING_50HZ; + else if (strcmp(antibanding_string, "60hz") == 0) + antibanding = ANTI_BANDING_60HZ; + else if (strcmp(antibanding_string, "off") == 0) + antibanding = ANTI_BANDING_OFF; + else + antibanding = ANTI_BANDING_AUTO; + + if (antibanding != exynos_camera->antibanding || force) { + exynos_camera->antibanding = antibanding; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ANTI_BANDING, antibanding); + if (rc < 0) + ALOGE("%s: Unable to set antibanding", __func__); + } + } + + // WB + + whitebalance_string = exynos_param_string_get(exynos_camera, "whitebalance"); + if (whitebalance_string != NULL) { + if (strcmp(whitebalance_string, "auto") == 0) + whitebalance = WHITE_BALANCE_AUTO; + else if (strcmp(whitebalance_string, "incandescent") == 0) + whitebalance = WHITE_BALANCE_TUNGSTEN; + else if (strcmp(whitebalance_string, "fluorescent") == 0) + whitebalance = WHITE_BALANCE_FLUORESCENT; + else if (strcmp(whitebalance_string, "daylight") == 0) + whitebalance = WHITE_BALANCE_SUNNY; + else if (strcmp(whitebalance_string, "cloudy-daylight") == 0) + whitebalance = WHITE_BALANCE_CLOUDY; + else + whitebalance = WHITE_BALANCE_AUTO; + + if (whitebalance != exynos_camera->whitebalance || force) { + exynos_camera->whitebalance = whitebalance; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_WHITE_BALANCE, whitebalance); + if (rc < 0) + ALOGE("%s: Unable to set whitebalance", __func__); + } + } + + // Effect + + effect_string = exynos_param_string_get(exynos_camera, "effect"); + if (effect_string != NULL) { + if (strcmp(effect_string, "auto") == 0) + effect = IMAGE_EFFECT_NONE; + if (strcmp(effect_string, "none") == 0) + effect = IMAGE_EFFECT_NONE; + else if (strcmp(effect_string, "mono") == 0) + effect = IMAGE_EFFECT_BNW; + else if (strcmp(effect_string, "negative") == 0) + effect = IMAGE_EFFECT_NEGATIVE; + else if (strcmp(effect_string, "sepia") == 0) + effect = IMAGE_EFFECT_SEPIA; + else if (strcmp(effect_string, "aqua") == 0) + effect = IMAGE_EFFECT_AQUA; + else if (strcmp(effect_string, "solarize") == 0) + effect = IMAGE_EFFECT_SOLARIZE; + else if (strcmp(effect_string, "posterize") == 0) + effect = IMAGE_EFFECT_POSTERIZE; + else if (strcmp(effect_string, "washed") == 0) + effect = IMAGE_EFFECT_WASHED; + else if (strcmp(effect_string, "sketch") == 0) + effect = IMAGE_EFFECT_SKETCH; + else if (strcmp(effect_string, "vintage-warm") == 0) + effect = IMAGE_EFFECT_VINTAGE_WARM; + else if (strcmp(effect_string, "vintage-cold") == 0) + effect = IMAGE_EFFECT_VINTAGE_COLD; + else if (strcmp(effect_string, "point-blue") == 0) + effect = IMAGE_EFFECT_POINT_BLUE; + else if (strcmp(effect_string, "point-red-yellow") == 0) + effect = IMAGE_EFFECT_POINT_RED_YELLOW; + else if (strcmp(effect_string, "point-green") == 0) + effect = IMAGE_EFFECT_POINT_GREEN; + else + effect = IMAGE_EFFECT_NONE; + + if (effect != exynos_camera->effect || force) { + exynos_camera->effect = effect; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EFFECT, effect); + if (rc < 0) + ALOGE("%s: Unable to set effect", __func__); + } + } + + // ISO + + iso_string = exynos_param_string_get(exynos_camera, "iso"); + if (iso_string != NULL) { + if (strcmp(iso_string, "auto") == 0) + iso = ISO_AUTO; + else if (strcmp(iso_string, "ISO50") == 0) + iso = ISO_50; + else if (strcmp(iso_string, "ISO100") == 0) + iso = ISO_100; + else if (strcmp(iso_string, "ISO200") == 0) + iso = ISO_200; + else if (strcmp(iso_string, "ISO400") == 0) + iso = ISO_400; + else if (strcmp(iso_string, "ISO800") == 0) + iso = ISO_800; + else + iso = ISO_AUTO; + + if (iso != exynos_camera->iso || force) { + exynos_camera->iso = iso; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ISO, iso); + if (rc < 0) + ALOGE("%s: Unable to set iso", __func__); + } + } + + // Image stabilization (Anti-shake) + + image_stabilization_string = exynos_param_string_get(exynos_camera, "image-stabilization"); + if (image_stabilization_string != NULL) { + if (strcmp(image_stabilization_string, "on") == 0) + image_stabilization = ANTI_SHAKE_STILL_ON; + else + image_stabilization = ANTI_SHAKE_OFF; + + if (image_stabilization != exynos_camera->image_stabilization || force) { + exynos_camera->image_stabilization = image_stabilization; + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_ANTI_SHAKE, image_stabilization); + if (rc < 0) + ALOGE("%s: Unable to set image-stabilization", __func__); + } + } + ALOGD("%s: Preview size: %dx%d, picture size: %dx%d, recording size: %dx%d", __func__, preview_width, preview_height, picture_width, picture_height, recording_width, recording_height); + + return 0; +} + +// Capture + +int s5c73m3_interleaved_decode(struct exynos_camera *exynos_camera, void *data, int size, + void *yuv_data, int *yuv_size, int yuv_width, int yuv_height, + void *jpeg_data, int *jpeg_size, int *decoded, int *auto_focus_result, + struct exynos_exif *exif) +{ + exif_attribute_t *attributes; + camera_face_t caface[exynos_camera->max_detected_faces]; + int yuv_length; + int jpeg_length; + int num_detected_faces; + int face; + unsigned char *yuv_p; + unsigned char *jpeg_p; + unsigned char *data_p; + unsigned int *offset_p; + unsigned int pointers_array_offset; + unsigned int pointers_array_size; + unsigned int interleaved_size; + unsigned char s5c73m3_auto_focus_result; + unsigned int yuv_offset_last; + unsigned int yuv_offset; + unsigned int yuv_line_size; + unsigned short *jpeg_start_p; + int gap; + unsigned int i; + + if (data == NULL || size <= 0 || yuv_data == NULL || yuv_size == NULL || yuv_width <= 0 || yuv_height <= 0 || jpeg_data == NULL || jpeg_size == NULL || decoded == NULL || auto_focus_result == NULL) + return -EINVAL; + + yuv_length = 0; + jpeg_length = 0; + + data_p = (unsigned char *) data; + data_p += size - 0x1000; // End of the first plane (interleaved buffer) + data_p += 4046; // Experimental offset for decoded + + *decoded = (int) *data_p; + + data_p = (unsigned char *) data; + data_p += size - 0x1000; // End of the first plane (interleaved buffer) + data_p += 50; // Experimental offset for auto-focus result + + *auto_focus_result = (int) *data_p; + + data_p = (unsigned char *) data; + data_p += size - 0x1000; // End of the first plane (interleaved buffer) + data_p += 4084; // Experimental offset for interleaved size + + // Read the pointers array offset + offset_p = (unsigned int *) data_p; + pointers_array_offset = BIG2LITTLE_ENDIAN(*offset_p); + interleaved_size = pointers_array_offset; + + // Read the pointers array size, it should be 4 * yuv_height + data_p += sizeof(pointers_array_offset); + offset_p = (unsigned int *) data_p; + pointers_array_size = BIG2LITTLE_ENDIAN(*offset_p); + + // FaceDetection Information + data_p = (unsigned char *) data; + data_p += size - 0x1000; // End of the first plane (interleaved buffer) + data_p += 108; //Number of Faces Detected + + num_detected_faces = (int) *data_p; + data_p += 2; //Start of Face Detection Info + + exynos_camera->mFaceData.faces = caface; + if (num_detected_faces > 0 && num_detected_faces < exynos_camera->max_detected_faces) + { + for (face = 0; face < num_detected_faces; face++) { + exynos_camera->mFaceData.faces[face].rect[0] = (short)(data_p[1] << 8) + data_p[0]; + data_p += 2; + exynos_camera->mFaceData.faces[face].rect[1] = (short)(data_p[1] << 8) + data_p[0]; + data_p += 2; + exynos_camera->mFaceData.faces[face].rect[2] = (short)(data_p[1] << 8) + data_p[0]; + data_p += 2; + exynos_camera->mFaceData.faces[face].rect[3] = (short)(data_p[1] << 8) + data_p[0]; + data_p += 2; + exynos_camera->mFaceData.faces[face].score = (short)(data_p[1] << 8) + data_p[0]; + data_p += 2; + exynos_camera->mFaceData.faces[face].id = (short)(data_p[1] << 8) + data_p[0]; + data_p += 2; + } + } + exynos_camera->mFaceData.number_of_faces = num_detected_faces; + + if (!*decoded) + return 0; + + attributes = &exif->attributes; + + //Extract the EXIF from the Metadata + //Flash + data_p = (unsigned char *) data; + data_p += size - 0x1000; // End of the first plane (interleaved buffer) + data_p += 4; // EXIF Flash Offset + attributes->flash = (int) data_p[0]; + + //ISO + data_p += 4; // EXIF ISO Offset + attributes->iso_speed_rating = (data_p[1] << 8) + data_p[0]; + + //Exposure + data_p += 4; // EXIF Exposure Offset + attributes->brightness.num = (int) data_p[0]; + + //Exposure Bias + data_p += 4; // EXIF Exposure Bias Offset + attributes->exposure_bias.num = (data_p[1] << 8) + data_p[0]; + + //Exposure Time + data_p += 8; // EXIF Exposure Time Offset + attributes->exposure_time.den = (data_p[1] << 8) + data_p[0]; + + + ALOGD("%s: Interleaved pointers array is at offset 0x%x, 0x%x bytes long\n", __func__, pointers_array_offset, pointers_array_size); + + if ((int) pointers_array_offset > size || (int) pointers_array_size > size || (int) pointers_array_size < yuv_height * (int) sizeof(unsigned int)) { + ALOGE("%s: Invalid informations", __func__); + return -1; + } + + data_p = (unsigned char *) data; + data_p += pointers_array_offset; + yuv_p = (unsigned char *) yuv_data; + jpeg_p = (unsigned char *) jpeg_data; + jpeg_start_p = NULL; + + yuv_line_size = yuv_width * 2; + yuv_offset_last = 0; + yuv_offset = 0; + i = 0; + + while (i < pointers_array_size) { + offset_p = (unsigned int *) data_p; + yuv_offset = BIG2LITTLE_ENDIAN(*offset_p); + + if (yuv_offset > size - yuv_line_size) + return -1; + + gap = yuv_offset - yuv_offset_last - yuv_line_size; + + if (gap > 0) { + data_p = (unsigned char *) data + yuv_offset_last + yuv_line_size; + + if (jpeg_start_p == NULL) { + jpeg_start_p = (unsigned short *) data_p; + if (*jpeg_start_p != 0xd8ff) { + ALOGE("%s: Invalid jpeg start", __func__); + return -1; + } + } + + memcpy(jpeg_p, data_p, gap); + jpeg_p += gap; + jpeg_length += gap; + } + + yuv_offset_last = yuv_offset; + + data_p = (unsigned char *) data + yuv_offset; + memcpy(yuv_p, data_p, yuv_line_size); + yuv_p += yuv_line_size; + yuv_length += yuv_line_size; + + data_p = (unsigned char *) offset_p; + data_p += sizeof(yuv_offset); + i += sizeof(yuv_offset); + } + + gap = interleaved_size - yuv_offset_last - yuv_line_size; + + if (gap > 0) { + data_p = (unsigned char *) data + yuv_offset_last + yuv_line_size; + + memcpy(jpeg_p, data_p, gap); + jpeg_p += gap; + jpeg_length += gap; + } + + *yuv_size = yuv_length; + *jpeg_size = jpeg_length; + + return 0; +} + +int exynos_camera_capture(struct exynos_camera *exynos_camera) +{ + struct exynos_camera_buffer *buffers = NULL; + struct exynos_camera_buffer *buffer; + int width, height, format; + int yuv_length, jpeg_length; + int jpeg_offset, jpeg_size; + int jpeg_thumbnail_offset, jpeg_thumbnail_size; + int buffers_count; + int buffer_length; + int auto_focus_result; + int current_af; + int decoded; + int busy; + void *pointer; + void *picture_yuv_pointer = NULL; + int address; + int offset; + int index; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + width = exynos_camera->capture_width; + height = exynos_camera->capture_height; + format = exynos_camera->capture_format; + + buffers_count = exynos_camera->capture_buffers_count; + buffer_length = exynos_camera->capture_buffer_length; + + // V4L2 + + index = exynos_v4l2_dqbuf_cap(exynos_camera, 0); + if (index < 0 || index >= buffers_count) { + rc = exynos_v4l2_poll(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s Unable to poll", __func__); + goto error; + } else if (rc == 0) { + // Timeout + rc = 0; + goto complete; + } + + index = exynos_v4l2_dqbuf_cap(exynos_camera, 0); + if (index < 0 || index >= buffers_count) { + ALOGE("%s: Unable to dequeue buffer", __func__); + goto error; + } + } + + exynos_camera->capture_memory_index = index; + + address = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_Y, index); + if (address == 0 || address == (int) 0xffffffff) { + ALOGE("%s: Unable to get address", __func__); + goto error; + } + + offset = address - exynos_camera->capture_memory_address; + if (offset != index * buffer_length) + ALOGE("%s: Inconsistent memory offset (0x%x/0x%x)", __func__, offset, index * buffer_length); + + pointer = (void *) ((unsigned char *) exynos_camera->capture_memory->data + offset); + + // Buffers + + if (!exynos_camera->camera_fimc_is) { + yuv_length = jpeg_length = 0; + auto_focus_result = decoded = 0; + + rc = s5c73m3_interleaved_decode(exynos_camera, pointer, buffer_length, exynos_camera->capture_yuv_buffer, &yuv_length, width, height, exynos_camera->capture_jpeg_buffer, &jpeg_length, &decoded, &auto_focus_result, &exynos_camera->exif); + if (rc < 0) { + ALOGE("%s: Unable to decode S5C73M3 interleaved", __func__); + goto error; + } + + // AutoFocus + switch (auto_focus_result) { + case S5C73M3_CAF_STATUS_FOCUSING: + case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR: + case S5C73M3_AF_STATUS_FOCUSING: + current_af = CAMERA_AF_STATUS_IN_PROGRESS; + break; + case S5C73M3_CAF_STATUS_FOCUSED: + case S5C73M3_AF_STATUS_FOCUSED: + current_af = CAMERA_AF_STATUS_SUCCESS; + break; + case S5C73M3_CAF_STATUS_UNFOCUSED: + case S5C73M3_AF_STATUS_UNFOCUSED: + current_af = CAMERA_AF_STATUS_FAIL; + break; + case S5C73M3_AF_STATUS_INVALID: + default: + current_af = CAMERA_AF_STATUS_RESTART; + } + + if (exynos_camera->auto_focus_enabled) { + rc = exynos_camera_auto_focus(exynos_camera, current_af); + if (rc < 0) { + ALOGE("%s: Unable to auto focus", __func__); + goto error; + } + } + + // CAF + switch (auto_focus_result) { + case S5C73M3_CAF_STATUS_FOCUSING: + case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR: + current_af = CAMERA_AF_STATUS_IN_PROGRESS; + break; + case S5C73M3_CAF_STATUS_FOCUSED: + current_af = CAMERA_AF_STATUS_SUCCESS; + break; + case S5C73M3_CAF_STATUS_UNFOCUSED: + default: + current_af = CAMERA_AF_STATUS_RESTART; + } + + rc = exynos_camera_continuous_auto_focus(exynos_camera, current_af); + if (rc < 0) { + ALOGE("%s: Unable to continuous auto focus", __func__); + goto error; + } + + if (!decoded) { + buffers_count = 1; + buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer)); + + buffer = buffers; + + buffer->pointer = pointer; + buffer->address = address; + buffer->length = buffer_length; + buffer->width = width; + buffer->height = height; + buffer->format = V4L2_PIX_FMT_UYVY; + } else { + buffers_count = 2; + buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer)); + + buffer = buffers; + + memcpy(pointer, exynos_camera->capture_yuv_buffer, yuv_length); + + buffer->pointer = pointer; + buffer->address = address; + buffer->length = yuv_length; + buffer->width = width; + buffer->height = height; + buffer->format = V4L2_PIX_FMT_UYVY; + + memcpy(&exynos_camera->picture_yuv_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + pointer = (void *) ((unsigned char *) pointer + yuv_length); + address += yuv_length; + buffer = (struct exynos_camera_buffer *) ((unsigned char *) buffer + sizeof(struct exynos_camera_buffer)); + + memcpy(pointer, exynos_camera->capture_jpeg_buffer, jpeg_length); + + buffer->pointer = pointer; + buffer->address = address; + buffer->length = jpeg_length; + buffer->width = exynos_camera->picture_width; + buffer->height = exynos_camera->picture_height; + buffer->format = exynos_camera->picture_format; + + memcpy(&exynos_camera->picture_jpeg_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + exynos_camera_picture_thread_start(exynos_camera); + + memcpy(buffer, &exynos_camera->picture_yuv_buffer, sizeof(struct exynos_camera_buffer)); + } + } else { + buffers_count = 1; + buffers = (struct exynos_camera_buffer *) calloc(buffers_count, sizeof(struct exynos_camera_buffer)); + + buffer = buffers; + + buffer->pointer = pointer; + buffer->address = address; + buffer->length = buffer_length; + buffer->width = width; + buffer->height = height; + buffer->format = format; + + if (exynos_camera->picture_enabled) { + memcpy(&exynos_camera->picture_yuv_buffer, buffer, sizeof(struct exynos_camera_buffer)); + exynos_camera_picture_thread_start(exynos_camera); + } + } + + // Preview + if (exynos_camera->preview_enabled) { + memcpy(&exynos_camera->preview_buffer, buffer, sizeof(struct exynos_camera_buffer)); + if (!exynos_camera->preview_output_enabled) { + rc = exynos_camera_preview_output_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start Preview Output", __func__); + goto error; + } + } + rc = exynos_camera_preview(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to process Camera Preview", __func__); + goto error; + } + } + + //Recording + if (exynos_camera->recording_enabled) { + if (exynos_camera->recording_output_enabled) { + memcpy(&exynos_camera->recording_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + exynos_camera->recording_memory_index = index; + + rc = exynos_camera_recording(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to process Camera Recording", __func__); + goto error; + } + } else { + memcpy(&exynos_camera->recording_buffer, buffer, sizeof(struct exynos_camera_buffer)); + + rc = exynos_camera_recording_output_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start recording output", __func__); + goto error; + } + + } + } else { + if (exynos_camera->recording_output_enabled) + exynos_camera_recording_output_stop(exynos_camera); + } + + rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, index); + if (rc < 0) { + ALOGE("%s: Unable to queue buffer", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + if (buffers != NULL) + free(buffers); + + return rc; +} + +void *exynos_camera_capture_thread(void *data) +{ + struct exynos_camera *exynos_camera; + int rc; + + if (data == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) data; + + ALOGE("%s: Starting thread", __func__); + exynos_camera->capture_thread_running = 1; + + while (exynos_camera->capture_thread_enabled) { + pthread_mutex_lock(&exynos_camera->capture_lock_mutex); + + while (exynos_camera->capture_enabled) { + pthread_mutex_lock(&exynos_camera->capture_mutex); + + if (!exynos_camera->capture_enabled) { + pthread_mutex_unlock(&exynos_camera->capture_mutex); + break; + } + + rc = exynos_camera_capture(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to capture", __func__); + pthread_mutex_unlock(&exynos_camera->capture_mutex); + break; + } + + pthread_mutex_unlock(&exynos_camera->capture_mutex); + + // Wait a bit to let others lock the mutex if they need to + usleep(10); + } + } + + exynos_camera->capture_thread_running = 0; + ALOGE("%s: Exiting thread", __func__); + + return NULL; +} + +void exynos_camera_picture_thread_start(struct exynos_camera *exynos_camera) +{ + int rc; + + if (exynos_camera->picture_running) + return; + + exynos_camera->picture_completed = 0; + + pthread_attr_t thread_attr; + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + rc = pthread_create(&exynos_camera->picture_thread, &thread_attr, exynos_camera_picture, (void *) exynos_camera); + if (rc < 0) + ALOGE("%s: Unable to create thread", __func__); + + exynos_camera->picture_running = 1; + + return; +} + +int exynos_camera_capture_thread_start(struct exynos_camera *exynos_camera) +{ + pthread_attr_t thread_attr; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->capture_thread_enabled) { + ALOGE("Capture thread was already started!"); + return -1; + } + + pthread_mutex_init(&exynos_camera->capture_mutex, NULL); + pthread_mutex_init(&exynos_camera->capture_lock_mutex, NULL); + + // Initial lock + pthread_mutex_lock(&exynos_camera->capture_lock_mutex); + + pthread_attr_init(&thread_attr); + pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); + + exynos_camera->capture_thread_enabled = 1; + + rc = pthread_create(&exynos_camera->capture_thread, &thread_attr, exynos_camera_capture_thread, (void *) exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to create thread", __func__); + goto error; + } + + rc = 0; + goto complete; + +error: + pthread_mutex_destroy(&exynos_camera->capture_mutex); + pthread_mutex_destroy(&exynos_camera->capture_lock_mutex); + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_capture_thread_stop(struct exynos_camera *exynos_camera) +{ + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->capture_thread_enabled) { + ALOGE("Capture thread was already stopped!"); + return; + } + + exynos_camera->capture_enabled = 0; + exynos_camera->capture_thread_enabled = 0; + + pthread_mutex_unlock(&exynos_camera->capture_lock_mutex); + + // Wait for the thread to end + i = 0; + while (exynos_camera->capture_thread_running) { + if (i++ > 10000) { + ALOGE("Capture thread is taking too long to end, something is going wrong"); + break; + } + usleep(100); + } + + if (exynos_camera->capture_enabled) { + pthread_mutex_lock(&exynos_camera->capture_mutex); + exynos_camera_capture_stop(exynos_camera); + pthread_mutex_unlock(&exynos_camera->capture_mutex); + } + + pthread_mutex_destroy(&exynos_camera->capture_mutex); + pthread_mutex_destroy(&exynos_camera->capture_lock_mutex); +} + +int exynos_camera_capture_start(struct exynos_camera *exynos_camera) +{ + struct v4l2_streamparm fps_param; + int width, height, format; + int mbus_width, mbus_height; + int buffers_count, buffer_length; + camera_memory_t *memory = NULL; + int value; + int fd; + int rc; + int i; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->capture_enabled) { + ALOGE("Capture was already started!"); + return -1; + } + + width = exynos_camera->capture_width; + height = exynos_camera->capture_height; + format = exynos_camera->capture_format; + + // V4L2 + + if (!exynos_camera->camera_fimc_is) { + ALOGD("Enabling hybrid capture"); + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_HYBRID, 1); + if (rc < 0) { + ALOGE("%s: Unable to set hybrid", __func__); + goto error; + } + } else { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_S_FORMAT_SCENARIO, exynos_camera->fimc_is_mode); + if (rc < 0) { + ALOGE("%s: Unable to set FIMC-IS scenario", __func__); + goto error; + } + } + + rc = exynos_v4l2_enum_fmt_cap(exynos_camera, 0, format); + if (rc < 0) { + ALOGE("%s: Unable to enumerate formats", __func__); + goto error; + } + + mbus_width = width; + mbus_height = height; + + if (exynos_camera->camera_mbus_resolutions != NULL) { + for (i = 0; i < exynos_camera->camera_mbus_resolutions_count; i++) { + if (exynos_camera->camera_mbus_resolutions[i].width == width && exynos_camera->camera_mbus_resolutions[i].height == height) { + mbus_width = exynos_camera->camera_mbus_resolutions[i].mbus_width; + mbus_height = exynos_camera->camera_mbus_resolutions[i].mbus_height; + break; + } + } + } + + if (exynos_camera->camera_fimc_is) { + // Set MBUS width/height/format + rc = exynos_v4l2_s_fmt_pix(exynos_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, exynos_camera->fimc_is_mode, V4L2_PIX_FMT_MODE_PREVIEW); + if (rc < 0) { + ALOGE("%s: Unable to set MBUS capture pixel format", __func__); + goto error; + } + } + + rc = exynos_v4l2_s_fmt_pix_cap(exynos_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_PREVIEW); + if (rc < 0) { + ALOGE("%s: Unable to set capture pixel format", __func__); + goto error; + } + + if (!exynos_camera->camera_fimc_is) { + // Set MBUS width/height/format + rc = exynos_v4l2_s_fmt_pix(exynos_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, V4L2_FIELD_NONE, V4L2_PIX_FMT_MODE_PREVIEW); + if (rc < 0) { + ALOGE("%s: Unable to set MBUS capture pixel format", __func__); + goto error; + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CACHEABLE, 0); + if (rc < 0) { + ALOGE("%s: Unable to set cacheable", __func__); + goto error; + } + + // This must be set to 1 for interleaved data decoding + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_EMBEDDEDDATA_ENABLE, 1); + if (rc < 0) { + ALOGE("%s: Unable to set embdedded data enable", __func__); + goto error; + } + } else { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CACHEABLE, 1); + if (rc < 0) { + ALOGE("%s: Unable to set cacheable", __func__); + goto error; + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_S_SCENARIO_MODE, exynos_camera->fimc_is_mode); + if (rc < 0) { + ALOGE("%s: Unable to set FIMC-IS scenario mode", __func__); + goto error; + } + } + + // Let's assume FIMC0 has memory available through mmap + + for (i = EXYNOS_CAMERA_CAPTURE_BUFFERS_COUNT; i > 0; i--) { + rc = exynos_v4l2_reqbufs_cap(exynos_camera, 0, i); + if (rc >= 0) + break; + } + + if (rc < 0) { + ALOGE("%s: Unable to request buffers", __func__); + goto error; + } + + buffers_count = rc; + ALOGD("Found %d buffers available for capture!", buffers_count); + + memset(&fps_param, 0, sizeof(fps_param)); + fps_param.parm.capture.timeperframe.numerator = 1; + fps_param.parm.capture.timeperframe.denominator = exynos_camera->preview_fps; + + rc = exynos_v4l2_s_parm_cap(exynos_camera, 0, &fps_param); + if (rc < 0) { + ALOGE("%s: Unable to set fps", __func__); + goto error; + } + + for (i = 0; i < buffers_count; i++) { + rc = exynos_v4l2_querybuf_cap(exynos_camera, 0, i); + if (rc < 0) { + ALOGE("%s: Unable to query buffers", __func__); + goto error; + } + } + + buffer_length = rc; + + value = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_PADDR_Y, 0); + if (value == 0 || value == (int) 0xffffffff) { + ALOGE("%s: Unable to get address", __func__); + goto error; + } + + exynos_camera->capture_memory_address = value; + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + fd = exynos_v4l2_fd(exynos_camera, 0); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, 0); + goto error; + } + + exynos_camera->capture_memory = NULL; + + memory = exynos_camera->callbacks.request_memory(fd, buffer_length, buffers_count, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + + exynos_camera->capture_memory = memory; + + memory = exynos_camera->callbacks.request_memory(-1, 1, 1, exynos_camera->callbacks.user); + + exynos_camera->face_data = memory; + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + if (!exynos_camera->camera_fimc_is) { + exynos_camera->capture_yuv_buffer = malloc(buffer_length); + exynos_camera->capture_jpeg_buffer = malloc(buffer_length); + } + + // Start EXIF + memset(&exynos_camera->exif, 0, sizeof(struct exynos_exif)); + exynos_exif_start(exynos_camera, &exynos_camera->exif); + + for (i = 0; i < buffers_count; i++) { + rc = exynos_v4l2_qbuf_cap(exynos_camera, 0, i); + if (rc < 0) { + ALOGE("%s: Unable to queue buffer", __func__); + goto error; + } + } + + exynos_camera->capture_buffers_count = buffers_count; + exynos_camera->capture_buffer_length = buffer_length; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_ROTATION, + exynos_camera->camera_rotation); + if (rc < 0) { + ALOGE("%s: Unable to set rotation", __func__); + goto error; + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_HFLIP, + exynos_camera->camera_hflip); + if (rc < 0) { + ALOGE("%s: Unable to set hflip", __func__); + goto error; + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_VFLIP, + exynos_camera->camera_vflip); + if (rc < 0) { + ALOGE("%s: Unable to set vflip", __func__); + goto error; + } + + rc = exynos_v4l2_streamon_cap(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to start stream", __func__); + goto error; + } + + // Few Scene Modes require to be set after stream on + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, exynos_camera->scene_mode); + if (rc < 0) { + ALOGE("%s: Unable to set scene mode", __func__); + goto error; + } + + if (exynos_camera->camera_fimc_is) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_START); + if (rc < 0) { + ALOGE("%s: Unable to start face detection", __func__); + goto error; + } + } + + exynos_camera->capture_enabled = 1; + pthread_mutex_unlock(&exynos_camera->capture_lock_mutex); + + rc = 0; + goto complete; + +error: + if (exynos_camera->face_data != NULL && exynos_camera->face_data->release != NULL) { + exynos_camera->face_data->release(exynos_camera->face_data); + exynos_camera->face_data = NULL; + } + if (exynos_camera->capture_memory != NULL && exynos_camera->capture_memory->release != NULL) { + exynos_camera->capture_memory->release(exynos_camera->capture_memory); + exynos_camera->capture_memory = NULL; + } + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_capture_stop(struct exynos_camera *exynos_camera) +{ + int rc; + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->capture_enabled) { + ALOGE("Capture was already stopped!"); + return; + } + + if (!exynos_camera->camera_fimc_is) { + ALOGD("Disabling hybrid capture"); + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_HYBRID, 0); + if (rc < 0) + ALOGE("%s: Unable to set hybrid", __func__); + } + + if (exynos_camera->camera_fimc_is) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_CMD_FD, IS_FD_COMMAND_STOP); + if (rc < 0) + ALOGE("%s: Unable to stop face detection", __func__); + } + + rc = exynos_v4l2_streamoff_cap(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to stop stream", __func__); + } + + if (exynos_camera->face_data != NULL && exynos_camera->face_data->release != NULL) { + exynos_camera->face_data->release(exynos_camera->face_data); + exynos_camera->face_data = NULL; + } + + if (exynos_camera->capture_memory != NULL && exynos_camera->capture_memory->release != NULL) { + exynos_camera->capture_memory->release(exynos_camera->capture_memory); + exynos_camera->capture_memory = NULL; + } + + if (exynos_camera->capture_yuv_buffer != NULL) { + free(exynos_camera->capture_yuv_buffer); + exynos_camera->capture_yuv_buffer = NULL; + } + + if (exynos_camera->capture_jpeg_buffer != NULL) { + free(exynos_camera->capture_jpeg_buffer); + exynos_camera->capture_jpeg_buffer = NULL; + } + + if (&exynos_camera->exif.enabled) + exynos_exif_stop(exynos_camera, &exynos_camera->exif); + + exynos_camera->capture_enabled = 0; +} + +int exynos_camera_capture_setup(struct exynos_camera *exynos_camera) +{ + int width, height, format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + format = exynos_camera->camera_capture_format; + + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + + ALOGD("%s: Selected width: %d, height: %d, format: 0x%x", __func__, width, height, format); + + if (!exynos_camera->capture_enabled) { + exynos_camera->capture_width = width; + exynos_camera->capture_height = height; + exynos_camera->capture_format = format; + + rc = exynos_camera_capture_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start capture", __func__); + return -1; + } + } else if (exynos_camera->capture_width != width || exynos_camera->capture_height != height || exynos_camera->capture_format != format) { + exynos_camera_capture_stop(exynos_camera); + + exynos_camera->capture_width = width; + exynos_camera->capture_height = height; + exynos_camera->capture_format = format; + + rc = exynos_camera_capture_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start capture", __func__); + return -1; + } + } + + return 0; +} + +// Preview + +int exynos_camera_preview_output_start(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->preview_output_enabled) { + ALOGE("Preview was already started!"); + return -1; + } + + output = &exynos_camera->preview_output; + + memset(output, 0, sizeof(struct exynos_v4l2_output)); + output->v4l2_id = 1; + output->width = exynos_camera->preview_width; + output->height = exynos_camera->preview_height; + output->format = exynos_camera->preview_format; + output->buffer_width = exynos_camera->preview_buffer.width; + output->buffer_height = exynos_camera->preview_buffer.height; + output->buffer_format = exynos_camera->preview_buffer.format; + output->buffers_count = EXYNOS_CAMERA_PREVIEW_BUFFERS_COUNT; + + rc = exynos_v4l2_output_start(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to start preview output", __func__); + goto error; + } + + exynos_camera->preview_output_enabled = 1; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +void exynos_camera_preview_output_stop(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->preview_output_enabled) { + ALOGE("Preview was already stopped!"); + return; + } + + output = &exynos_camera->preview_output; + + exynos_v4l2_output_stop(exynos_camera, output); + + exynos_camera->preview_output_enabled = 0; +} + +int exynos_camera_preview(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int width, height, format; + buffer_handle_t *window_buffer; + void *window_data; + int window_stride; + camera_memory_t *memory; + camera_face_t caface[exynos_camera->max_detected_faces]; + void *memory_pointer; + int memory_index; + int memory_size; + int rc; + + if (exynos_camera == NULL) + goto error; + +// ALOGD("%s()", __func__); + + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + format = exynos_camera->preview_format; + + output = &exynos_camera->preview_output; + + if (exynos_camera->preview_output_enabled) { + rc = exynos_v4l2_output(exynos_camera, output, exynos_camera->preview_buffer.address); + if (rc < 0) { + ALOGE("%s: Unable to output preview", __func__); + goto error; + } + + memory = output->memory; + memory_index = output->memory_index; + memory_pointer = (void *) ((unsigned char *) memory->data + output->buffer_length * memory_index); + memory_size = output->buffer_length; + } else { + // In that case, we can directly use the capture memory + memory = exynos_camera->capture_memory; + memory_index = exynos_camera->capture_memory_index; + memory_pointer = exynos_camera->preview_buffer.pointer; + memory_size = exynos_camera->preview_buffer.length; + } + + if (exynos_camera->preview_window != NULL && exynos_camera->gralloc != NULL) { + int ret = exynos_camera->preview_window->dequeue_buffer(exynos_camera->preview_window, &window_buffer, &window_stride); + if (ret < 0) { + ALOGE("%s: Error in dequeueing buffer", __func__); + goto error; + } + ret = exynos_camera->gralloc->lock(exynos_camera->gralloc, *window_buffer, GRALLOC_USAGE_YUV_ADDR | GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, width, height, &window_data); + + if (window_data == NULL || ret == -EINVAL) { + ALOGE("%s: Unable to lock gralloc", __func__); + goto error; + } + + memcpy(window_data, memory_pointer, memory_size); + + exynos_camera->gralloc->unlock(exynos_camera->gralloc, *window_buffer); + exynos_camera->preview_window->enqueue_buffer(exynos_camera->preview_window, window_buffer); + } + + if (exynos_camera->camera_fimc_is) { + exynos_camera->mFaceData.faces = caface; + exynos_v4l2_s_ext_ctrl_face_detection(exynos_camera, 0, &exynos_camera->mFaceData); + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_PREVIEW_FRAME) && EXYNOS_CAMERA_CALLBACK_DEFINED(data) && !exynos_camera->callback_lock) { + exynos_camera->callbacks.data(CAMERA_MSG_PREVIEW_FRAME, memory, memory_index, NULL, exynos_camera->callbacks.user); + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_PREVIEW_METADATA) && EXYNOS_CAMERA_CALLBACK_DEFINED(data) && !exynos_camera->callback_lock) { + exynos_camera->callbacks.data(CAMERA_MSG_PREVIEW_METADATA, exynos_camera->face_data, 0, &exynos_camera->mFaceData, exynos_camera->callbacks.user); + } + + if (exynos_camera->preview_output_enabled) { + rc = exynos_v4l2_output_release(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to release preview output", __func__); + goto error; + } + } + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +int exynos_camera_preview_start(struct exynos_camera *exynos_camera) +{ + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->preview_enabled) { + ALOGE("Preview was already started!"); + return -1; + } + + exynos_camera_capture_setup(exynos_camera); + + exynos_camera->preview_enabled = 1; + + return 0; +} + +void exynos_camera_preview_stop(struct exynos_camera *exynos_camera) +{ + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->preview_enabled) { + ALOGE("Preview was already stopped!"); + return; + } + + exynos_camera->preview_enabled = 0; + + if (exynos_camera->capture_enabled) { + pthread_mutex_lock(&exynos_camera->capture_mutex); + exynos_camera_capture_stop(exynos_camera); + pthread_mutex_unlock(&exynos_camera->capture_mutex); + } + + if (exynos_camera->preview_output_enabled) + exynos_camera_preview_output_stop(exynos_camera); + + exynos_camera->preview_window = NULL; +} + +// Picture + +void *exynos_camera_picture(void *data) +{ + struct exynos_camera *exynos_camera; + struct exynos_camera_buffer *jpeg_buffer; + struct exynos_camera_buffer *yuv_buffer; + struct exynos_v4l2_output output; + struct exynos_jpeg jpeg; + int output_enabled = 0; + int width, height, format; + int buffer_width, buffer_height, buffer_format, buffer_address; + camera_memory_t *memory = NULL; + int memory_size; + unsigned char *p; + camera_memory_t *jpeg_memory = NULL; + void *jpeg_data = NULL; + int jpeg_size = 0; + camera_memory_t *jpeg_thumbnail_memory = NULL; + void *jpeg_thumbnail_data = NULL; + int jpeg_thumbnail_size = 0; + void *yuv_data = NULL; + int yuv_address = 0; + int yuv_size = 0; + void *yuv_thumbnail_data = NULL; + int yuv_thumbnail_address; + int yuv_thumbnail_size = 0; + int rc; + + exynos_camera = (struct exynos_camera *) data; + + if (exynos_camera == NULL) + goto error; + + ALOGD("%s()", __func__); + + jpeg_buffer = &exynos_camera->picture_jpeg_buffer; + yuv_buffer = &exynos_camera->picture_yuv_buffer; + + if (jpeg_buffer->pointer != NULL && jpeg_buffer->length > 0) { + jpeg_data = jpeg_buffer->pointer; + jpeg_size = jpeg_buffer->length; + } + + if (yuv_buffer->pointer != NULL && yuv_buffer->length > 0) { + yuv_data = yuv_buffer->pointer; + yuv_address = yuv_buffer->address; + yuv_size = yuv_buffer->length; + } + + // JPEG + + if (jpeg_data == NULL) { + if (yuv_data == NULL || yuv_size <= 0) { + ALOGE("%s: Unable to create jpeg without an YUV buffer", __func__); + goto error; + } + + width = exynos_camera->picture_width; + height = exynos_camera->picture_height; + format = yuv_buffer->format; + + buffer_width = yuv_buffer->width; + buffer_height = yuv_buffer->height; + buffer_format = yuv_buffer->format; + buffer_address = yuv_buffer->address; + + if ((width != buffer_width && height != buffer_height) || exynos_camera->camera_fimc_is) { + format = EXYNOS_CAMERA_PICTURE_OUTPUT_FORMAT; + + memset(&output, 0, sizeof(output)); + output.v4l2_id = 2; + output.width = width; + output.height = height; + output.format = format; + output.buffer_width = buffer_width; + output.buffer_height = buffer_height; + output.buffer_format = buffer_format; + output.buffers_count = 1; + + rc = exynos_v4l2_output_start(exynos_camera, &output); + if (rc < 0) { + ALOGE("%s: Unable to start picture output", __func__); + goto error; + } + + rc = exynos_v4l2_output(exynos_camera, &output, buffer_address); + if (rc < 0) { + ALOGE("%s: Unable to output picture", __func__); + goto error; + } + + output_enabled = 1; + + yuv_data = output.memory->data; + yuv_address = output.memory_address; + yuv_size = output.buffer_length; + + if (exynos_camera->camera_fimc_is) + exynos_exif_create(exynos_camera, &exynos_camera->exif); + } + + memset(&jpeg, 0, sizeof(jpeg)); + jpeg.width = width; + jpeg.height = height; + jpeg.format = format; + jpeg.quality = exynos_camera->jpeg_quality; + + rc = exynos_jpeg_start(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to start jpeg", __func__); + goto error; + } + + if (jpeg.memory_in_pointer == NULL) { + ALOGE("%s: Invalid memory input pointer", __func__); + goto error; + } + + memcpy(jpeg.memory_in_pointer, yuv_data, yuv_size); + + rc = exynos_jpeg(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to jpeg", __func__); + goto error; + } + + jpeg_size = jpeg.memory_out_size; + if (jpeg_size <= 0) { + ALOGE("%s: Invalid jpeg size", __func__); + goto error; + } + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + jpeg_memory = exynos_camera->callbacks.request_memory(-1, jpeg_size, 1, exynos_camera->callbacks.user); + if (jpeg_memory == NULL || jpeg_memory->data == NULL || jpeg_memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + jpeg_data = jpeg_memory->data; + + memcpy(jpeg_data, jpeg.memory_out_pointer, jpeg_size); + + exynos_jpeg_stop(exynos_camera, &jpeg); + + if (output_enabled) { + exynos_v4l2_output_stop(exynos_camera, &output); + output_enabled = 0; + } + } + + // Thumbnail + + if (yuv_data == NULL || yuv_size <= 0) { + ALOGE("%s: Unable to create jpeg thumbnail without an YUV buffer", __func__); + goto error; + } + + width = exynos_camera->jpeg_thumbnail_width; + height = exynos_camera->jpeg_thumbnail_height; + format = yuv_buffer->format; + + buffer_width = yuv_buffer->width; + buffer_height = yuv_buffer->height; + buffer_format = yuv_buffer->format; + buffer_address = yuv_buffer->address; + + if (width != buffer_width && height != buffer_height) { + format = EXYNOS_CAMERA_PICTURE_OUTPUT_FORMAT; + + memset(&output, 0, sizeof(output)); + output.v4l2_id = 2; + output.width = width; + output.height = height; + output.format = format; + output.buffer_width = buffer_width; + output.buffer_height = buffer_height; + output.buffer_format = buffer_format; + output.buffers_count = 1; + + rc = exynos_v4l2_output_start(exynos_camera, &output); + if (rc < 0) { + ALOGE("%s: Unable to start thumbnail picture output", __func__); + goto error; + } + + output_enabled = 1; + + rc = exynos_v4l2_output(exynos_camera, &output, buffer_address); + if (rc < 0) { + ALOGE("%s: Unable to output thumbnail picture", __func__); + goto error; + } + + yuv_thumbnail_data = output.memory->data; + yuv_thumbnail_address = output.memory_address; + yuv_thumbnail_size = output.buffer_length; + } + + memset(&jpeg, 0, sizeof(jpeg)); + jpeg.width = width; + jpeg.height = height; + jpeg.format = format; + jpeg.quality = exynos_camera->jpeg_thumbnail_quality; + + rc = exynos_jpeg_start(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to start jpeg", __func__); + goto error; + } + + if (jpeg.memory_in_pointer == NULL) { + ALOGE("%s: Invalid memory input pointer", __func__); + goto error; + } + + memcpy(jpeg.memory_in_pointer, yuv_thumbnail_data, yuv_thumbnail_size); + + rc = exynos_jpeg(exynos_camera, &jpeg); + if (rc < 0) { + ALOGE("%s: Unable to jpeg", __func__); + goto error; + } + + jpeg_thumbnail_size = jpeg.memory_out_size; + if (jpeg_thumbnail_size <= 0) { + ALOGE("%s: Invalid jpeg size", __func__); + goto error; + } + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + jpeg_thumbnail_memory = exynos_camera->callbacks.request_memory(-1, jpeg_thumbnail_size, 1, exynos_camera->callbacks.user); + if (jpeg_thumbnail_memory == NULL || jpeg_thumbnail_memory->data == NULL || jpeg_thumbnail_memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + jpeg_thumbnail_data = jpeg_thumbnail_memory->data; + + memcpy(jpeg_thumbnail_data, jpeg.memory_out_pointer, jpeg_thumbnail_size); + + exynos_jpeg_stop(exynos_camera, &jpeg); + + if (output_enabled) { + exynos_v4l2_output_stop(exynos_camera, &output); + output_enabled = 0; + } + + // EXIF + exynos_exif_create(exynos_camera, &exynos_camera->exif); + + exynos_camera->exif.jpeg_thumbnail_data = jpeg_thumbnail_data; + exynos_camera->exif.jpeg_thumbnail_size = jpeg_thumbnail_size; + + rc = exynos_exif(exynos_camera, &exynos_camera->exif); + if (rc < 0) { + ALOGE("%s: Unable to exif", __func__); + goto error; + } + + memory_size = exynos_camera->exif.memory_size + jpeg_size; + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(-1, memory_size, 1, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + p = (unsigned char *) memory->data; + + // Copy the first two bytes of the JPEG picture + memcpy(p, jpeg_data, 2); + p += 2; + + // Copy the EXIF data + memcpy(p, exynos_camera->exif.memory->data, exynos_camera->exif.memory_size); + p += exynos_camera->exif.memory_size; + + // Copy the JPEG picture + memcpy(p, (void *) ((unsigned char *) jpeg_data + 2), jpeg_size - 2); + + exynos_camera->picture_memory = memory; + + goto complete; + +error: + if (output_enabled) + exynos_v4l2_output_stop(exynos_camera, &output); + + if (memory != NULL && memory->release != NULL) { + memory->release(memory); + exynos_camera->picture_memory = NULL; + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_ERROR) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_ERROR, -1, 0, exynos_camera->callbacks.user); + +complete: + if (jpeg_memory != NULL && jpeg_memory->release != NULL) + jpeg_memory->release(jpeg_memory); + + if (jpeg_thumbnail_memory != NULL && jpeg_thumbnail_memory->release != NULL) + jpeg_thumbnail_memory->release(jpeg_thumbnail_memory); + + + exynos_camera->picture_completed = 1; + + exynos_camera_picture_stop(exynos_camera); + exynos_camera->picture_running = 0; + + return NULL; +} + +int exynos_camera_picture_start(struct exynos_camera *exynos_camera) +{ + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->picture_enabled) { + ALOGE("Picture was already started!"); + return 0; + } + + if (!exynos_camera->camera_fimc_is) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_CAPTURE, 0); + if (rc < 0) { + ALOGE("%s: Unable to set capture", __func__); + return -1; + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_HYBRID_CAPTURE, 1); + if (rc < 0) { + ALOGE("%s: Unable to set hybrid capture", __func__); + return -1; + } + } + + exynos_camera->picture_enabled = 1; + + return 0; +} + +void exynos_camera_picture_stop(struct exynos_camera *exynos_camera) +{ + camera_memory_t *memory; + int rc, i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->picture_enabled) { + ALOGE("Picture was already stopped!"); + return; + } + + memory = exynos_camera->picture_memory; + + if (exynos_camera->picture_completed && memory != NULL) { + // It is important to return at this point (and not before) for burst + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_SHUTTER) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_SHUTTER, 0, 0, exynos_camera->callbacks.user); + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_COMPRESSED_IMAGE) && EXYNOS_CAMERA_CALLBACK_DEFINED(data) && !exynos_camera->callback_lock) + exynos_camera->callbacks.data(CAMERA_MSG_COMPRESSED_IMAGE, memory, 0, NULL, exynos_camera->callbacks.user); + + if (memory->release != NULL) { + memory->release(memory); + exynos_camera->picture_memory = NULL; + } + } + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, AE_UNLOCK_AWB_UNLOCK); + if (rc < 0) + ALOGE("%s: Unable to set AEAWB lock", __func__); + + exynos_camera->picture_enabled = 0; +} + +// Recording + +int exynos_camera_recording_output_start(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->recording_output_enabled) { + ALOGE("Recording was already started!"); + return -1; + } + + output = &exynos_camera->recording_output; + + memset(output, 0, sizeof(struct exynos_v4l2_output)); + output->v4l2_id = 3; + output->width = exynos_camera->recording_width; + output->height = exynos_camera->recording_height; + output->format = exynos_camera->recording_format; + output->buffer_width = exynos_camera->recording_buffer.width; + output->buffer_height = exynos_camera->recording_buffer.height; + output->buffer_format = exynos_camera->recording_buffer.format; + output->buffers_count = EXYNOS_CAMERA_RECORDING_BUFFERS_COUNT; + + rc = exynos_v4l2_output_start(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to start recording output", __func__); + goto error; + } + + exynos_camera->recording_output_enabled = 1; + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +void exynos_camera_recording_output_stop(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->recording_output_enabled) { + ALOGE("Recording was already stopped!"); + return; + } + + output = &exynos_camera->recording_output; + + exynos_v4l2_output_stop(exynos_camera, output); + + exynos_camera->recording_output_enabled = 0; +} + +void exynos_camera_recording_frame_release(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + int rc; + + if (exynos_camera == NULL) + return; + +// ALOGD("%s()", __func__); + + output = &exynos_camera->recording_output; + + if (!exynos_camera->recording_output_enabled) { + ALOGE("%s: Recording output should always be enabled", __func__); + return; + } + + rc = exynos_v4l2_output_release(exynos_camera, output); + if (rc < 0) { + ALOGE("%s: Unable to release recording output", __func__); + return; + } +} + +int exynos_camera_recording(struct exynos_camera *exynos_camera) +{ + struct exynos_v4l2_output *output; + struct exynos_camera_addrs *addrs; + int width, height, format; + camera_memory_t *memory; + int memory_address; + int memory_index; + int buffer_length; + int buffers_count; + nsecs_t timestamp; + int rc; + + if (exynos_camera == NULL) + goto error; + +// ALOGD("%s()", __func__); + + width = exynos_camera->recording_width; + height = exynos_camera->recording_height; + format = exynos_camera->recording_format; + + output = &exynos_camera->recording_output; + + buffer_length = exynos_camera->recording_buffer_length; + buffers_count = exynos_camera->recording_buffers_count; + + timestamp = systemTime(1); + + if (!exynos_camera->recording_output_enabled) { + ALOGE("%s: Recording output should always be enabled", __func__); + goto error; + } + + rc = exynos_v4l2_output(exynos_camera, output, exynos_camera->recording_buffer.address); + if (rc < 0) { + ALOGE("%s: Unable to output recording", __func__); + goto error; + } + + if (exynos_camera->recording_metadata) { + memory = exynos_camera->recording_memory; + memory_index = exynos_camera->recording_memory_index; + memory_address = output->memory_address + output->buffer_length * output->memory_index; + + addrs = (struct exynos_camera_addrs *) ((unsigned char *) memory->data + buffer_length * memory_index); + memset(addrs, 0, sizeof(struct exynos_camera_addrs)); + addrs->type = 0; // kMetadataBufferTypeCameraSource + addrs->index = memory_index; + + exynos_camera_yuv_planes(width, height, format, memory_address, (int *) &addrs->y, (int *) &addrs->cbcr, NULL); + } else { + memory = output->memory; + memory_index = output->memory_index; + } + + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_VIDEO_FRAME) && EXYNOS_CAMERA_CALLBACK_DEFINED(data_timestamp) && !exynos_camera->callback_lock) + exynos_camera->callbacks.data_timestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, memory, memory_index, exynos_camera->callbacks.user); + else + exynos_camera_recording_frame_release(exynos_camera); + + rc = 0; + goto complete; + +error: + rc = -1; + +complete: + return rc; +} + +int exynos_camera_recording_start(struct exynos_camera *exynos_camera) +{ + int rc; + + camera_memory_t *memory = NULL; + int buffer_length; + int buffers_count; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + if (exynos_camera->recording_enabled) { + ALOGE("Recording was already started!"); + return -1; + } + + exynos_camera->recording_enabled = 1; + + if (exynos_camera->recording_metadata) { + buffer_length = sizeof(struct exynos_camera_addrs); + buffers_count = EXYNOS_CAMERA_RECORDING_BUFFERS_COUNT; + + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(-1, buffer_length, buffers_count, exynos_camera->callbacks.user); + if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { + ALOGE("%s: Unable to request memory", __func__); + goto error; + } + } else { + ALOGE("%s: No memory request function!", __func__); + goto error; + } + + exynos_camera->recording_memory = memory; + exynos_camera->recording_buffer_length = buffer_length; + exynos_camera->recording_buffers_count = buffers_count; + } + + rc = 0; + goto complete; + +error: + if (memory != NULL && memory->release != NULL) { + memory->release(memory); + exynos_camera->recording_memory = NULL; + } + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_recording_stop(struct exynos_camera *exynos_camera) +{ + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (!exynos_camera->recording_enabled) { + ALOGE("Recording was already stopped!"); + return; + } + + exynos_camera->recording_enabled = 0; + +} + +// Auto-focus + + +int exynos_camera_auto_focus(struct exynos_camera *exynos_camera, int auto_focus_status) +{ + if (exynos_camera == NULL) + return -EINVAL; + +// ALOGD("%s()", __func__); + + switch (auto_focus_status) { + case CAMERA_AF_STATUS_SUCCESS: + if (exynos_camera->auto_focus_started) { + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS, 1, 0, exynos_camera->callbacks.user); + exynos_camera_auto_focus_finish(exynos_camera); + } + break; + case CAMERA_AF_STATUS_FAIL: + if (exynos_camera->auto_focus_started) { + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS, 0, 0, exynos_camera->callbacks.user); + exynos_camera_auto_focus_finish(exynos_camera); + } + break; + case CAMERA_AF_STATUS_IN_PROGRESS: + exynos_camera->auto_focus_started = 1; + break; + case CAMERA_AF_STATUS_RESTART: + default: + break; + } + + return 0; +} + +int exynos_camera_continuous_auto_focus(struct exynos_camera *exynos_camera, int auto_focus_status) +{ + if (exynos_camera == NULL) + return -EINVAL; + + switch (auto_focus_status) { + case CAMERA_AF_STATUS_IN_PROGRESS: + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS_MOVE) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS_MOVE, 1, 0, exynos_camera->callbacks.user); + + break; + case CAMERA_AF_STATUS_SUCCESS: + if (EXYNOS_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS_MOVE) && EXYNOS_CAMERA_CALLBACK_DEFINED(notify) && !exynos_camera->callback_lock) + exynos_camera->callbacks.notify(CAMERA_MSG_FOCUS_MOVE, 0, 0, exynos_camera->callbacks.user); + break; + case CAMERA_AF_STATUS_RESTART: + default: + break; + } + + return 0; +} + +int exynos_camera_auto_focus_start(struct exynos_camera *exynos_camera) +{ + int auto_focus; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + ALOGD("%s()", __func__); + + auto_focus = AUTO_FOCUS_ON | (exynos_camera->preview_width & 0xfff) << 20 | (exynos_camera->preview_height & 0xfff) << 8; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, auto_focus); + if (rc < 0) { + ALOGE("%s: Unable to set auto-focus on", __func__); + goto error; + } + + exynos_camera->auto_focus_enabled = 1; + + rc = 0; + goto complete; + +error: + + rc = -1; + +complete: + return rc; +} + +void exynos_camera_auto_focus_finish(struct exynos_camera *exynos_camera) +{ + int rc; + + ALOGD("%s()", __func__); + + if (!exynos_camera->auto_focus_enabled) { + return; + } + + exynos_camera->auto_focus_enabled = 0; + exynos_camera->auto_focus_started = 0; + + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, AE_UNLOCK_AWB_UNLOCK); + if (rc < 0) + ALOGE("%s: Unable to set AEAWB lock", __func__); +} + +void exynos_camera_auto_focus_stop(struct exynos_camera *exynos_camera) +{ + int rc; + int i; + + if (exynos_camera == NULL) + return; + + ALOGD("%s()", __func__); + + if (exynos_camera->auto_focus_enabled) { + rc = exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF); + if (rc < 0) + ALOGE("%s: Unable to set auto-focus off", __func__); + exynos_camera_auto_focus_finish(exynos_camera); + } + +} + +/* + * Exynos Camera OPS + */ + +int exynos_camera_set_preview_window(struct camera_device *dev, + struct preview_stream_ops *w) +{ + struct exynos_camera *exynos_camera; + + int width, height, format, gralloc_format; + + buffer_handle_t *buffer; + int stride; + void *addr = NULL; + + int rc; + + ALOGD("%s(%p, %p)", __func__, dev, w); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + if (w == NULL) { + exynos_camera->preview_window = NULL; + return 0; + } + + if (w->set_buffer_count == NULL || w->set_usage == NULL || w->set_buffers_geometry == NULL) + goto error; + + rc = w->set_buffer_count(w, EXYNOS_CAMERA_GRALLOC_BUFFERS_COUNT); + if (rc) { + ALOGE("%s: Unable to set buffer count: %d", __func__, EXYNOS_CAMERA_GRALLOC_BUFFERS_COUNT); + goto error; + } + + rc = w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN); + if (rc) { + ALOGE("%s: Unable to set usage", __func__); + goto error; + } + + width = exynos_camera->preview_width; + height = exynos_camera->preview_height; + format = exynos_camera->preview_format; + + switch (format) { + case V4L2_PIX_FMT_NV21: + gralloc_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + break; + case V4L2_PIX_FMT_YUV420: + gralloc_format = HAL_PIXEL_FORMAT_YV12; + break; + case V4L2_PIX_FMT_RGB565: + gralloc_format = HAL_PIXEL_FORMAT_RGB_565; + break; + case V4L2_PIX_FMT_RGB32: + gralloc_format = HAL_PIXEL_FORMAT_RGBX_8888; + break; + default: + gralloc_format = HAL_PIXEL_FORMAT_YCrCb_420_SP; + break; + } + + rc = w->set_buffers_geometry(w, width, height, gralloc_format); + if (rc) { + ALOGE("%s: Unable to set buffers geometry", __func__); + goto error; + } + + exynos_camera->preview_window = w; + + rc = 0; + goto complete; + +error: + exynos_camera->preview_window = NULL; + rc = -1; + +complete: + return rc; +} + +void exynos_camera_set_callbacks(struct camera_device *dev, + camera_notify_callback notify_cb, + camera_data_callback data_cb, + camera_data_timestamp_callback data_cb_timestamp, + camera_request_memory get_memory, + void *user) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %p)", __func__, dev, user); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callbacks.notify = notify_cb; + exynos_camera->callbacks.data = data_cb; + exynos_camera->callbacks.data_timestamp = data_cb_timestamp; + exynos_camera->callbacks.request_memory = get_memory; + exynos_camera->callbacks.user = user; +} + +void exynos_camera_enable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, msg_type); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->messages_enabled |= msg_type; +} + +void exynos_camera_disable_msg_type(struct camera_device *dev, int32_t msg_type) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, msg_type); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->messages_enabled &= ~msg_type; +} + +int exynos_camera_msg_type_enabled(struct camera_device *dev, int32_t msg_type) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, msg_type); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera->messages_enabled & msg_type; +} + +int exynos_camera_start_preview(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + rc = exynos_camera_preview_start(exynos_camera); + exynos_camera->callback_lock = 0; + + return rc; +} + +void exynos_camera_stop_preview(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + exynos_camera_preview_stop(exynos_camera); + exynos_camera->callback_lock = 0; +} + +int exynos_camera_preview_enabled(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera->preview_enabled; +} + +int exynos_camera_store_meta_data_in_buffers(struct camera_device *dev, + int enable) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p, %d)", __func__, dev, enable); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + if (!exynos_camera->recording_enabled) + exynos_camera->recording_metadata = enable; + else + ALOGE("%s: Recording is running!", __func__); + + return 0; +} + +int exynos_camera_start_recording(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + rc = exynos_camera_recording_start(exynos_camera); + exynos_camera->callback_lock = 0; + + return rc; +} + +void exynos_camera_stop_recording(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + exynos_camera_recording_stop(exynos_camera); + exynos_camera->callback_lock = 0; +} + +int exynos_camera_recording_enabled(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera->recording_enabled; +} + +void exynos_camera_release_recording_frame(struct camera_device *dev, + const void *opaque) +{ + struct exynos_camera *exynos_camera; + +// ALOGD("%s(%p, %p)", __func__, dev, opaque); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera_recording_frame_release(exynos_camera); +} + +int exynos_camera_start_auto_focus(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + return exynos_camera_auto_focus_start(exynos_camera); +} + +int exynos_camera_cancel_auto_focus(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera_auto_focus_stop(exynos_camera); + + return 0; +} + +int exynos_camera_take_picture(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + rc = exynos_camera_picture_start(exynos_camera); + exynos_camera->callback_lock = 0; + + return rc; +} + +int exynos_camera_cancel_picture(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera->callback_lock = 1; + exynos_camera_picture_stop(exynos_camera); + exynos_camera->callback_lock = 0; + + return 0; +} + +int exynos_camera_set_parameters(struct camera_device *dev, + const char *params) +{ + struct exynos_camera *exynos_camera; + int rc; + + ALOGD("%s(%p, %s)", __func__, dev, params); + + if (dev == NULL || dev->priv == NULL || params == NULL) + return -EINVAL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + if (strstr(params, "gps-timestamp=") == NULL) { + /* Make sure the GPS data is ignored, it may have + * been explicitly erased with removeGpsData() + */ + exynos_param_int_set(exynos_camera, "gps-timestamp", -1); + exynos_param_int_set(exynos_camera, "gps-latitude", -1); + exynos_param_int_set(exynos_camera, "gps-longitude", -1); + } + + rc = exynos_params_string_set(exynos_camera, (char *) params); + if (rc < 0) { + ALOGE("%s: Unable to set params string", __func__); + return -1; + } + + rc = exynos_camera_params_apply(exynos_camera, 0); + if (rc < 0) { + ALOGE("%s: Unable to apply params", __func__); + return -1; + } + + return 0; +} + +char *exynos_camera_get_parameters(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + char *params; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return NULL; + + exynos_camera = (struct exynos_camera *) dev->priv; + + params = exynos_params_string_get(exynos_camera); + if (params == NULL) { + ALOGE("%s: Couldn't find any param", __func__); + return strdup(""); + } + + return params; +} + +void exynos_camera_put_parameters(struct camera_device *dev, char *params) +{ + ALOGD("%s(%p)", __func__, dev); + + if (params != NULL) + free(params); +} + +int setFaceDetect(struct exynos_camera *exynos_camera, int face_detect) +{ + ALOGD("%s(face_detect(%d))", __func__, face_detect); + if (exynos_camera->camera_fimc_is) { + if (face_detect < IS_FD_COMMAND_STOP || IS_FD_COMMAND_MAX <= face_detect) { + ALOGE("ERR(%s):Invalid face_detect value (%d)", __func__, face_detect); + return -1; + } + } else { + if (face_detect < FACE_DETECTION_OFF || FACE_DETECTION_MAX <= face_detect) { + ALOGE("ERR(%s):Invalid face_detect value (%d)", __func__, face_detect); + return -1; + } + } + + if (exynos_camera->camera_fimc_is) { + if (exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_IS_CMD_FD, face_detect) < 0) { + ALOGE("ERR(%s):Fail on V4L2_CID_IS_CMD_FD", __func__); + return -1; + } + } else { + if (exynos_v4l2_s_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_FACE_DETECTION, face_detect) < 0) { + ALOGE("ERR(%s):Fail on V4L2_CID_CAMERA_FACE_DETECTION", __func__); + return -1; + } + } + + return 0; +} + +int exynos_camera_send_command(struct camera_device *dev, + int32_t cmd, int32_t arg1, int32_t arg2) +{ + struct exynos_camera *exynos_camera; + exynos_camera = (struct exynos_camera *) dev->priv; + + ALOGD("%s(%p, %d, %d, %d)", __func__, dev, cmd, arg1, arg2); + switch (cmd) { + case CAMERA_CMD_START_FACE_DETECTION: + if (setFaceDetect(exynos_camera, FACE_DETECTION_ON) < 0) { + ALOGE("ERR: Fail on setFaceDetect(ON)"); + return -EINVAL; + } else { + return 0; + } + break; + case CAMERA_CMD_STOP_FACE_DETECTION: + if (setFaceDetect(exynos_camera, FACE_DETECTION_OFF) < 0) { + ALOGE("ERR: Fail on setFaceDetect(OFF)"); + return -EINVAL; + } else { + return 0; + } + break; + default: + break; + } + + return 0; +} + +void exynos_camera_release(struct camera_device *dev) +{ + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, dev); + + if (dev == NULL || dev->priv == NULL) + return; + + exynos_camera = (struct exynos_camera *) dev->priv; + + exynos_camera_capture_thread_stop(exynos_camera); + + exynos_camera_stop(exynos_camera); +} + +int exynos_camera_dump(struct camera_device *dev, int fd) +{ + ALOGD("%s(%p, %d)", __func__, dev, fd); + + return 0; +} + +/* + * Interface + */ + +struct camera_device_ops exynos_camera_ops = { + .set_preview_window = exynos_camera_set_preview_window, + .set_callbacks = exynos_camera_set_callbacks, + .enable_msg_type = exynos_camera_enable_msg_type, + .disable_msg_type = exynos_camera_disable_msg_type, + .msg_type_enabled = exynos_camera_msg_type_enabled, + .start_preview = exynos_camera_start_preview, + .stop_preview = exynos_camera_stop_preview, + .preview_enabled = exynos_camera_preview_enabled, + .store_meta_data_in_buffers = exynos_camera_store_meta_data_in_buffers, + .start_recording = exynos_camera_start_recording, + .stop_recording = exynos_camera_stop_recording, + .recording_enabled = exynos_camera_recording_enabled, + .release_recording_frame = exynos_camera_release_recording_frame, + .auto_focus = exynos_camera_start_auto_focus, + .cancel_auto_focus = exynos_camera_cancel_auto_focus, + .take_picture = exynos_camera_take_picture, + .cancel_picture = exynos_camera_cancel_picture, + .set_parameters = exynos_camera_set_parameters, + .get_parameters = exynos_camera_get_parameters, + .put_parameters = exynos_camera_put_parameters, + .send_command = exynos_camera_send_command, + .release = exynos_camera_release, + .dump = exynos_camera_dump, +}; + +int exynos_camera_close(hw_device_t *device) +{ + struct camera_device *camera_device; + struct exynos_camera *exynos_camera; + + ALOGD("%s(%p)", __func__, device); + + if (device == NULL) + return -EINVAL; + + camera_device = (struct camera_device *) device; + + if (camera_device->priv != NULL) { + free(camera_device->priv); + } + + free(camera_device); + + return 0; +} + +int exynos_camera_open(const struct hw_module_t* module, const char *camera_id, + struct hw_device_t** device) +{ + struct camera_device *camera_device = NULL; + struct exynos_camera *exynos_camera = NULL; + int id; + int rc; + + ALOGD("%s(%p, %s, %p)", __func__, module, camera_id, device); + + if (module == NULL || camera_id == NULL || device == NULL) + return -EINVAL; + + id = atoi(camera_id); + if (id < 0) + return -EINVAL; + + exynos_camera = calloc(1, sizeof(struct exynos_camera)); + exynos_camera->config = exynos_camera_config; + + if (exynos_camera->config->v4l2_nodes_count > EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT) + goto error_preset; + + if (id >= exynos_camera->config->presets_count) + goto error_preset; + + rc = exynos_camera_start(exynos_camera, id); + if (rc < 0) { + ALOGE("%s: Unable to start camera", __func__); + goto error; + } + + rc = exynos_camera_capture_thread_start(exynos_camera); + if (rc < 0) { + ALOGE("%s: Unable to start capture thread", __func__); + goto error; + } + + camera_device = calloc(1, sizeof(struct camera_device)); + camera_device->common.tag = HARDWARE_DEVICE_TAG; + camera_device->common.version = 0; + camera_device->common.module = (struct hw_module_t *) module; + camera_device->common.close = exynos_camera_close; + + camera_device->ops = &exynos_camera_ops; + camera_device->priv = exynos_camera; + + *device = (struct hw_device_t *) &(camera_device->common); + + return 0; + +error: + exynos_camera_stop(exynos_camera); + +error_device: + if (camera_device != NULL) + free(camera_device); + +error_preset: + if (exynos_camera != NULL) + free(exynos_camera); + + return -1; +} + +int exynos_camera_get_number_of_cameras(void) +{ + ALOGD("%s()", __func__); + + if (exynos_camera_config == NULL || exynos_camera_config->presets == NULL) { + ALOGE("%s: Unable to find proper camera config", __func__); + return -1; + } + + return exynos_camera_config->presets_count; +} + +int exynos_camera_get_camera_info(int id, struct camera_info *info) +{ + ALOGD("%s(%d, %p)", __func__, id, info); + + if (id < 0 || info == NULL) + return -EINVAL; + + if (exynos_camera_config == NULL || exynos_camera_config->presets == NULL) { + ALOGE("%s: Unable to find proper camera config", __func__); + return -1; + } + + if (id >= exynos_camera_config->presets_count) + return -EINVAL; + + ALOGD("Selected camera: %s", exynos_camera_config->presets[id].name); + + info->facing = exynos_camera_config->presets[id].facing; + info->orientation = exynos_camera_config->presets[id].orientation; + + return 0; +} + +struct hw_module_methods_t exynos_camera_module_methods = { + .open = exynos_camera_open, +}; + +struct camera_module HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .module_api_version = CAMERA_MODULE_API_VERSION_1_0, + .id = CAMERA_HARDWARE_MODULE_ID, + .name = "Exynos Camera - Dheeraj CVR", + .author = "Paul Kocialkowski", + .methods = &exynos_camera_module_methods, + }, + .get_number_of_cameras = exynos_camera_get_number_of_cameras, + .get_camera_info = exynos_camera_get_camera_info, +}; diff --git a/camera/exynos_camera.h b/camera/exynos_camera.h new file mode 100644 index 0000000..e411b73 --- /dev/null +++ b/camera/exynos_camera.h @@ -0,0 +1,674 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * 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 3 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/>. + */ + +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <pthread.h> + +#include <linux/videodev2.h> +#include <linux/videodev2_exynos_camera.h> +#include <linux/videodev2_exynos_media.h> +#include <linux/fimc.h> + +#include <linux/s5c73m3.h> + +#ifdef EXYNOS_JPEG_HW +#include <jpeg_hal.h> +#endif +#include <Exif.h> + +#include <hardware/hardware.h> +#include <hardware/camera.h> + +#ifndef _EXYNOS_CAMERA_H_ +#define _EXYNOS_CAMERA_H_ + +#define EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT 4 + +#define EXYNOS_CAMERA_CAPTURE_BUFFERS_COUNT 6 +#define EXYNOS_CAMERA_PREVIEW_BUFFERS_COUNT 6 +#define EXYNOS_CAMERA_RECORDING_BUFFERS_COUNT 6 +#define EXYNOS_CAMERA_GRALLOC_BUFFERS_COUNT 3 + +#define EXYNOS_CAMERA_PICTURE_OUTPUT_FORMAT V4L2_PIX_FMT_YUYV + +#define EXYNOS_CAMERA_MSG_ENABLED(msg) (exynos_camera->messages_enabled & msg) +#define EXYNOS_CAMERA_CALLBACK_DEFINED(cb) (exynos_camera->callbacks.cb != NULL) + +#define EXYNOS_CAMERA_ALIGN(value) ((value + (0x10000 - 1)) & ~(0x10000 - 1)) + +/* + * Structures + */ + +struct exynos_camera; + +struct list_head { + struct list_head *next; + struct list_head *prev; +}; + +enum exynos_param_type { + EXYNOS_PARAM_INT, + EXYNOS_PARAM_FLOAT, + EXYNOS_PARAM_STRING, +}; + +union exynos_param_data { + int integer; + float floating; + char *string; +}; + +struct exynos_param { + struct list_head list; + + char *key; + union exynos_param_data data; + enum exynos_param_type type; +}; + +struct exynos_camera_buffer { + void *pointer; + int address; + int length; + + int width; + int height; + int format; +}; + +struct exynos_camera_mbus_resolution { + int width; + int height; + int mbus_width; + int mbus_height; +}; + +struct exynos_camera_videosnapshot_resolution { + int video_width; + int video_height; + int snapshot_width; + int snapshot_height; +}; + +struct exynos_camera_params { + char *preview_size_values; + char *preview_size; + char *preview_format_values; + char *preview_format; + char *preview_frame_rate_values; + int preview_frame_rate; + char *preview_fps_range_values; + char *preview_fps_range; + + char *picture_size_values; + char *picture_size; + char *picture_format_values; + char *picture_format; + char *jpeg_thumbnail_size_values; + int jpeg_thumbnail_width; + int jpeg_thumbnail_height; + int jpeg_thumbnail_quality; + int jpeg_quality; + + int video_snapshot_supported; + int full_video_snap_supported; + + char *recording_size; + char *recording_size_values; + char *recording_format; + + char *focus_mode; + char *focus_mode_values; + char *focus_distances; + char *focus_areas; + int max_num_focus_areas; + + int max_detected_faces; + + int zoom_supported; + int smooth_zoom_supported; + char *zoom_ratios; + int zoom; + int max_zoom; + + int auto_exposure_lock_supported; + int auto_exposure_lock; + + int auto_white_balance_lock_supported; + int auto_white_balance_lock; + + char *flash_mode; + char *flash_mode_values; + + int exposure_compensation; + float exposure_compensation_step; + int min_exposure_compensation; + int max_exposure_compensation; + + char *whitebalance; + char *whitebalance_values; + + char *antibanding; + char *antibanding_values; + + char *scene_mode; + char *scene_mode_values; + + char *effect; + char *effect_values; + + char *iso; + char *iso_values; + + char *image_stabilization; // Anti-shake + char *image_stabilization_values; +}; + +struct exynos_camera_preset { + char *name; + int facing; + int orientation; + + int rotation; + int hflip; + int vflip; + + int capture_format; + int picture_format; + int fimc_is; + + float focal_length; + float horizontal_view_angle; + float vertical_view_angle; + + int metering; + + struct exynos_camera_params params; + struct exynos_camera_mbus_resolution *mbus_resolutions; + int mbus_resolutions_count; + struct exynos_camera_videosnapshot_resolution *videosnapshot_resolutions; + int videosnapshot_resolutions_count; +}; + +struct exynos_v4l2_node { + int id; + char *node; +}; + +struct exynos_v4l2_output { + int enabled; + + int v4l2_id; + + int width; + int height; + int format; + + int buffer_width; + int buffer_height; + int buffer_format; + + camera_memory_t *memory; + int memory_address; +#ifdef EXYNOS_ION + int memory_ion_fd; +#endif + int memory_index; + int buffers_count; + int buffer_length; +}; + +struct exynos_exif { + int enabled; + + exif_attribute_t attributes; + void *jpeg_thumbnail_data; + int jpeg_thumbnail_size; + + camera_memory_t *memory; + int memory_size; +}; + +#ifdef EXYNOS_JPEG_HW +struct exynos_jpeg { + int enabled; + + int fd; + struct jpeg_buf buffer_in; + struct jpeg_buf buffer_out; + camera_memory_t *memory_in; + void *memory_in_pointer; +#ifdef EXYNOS_ION + int memory_in_ion_fd; +#endif + camera_memory_t *memory_out; + void *memory_out_pointer; + int memory_out_size; +#ifdef EXYNOS_ION + int memory_out_ion_fd; +#endif + + int width; + int height; + int format; + + int quality; +}; +#endif + +struct exynox_camera_config { + struct exynos_camera_preset *presets; + int presets_count; + + struct exynos_v4l2_node *v4l2_nodes; + int v4l2_nodes_count; +}; + +struct exynos_camera_callbacks { + camera_notify_callback notify; + camera_data_callback data; + camera_data_timestamp_callback data_timestamp; + camera_request_memory request_memory; + void *user; +}; + +struct exynos_camera { + int v4l2_fds[EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT]; + int ion_fd; + + struct exynox_camera_config *config; + struct exynos_param *params; + + struct exynos_camera_callbacks callbacks; + int callback_lock; + int messages_enabled; + + gralloc_module_t *gralloc; + + // Capture + + pthread_t capture_thread; + pthread_mutex_t capture_mutex; + pthread_mutex_t capture_lock_mutex; + int capture_thread_running; + int capture_thread_enabled; + + int capture_enabled; + struct exynos_exif exif; + camera_memory_t *capture_memory; + int capture_memory_address; + int capture_memory_index; + void *capture_yuv_buffer; + void *capture_jpeg_buffer; + int capture_width; + int capture_height; + int capture_format; + int capture_buffers_count; + int capture_buffer_length; + + // Preview + int preview_enabled; + int preview_stopping; + + int preview_output_enabled; + struct preview_stream_ops *preview_window; + struct exynos_camera_buffer preview_buffer; + struct exynos_v4l2_output preview_output; + + // Picture + + pthread_t picture_thread; + int picture_running; + int picture_enabled; + + int picture_completed; + camera_memory_t *picture_memory; + struct exynos_camera_buffer picture_jpeg_buffer; + struct exynos_camera_buffer picture_yuv_buffer; + + // Face Detection + camera_frame_metadata_t mFaceData; + camera_memory_t *face_data; + int max_detected_faces; + + // Recording + + int recording_running; + int recording_enabled; + + int recording_output_enabled; + camera_memory_t *recording_memory; + int recording_memory_index; + struct exynos_camera_buffer recording_buffer; + struct exynos_v4l2_output recording_output; + int recording_buffers_count; + int recording_buffer_length; + int recording_metadata; + + // Auto-focus + + int auto_focus_enabled; + int auto_focus_started; + + // Camera params + + int camera_rotation; + int camera_hflip; + int camera_vflip; + int camera_capture_format; + int camera_picture_format; + int camera_fimc_is; + int camera_focal_length; + int camera_metering; + + struct exynos_camera_mbus_resolution *camera_mbus_resolutions; + int camera_mbus_resolutions_count; + struct exynos_camera_videosnapshot_resolution *camera_videosnapshot_resolutions; + int camera_videosnapshot_resolutions_count; + + int camera_sensor_mode; + int fimc_is_mode; + + // Params + + int preview_width; + int preview_height; + int preview_format; + int preview_fps; + int picture_width; + int picture_height; + int picture_format; + int jpeg_thumbnail_width; + int jpeg_thumbnail_height; + int jpeg_thumbnail_quality; + int jpeg_quality; + int recording_width; + int recording_height; + int recording_format; + int focus_mode; + int focus_x; + int focus_y; + int zoom; + int ae_lock; + int awb_lock; + int flash_mode; + int exposure_compensation; + int whitebalance; + int antibanding; + int scene_mode; + int effect; + int iso; + int metering; + int image_stabilization; + char raw_focus_areas[PAGE_SIZE]; + char raw_focus_mode[64]; + char raw_flash_mode[64]; +}; + +struct exynos_camera_addrs { + unsigned int type; + unsigned int y; + unsigned int cbcr; + unsigned int index; + unsigned int reserved; +}; + +// This is because the linux header uses anonymous union +struct exynos_v4l2_ext_control { + __u32 id; + __u32 size; + __u32 reserved2[1]; + union { + __s32 value; + __s64 value64; + char *string; + } data; +} __attribute__ ((packed)); + +/* + * Camera + */ + +// Camera +int exynos_camera_start(struct exynos_camera *exynos_camera, int id); +void exynos_camera_stop(struct exynos_camera *exynos_camera); + +// Params +int exynos_camera_params_init(struct exynos_camera *exynos_camera, int id); +int exynos_camera_params_apply(struct exynos_camera *exynos_camera, int force); + +// Capture +int exynos_camera_capture(struct exynos_camera *exynos_camera); +int exynos_camera_capture_start(struct exynos_camera *exynos_camera); +void exynos_camera_capture_stop(struct exynos_camera *exynos_camera); +int exynos_camera_capture_setup(struct exynos_camera *exynos_camera); + +// Preview +int exynos_camera_preview_output_start(struct exynos_camera *exynos_camera); +void exynos_camera_preview_output_stop(struct exynos_camera *exynos_camera); +int exynos_camera_preview(struct exynos_camera *exynos_camera); +int exynos_camera_preview_start(struct exynos_camera *exynos_camera); +void exynos_camera_preview_stop(struct exynos_camera *exynos_camera); + +// Picture +void *exynos_camera_picture(void *data); +int exynos_camera_picture_start(struct exynos_camera *exynos_camera); +void exynos_camera_picture_thread_start(struct exynos_camera *exynos_camera); +void exynos_camera_picture_stop(struct exynos_camera *exynos_camera); + +// Recording +int exynos_camera_recording_output_start(struct exynos_camera *exynos_camera); +void exynos_camera_recording_output_stop(struct exynos_camera *exynos_camera); +void exynos_camera_recording_frame_release(struct exynos_camera *exynos_camera); +int exynos_camera_recording(struct exynos_camera *exynos_camera); +int exynos_camera_recording_start(struct exynos_camera *exynos_camera); +void exynos_camera_recording_stop(struct exynos_camera *exynos_camera); + +// Auto-focus +int exynos_camera_auto_focus(struct exynos_camera *exynos_camera, int auto_focus_status); +int exynos_camera_continuous_auto_focus(struct exynos_camera *exynos_camera, int auto_focus_status); +int exynos_camera_auto_focus_start(struct exynos_camera *exynos_camera); +void exynos_camera_auto_focus_finish(struct exynos_camera *exynos_camera); +void exynos_camera_auto_focus_stop(struct exynos_camera *exynos_camera); + +/* + * EXIF + */ + +int exynos_exif_start(struct exynos_camera *exynos_camera, struct exynos_exif *exif); +int exynos_exif_create(struct exynos_camera *exynos_camera, struct exynos_exif *exif); +void exynos_exif_stop(struct exynos_camera *exynos_camera, + struct exynos_exif *exif); +int exynos_exif(struct exynos_camera *exynos_camera, struct exynos_exif *exif); + +/* + * ION + */ + +#ifdef EXYNOS_ION +int exynos_ion_init(struct exynos_camera *exynos_camera); +int exynos_ion_open(struct exynos_camera *exynos_camera); +void exynos_ion_close(struct exynos_camera *exynos_camera); +int exynos_ion_alloc(struct exynos_camera *exynos_camera, int size); +int exynos_ion_free(struct exynos_camera *exynos_camera, int fd); +int exynos_ion_phys(struct exynos_camera *exynos_camera, int fd); +int exynos_ion_msync(struct exynos_camera *exynos_camera, int fd, + int offset, int size); +#endif + +/* + * Jpeg + */ + +int exynos_jpeg_start(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg); +void exynos_jpeg_stop(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg); +int exynos_jpeg(struct exynos_camera *exynos_camera, struct exynos_jpeg *jpeg); + +/* + * Param + */ + +int exynos_param_int_get(struct exynos_camera *exynos_camera, + char *key); +float exynos_param_float_get(struct exynos_camera *exynos_camera, + char *key); +char *exynos_param_string_get(struct exynos_camera *exynos_camera, + char *key); +int exynos_param_int_set(struct exynos_camera *exynos_camera, + char *key, int integer); +int exynos_param_float_set(struct exynos_camera *exynos_camera, + char *key, float floating); +int exynos_param_string_set(struct exynos_camera *exynos_camera, + char *key, char *string); +char *exynos_params_string_get(struct exynos_camera *exynos_camera); +int exynos_params_string_set(struct exynos_camera *exynos_camera, char *string); + +/* + * Utils + */ + +int list_head_insert(struct list_head *list, struct list_head *prev, + struct list_head *next); +void list_head_remove(struct list_head *list); + +int exynos_camera_buffer_length(int width, int height, int format); +void exynos_camera_yuv_planes(int width, int height, int format, int address, int *address_y, int *address_cb, int *address_cr); + +/* + * V4L2 + */ + +int exynos_v4l2_init(struct exynos_camera *exynos_camera); +int exynos_v4l2_index(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +int exynos_v4l2_fd(struct exynos_camera *exynos_camera, int exynos_v4l2_id); + +int exynos_v4l2_open(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +void exynos_v4l2_close(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +int exynos_v4l2_ioctl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int request, void *data); +int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id); +int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory, int index, unsigned long userptr); +int exynos_v4l2_s_ext_ctrl_face_detection(struct exynos_camera *exynos_camera, + int id, void *value); +int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index); +int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index, unsigned long userptr); +int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory); +int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int count); +int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count); +int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count); +int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int index); +int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index); +int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index); +int exynos_v4l2_querycap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int flags); +int exynos_v4l2_querycap_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_querycap_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamon(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type); +int exynos_v4l2_streamon_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamon_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamoff(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type); +int exynos_v4l2_streamoff_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_streamoff_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id); +int exynos_v4l2_g_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int *width, int *height, int *fmt); +int exynos_v4l2_g_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt); +int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt); +int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int width, int height, int fmt, int field, + int priv); +int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv); +int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv); +int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height); +int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int fmt); +int exynos_v4l2_enum_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt); +int exynos_v4l2_enum_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt); +int exynos_v4l2_enum_input(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int id); +int exynos_v4l2_s_input(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id); +int exynos_v4l2_g_ext_ctrls(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_ext_control *control, int count); +int exynos_v4l2_g_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int *value); +int exynos_v4l2_s_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int value); +int exynos_v4l2_s_parm(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, struct v4l2_streamparm *streamparm); +int exynos_v4l2_s_parm_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm); +int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm); +int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int left, int top, int width, int height); +int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height); +int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height); +int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void **base, int *width, int *height, int *fmt); +int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void *base, int width, int height, int fmt); + +/* + * V4L2 Output + */ + +int exynos_v4l2_output_start(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output); +void exynos_v4l2_output_stop(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output); +int exynos_v4l2_output(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output, int buffer_address); +int exynos_v4l2_output_release(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output); + +#endif diff --git a/camera/smdk4x12_exif.c b/camera/exynos_exif.c index f2024fd..486b256 100644 --- a/camera/smdk4x12_exif.c +++ b/camera/exynos_exif.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2013 Paul Kocialkowski * * Based on crespo libcamera and exynos4 hal libcamera: * Copyright 2008, The Android Open Source Project @@ -33,21 +33,21 @@ #include <Exif.h> -#define LOG_TAG "smdk4x12_camera" +#define LOG_TAG "exynos_camera" #include <utils/Log.h> #include <cutils/properties.h> -#include "smdk4x12_camera.h" +#include "exynos_camera.h" -int smdk4x12_exif_attributes_create_static(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_exif *exif) +int exynos_exif_attributes_create_static(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) { exif_attribute_t *attributes; unsigned char gps_version[] = { 0x02, 0x02, 0x00, 0x00 }; char property[PROPERTY_VALUE_MAX]; uint32_t av; - if (smdk4x12_camera == NULL || exif == NULL) + if (exynos_camera == NULL || exif == NULL) return -EINVAL; attributes = &exif->attributes; @@ -104,8 +104,8 @@ int smdk4x12_exif_attributes_create_static(struct smdk4x12_camera *smdk4x12_came return 0; } -int smdk4x12_exif_attributes_create_gps(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_exif *exif) +int exynos_exif_attributes_create_gps(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) { exif_attribute_t *attributes; float gps_latitude_float, gps_longitude_float, gps_altitude_float; @@ -117,18 +117,18 @@ int smdk4x12_exif_attributes_create_gps(struct smdk4x12_camera *smdk4x12_camera, struct tm time_info; - if (smdk4x12_camera == NULL || exif == NULL) + if (exynos_camera == NULL || exif == NULL) return -EINVAL; attributes = &exif->attributes; - gps_latitude_float = smdk4x12_param_float_get(smdk4x12_camera, "gps-latitude"); - gps_longitude_float = smdk4x12_param_float_get(smdk4x12_camera, "gps-longitude"); - gps_altitude_float = smdk4x12_param_float_get(smdk4x12_camera, "gps-altitude"); + gps_latitude_float = exynos_param_float_get(exynos_camera, "gps-latitude"); + gps_longitude_float = exynos_param_float_get(exynos_camera, "gps-longitude"); + gps_altitude_float = exynos_param_float_get(exynos_camera, "gps-altitude"); if (gps_altitude_float == -1) - gps_altitude_float = (float) smdk4x12_param_int_get(smdk4x12_camera, "gps-altitude"); - gps_timestamp_int = smdk4x12_param_int_get(smdk4x12_camera, "gps-timestamp"); - gps_processing_method_string = smdk4x12_param_string_get(smdk4x12_camera, "gps-processing-method"); + gps_altitude_float = (float) exynos_param_int_get(exynos_camera, "gps-altitude"); + gps_timestamp_int = exynos_param_int_get(exynos_camera, "gps-timestamp"); + gps_processing_method_string = exynos_param_string_get(exynos_camera, "gps-processing-method"); if (gps_latitude_float == -1 || gps_longitude_float == -1 || gps_altitude_float == -1 || gps_timestamp_int <= 0 || @@ -195,13 +195,14 @@ int smdk4x12_exif_attributes_create_gps(struct smdk4x12_camera *smdk4x12_camera, snprintf((char *) attributes->gps_datestamp, sizeof(attributes->gps_datestamp), "%04d:%02d:%02d", time_info.tm_year + 1900, time_info.tm_mon + 1, time_info.tm_mday); + strcpy((char *) attributes->gps_processing_method, gps_processing_method_string); attributes->enableGps = true; return 0; } -int smdk4x12_exif_attributes_create_params(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_exif *exif) +int exynos_exif_attributes_create_params(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) { exif_attribute_t *attributes; uint32_t av, tv, bv, sv, ev; @@ -216,25 +217,25 @@ int smdk4x12_exif_attributes_create_params(struct smdk4x12_camera *smdk4x12_came int rc; - if (smdk4x12_camera == NULL || exif == NULL) + if (exynos_camera == NULL || exif == NULL) return -EINVAL; attributes = &exif->attributes; // Picture size - attributes->width = smdk4x12_camera->picture_width; - attributes->height = smdk4x12_camera->picture_height; + attributes->width = exynos_camera->picture_width; + attributes->height = exynos_camera->picture_height; // Thumbnail - attributes->widthThumb = smdk4x12_camera->jpeg_thumbnail_width; - attributes->heightThumb = smdk4x12_camera->jpeg_thumbnail_height; + attributes->widthThumb = exynos_camera->jpeg_thumbnail_width; + attributes->heightThumb = exynos_camera->jpeg_thumbnail_height; attributes->enableThumb = true; // Orientation - rotation = smdk4x12_param_int_get(smdk4x12_camera, "rotation"); + rotation = exynos_param_int_get(exynos_camera, "rotation"); switch (rotation) { case 90: attributes->orientation = EXIF_ORIENTATION_90; @@ -258,84 +259,74 @@ int smdk4x12_exif_attributes_create_params(struct smdk4x12_camera *smdk4x12_came strftime((char *) attributes->date_time, sizeof(attributes->date_time), "%Y:%m:%d %H:%M:%S", time_info); - attributes->focal_length.num = smdk4x12_camera->camera_focal_length; + attributes->focal_length.num = exynos_camera->camera_focal_length; attributes->focal_length.den = EXIF_DEF_FOCAL_LEN_DEN; - if (smdk4x12_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED) { - attributes->shutter_speed.num = APEX_EXPOSURE_TO_SHUTTER(smdk4x12_camera->capture_exif_exposure_time); - attributes->shutter_speed.den = 100; - - attributes->exposure_time.num = 1; - attributes->exposure_time.den = smdk4x12_camera->capture_exif_exposure_time; - - attributes->iso_speed_rating = smdk4x12_camera->capture_exif_iso; - - attributes->flash = smdk4x12_camera->capture_exif_flash; - - bv = smdk4x12_camera->capture_exif_exposure; - ev = smdk4x12_camera->capture_exif_exposure_bias; - } else { - shutter_speed = 100; - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_EXIF_TV, - &shutter_speed); + // Only Query the Front Camera Sensor for EXIF Attributes. + if (exynos_camera->camera_fimc_is) { + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_EXPTIME, + &exposure_time); if (rc < 0) - ALOGE("%s: Unable to get shutter speed", __func__); - - attributes->shutter_speed.num = shutter_speed; - attributes->shutter_speed.den = 100; + ALOGE("%s: Unable to get exposure time", __func__); - attributes->exposure_time.num = 1; - attributes->exposure_time.den = APEX_SHUTTER_TO_EXPOSURE(shutter_speed); + attributes->exposure_time.den = exposure_time; - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_EXIF_ISO, + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_ISO, &iso_speed); if (rc < 0) ALOGE("%s: Unable to get iso", __func__); attributes->iso_speed_rating = iso_speed; - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_EXIF_FLASH, + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_FLASH, &flash_results); if (rc < 0) ALOGE("%s: Unable to get flash", __func__); attributes->flash = flash_results; - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_EXIF_BV, - (int *) &bv); + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_BV, + (int *) &bv); if (rc < 0) { ALOGE("%s: Unable to get bv", __func__); goto bv_static; } - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_EXIF_EBV, + rc = exynos_v4l2_g_ctrl(exynos_camera, 0, V4L2_CID_CAMERA_EXIF_EBV, (int *) &ev); if (rc < 0) { ALOGE("%s: Unable to get ebv", __func__); goto bv_static; } - } - goto bv_camera; + goto bv_ioctl; bv_static: - exposure = smdk4x12_param_int_get(smdk4x12_camera, "exposure-compensation"); - if (exposure < 0) - exposure = EV_DEFAULT; + exposure = exynos_param_int_get(exynos_camera, "exposure-compensation"); + if (exposure < 0) + exposure = EV_DEFAULT; + + av = APEX_FNUM_TO_APERTURE((double) attributes->fnumber.num / + attributes->fnumber.den); + tv = APEX_EXPOSURE_TO_SHUTTER((double) attributes->exposure_time.num / + attributes->exposure_time.den); + sv = APEX_ISO_TO_FILMSENSITIVITY(iso_speed); + bv = av + tv - sv; + ev = exposure - EV_DEFAULT; + + +bv_ioctl: + attributes->brightness.num = bv; + } + + attributes->shutter_speed.num = APEX_EXPOSURE_TO_SHUTTER(attributes->exposure_time.den); + attributes->shutter_speed.den = 100; + + attributes->exposure_time.num = 1; - av = APEX_FNUM_TO_APERTURE((double) attributes->fnumber.num / - attributes->fnumber.den); - tv = APEX_EXPOSURE_TO_SHUTTER((double) attributes->exposure_time.num / - attributes->exposure_time.den); - sv = APEX_ISO_TO_FILMSENSITIVITY(iso_speed); - bv = av + tv - sv; - ev = exposure - EV_DEFAULT; - -bv_camera: - attributes->brightness.num = bv; attributes->brightness.den = EXIF_DEF_APEX_DEN; - if (smdk4x12_camera->scene_mode == SCENE_MODE_BEACH_SNOW) { + if (exynos_camera->scene_mode == SCENE_MODE_BEACH_SNOW) { attributes->exposure_bias.num = EXIF_DEF_APEX_DEN; attributes->exposure_bias.den = EXIF_DEF_APEX_DEN; } else { @@ -343,7 +334,7 @@ bv_camera: attributes->exposure_bias.den = EXIF_DEF_APEX_DEN; } - switch (smdk4x12_camera->camera_metering) { + switch (exynos_camera->camera_metering) { case METERING_CENTER: attributes->metering_mode = EXIF_METERING_CENTER; break; @@ -358,13 +349,13 @@ bv_camera: break; } - if (smdk4x12_camera->whitebalance == WHITE_BALANCE_AUTO || - smdk4x12_camera->whitebalance == WHITE_BALANCE_BASE) + if (exynos_camera->whitebalance == WHITE_BALANCE_AUTO || + exynos_camera->whitebalance == WHITE_BALANCE_BASE) attributes->white_balance = EXIF_WB_AUTO; else attributes->white_balance = EXIF_WB_MANUAL; - switch (smdk4x12_camera->scene_mode) { + switch (exynos_camera->scene_mode) { case SCENE_MODE_PORTRAIT: attributes->scene_capture_type = EXIF_SCENE_PORTRAIT; break; @@ -379,7 +370,7 @@ bv_camera: break; } - rc = smdk4x12_exif_attributes_create_gps(smdk4x12_camera, exif); + rc = exynos_exif_attributes_create_gps(exynos_camera, exif); if (rc < 0) { ALOGE("%s: Unable to create GPS attributes", __func__); return -1; @@ -388,7 +379,7 @@ bv_camera: return 0; } -int smdk4x12_exif_write_data(void *exif_data, unsigned short tag, +int exynos_exif_write_data(void *exif_data, unsigned short tag, unsigned short type, unsigned int count, unsigned int *offset, void *start, void *data, int length) { @@ -424,11 +415,11 @@ int smdk4x12_exif_write_data(void *exif_data, unsigned short tag, return size; } -int smdk4x12_exif_start(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif *exif) +int exynos_exif_start(struct exynos_camera *exynos_camera, struct exynos_exif *exif) { int rc; - if (smdk4x12_camera == NULL || exif == NULL) + if (exynos_camera == NULL || exif == NULL) return -EINVAL; ALOGD("%s()", __func__); @@ -438,13 +429,15 @@ int smdk4x12_exif_start(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12 return -1; } - rc = smdk4x12_exif_attributes_create_static(smdk4x12_camera, exif); + memset(&exif->attributes, 0, sizeof(exif_attribute_t)); + + rc = exynos_exif_attributes_create_static(exynos_camera, exif); if (rc < 0) { ALOGE("%s: Unable to create exif attributes", __func__); goto error; } - rc = smdk4x12_exif_attributes_create_params(smdk4x12_camera, exif); + rc = exynos_exif_attributes_create_params(exynos_camera, exif); if (rc < 0) { ALOGE("%s: Unable to create exif parameters", __func__); goto error; @@ -462,10 +455,28 @@ complete: return rc; } -void smdk4x12_exif_stop(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_exif *exif) +int exynos_exif_create(struct exynos_camera *exynos_camera, struct exynos_exif *exif) +{ + int rc; + + rc = exynos_exif_attributes_create_params(exynos_camera, exif); + if (rc < 0) { + ALOGE("%s: Unable to create exif parameters", __func__); + goto error; + } + + goto complete; +error: + rc = -1; + +complete: + return rc; +} + +void exynos_exif_stop(struct exynos_camera *exynos_camera, + struct exynos_exif *exif) { - if (smdk4x12_camera == NULL || exif == NULL) + if (exynos_camera == NULL || exif == NULL) return; ALOGD("%s()", __func__); @@ -483,7 +494,7 @@ void smdk4x12_exif_stop(struct smdk4x12_camera *smdk4x12_camera, exif->enabled = 0; } -int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif *exif) +int exynos_exif(struct exynos_camera *exynos_camera, struct exynos_exif *exif) { // Markers unsigned char exif_app1_marker[] = { 0xff, 0xe1 }; @@ -510,7 +521,7 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif int count; int rc; - if (smdk4x12_camera == NULL || exif == NULL) + if (exynos_camera == NULL || exif == NULL) return -EINVAL; ALOGD("%s()", __func__); @@ -532,8 +543,8 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif memory_size = EXIF_FILE_SIZE + jpeg_thumbnail_size; - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - memory = smdk4x12_camera->callbacks.request_memory(-1, memory_size, 1, smdk4x12_camera->callbacks.user); + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(-1, memory_size, 1, exynos_camera->callbacks.user); if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { ALOGE("%s: Unable to request memory", __func__); goto error; @@ -571,39 +582,39 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif offset = 8 + NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE; // Write EXIF data - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH, + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->width, sizeof(attributes->width)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT, + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->height, sizeof(attributes->height)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_MAKE, + count = exynos_exif_write_data(pointer, EXIF_TAG_MAKE, EXIF_TYPE_ASCII, strlen((char *) attributes->maker) + 1, &offset, exif_ifd_start, &attributes->maker, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_MODEL, + count = exynos_exif_write_data(pointer, EXIF_TAG_MODEL, EXIF_TYPE_ASCII, strlen((char *) attributes->model) + 1, &offset, exif_ifd_start, &attributes->model, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_ORIENTATION, + count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->orientation, sizeof(attributes->orientation)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_SOFTWARE, + count = exynos_exif_write_data(pointer, EXIF_TAG_SOFTWARE, EXIF_TYPE_ASCII, strlen((char *) attributes->software) + 1, &offset, exif_ifd_start, &attributes->software, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_DATE_TIME, + count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME, EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &attributes->date_time, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_YCBCR_POSITIONING, + count = exynos_exif_write_data(pointer, EXIF_TAG_YCBCR_POSITIONING, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->ycbcr_positioning, sizeof(attributes->ycbcr_positioning)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_EXIF_IFD_POINTER, + count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_IFD_POINTER, EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset)); pointer += count; @@ -624,63 +635,63 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif offset += NUM_SIZE + NUM_0TH_IFD_EXIF * IFD_SIZE + OFFSET_SIZE; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_EXPOSURE_TIME, + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_TIME, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->exposure_time, sizeof(attributes->exposure_time)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_FNUMBER, + count = exynos_exif_write_data(pointer, EXIF_TAG_FNUMBER, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->fnumber, sizeof(attributes->fnumber)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_EXPOSURE_PROGRAM, + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_PROGRAM, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->exposure_program, sizeof(attributes->exposure_program)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_ISO_SPEED_RATING, + count = exynos_exif_write_data(pointer, EXIF_TAG_ISO_SPEED_RATING, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->iso_speed_rating, sizeof(attributes->iso_speed_rating)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_EXIF_VERSION, + count = exynos_exif_write_data(pointer, EXIF_TAG_EXIF_VERSION, EXIF_TYPE_UNDEFINED, 4, NULL, NULL, &attributes->exif_version, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_DATE_TIME_ORG, + count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_ORG, EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &attributes->date_time, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_DATE_TIME_DIGITIZE, + count = exynos_exif_write_data(pointer, EXIF_TAG_DATE_TIME_DIGITIZE, EXIF_TYPE_ASCII, 20, &offset, exif_ifd_start, &attributes->date_time, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_SHUTTER_SPEED, + count = exynos_exif_write_data(pointer, EXIF_TAG_SHUTTER_SPEED, EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &attributes->shutter_speed, sizeof(attributes->shutter_speed)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_APERTURE, + count = exynos_exif_write_data(pointer, EXIF_TAG_APERTURE, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->aperture, sizeof(attributes->aperture)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_BRIGHTNESS, + count = exynos_exif_write_data(pointer, EXIF_TAG_BRIGHTNESS, EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &attributes->brightness, sizeof(attributes->brightness)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_EXPOSURE_BIAS, + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_BIAS, EXIF_TYPE_SRATIONAL, 1, &offset, exif_ifd_start, &attributes->exposure_bias, sizeof(attributes->exposure_bias)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_MAX_APERTURE, + count = exynos_exif_write_data(pointer, EXIF_TAG_MAX_APERTURE, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->max_aperture, sizeof(attributes->max_aperture)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_METERING_MODE, + count = exynos_exif_write_data(pointer, EXIF_TAG_METERING_MODE, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->metering_mode, sizeof(attributes->metering_mode)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_FLASH, + count = exynos_exif_write_data(pointer, EXIF_TAG_FLASH, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->flash, sizeof(attributes->flash)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_FOCAL_LENGTH, + count = exynos_exif_write_data(pointer, EXIF_TAG_FOCAL_LENGTH, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->focal_length, sizeof(attributes->focal_length)); pointer += count; @@ -688,31 +699,31 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif memmove(attributes->user_comment + sizeof(user_comment_code), attributes->user_comment, value); memcpy(attributes->user_comment, user_comment_code, sizeof(user_comment_code)); - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_USER_COMMENT, + count = exynos_exif_write_data(pointer, EXIF_TAG_USER_COMMENT, EXIF_TYPE_UNDEFINED, value + sizeof(user_comment_code), &offset, exif_ifd_start, &attributes->user_comment, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_COLOR_SPACE, + count = exynos_exif_write_data(pointer, EXIF_TAG_COLOR_SPACE, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->color_space, sizeof(attributes->color_space)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_PIXEL_X_DIMENSION, + count = exynos_exif_write_data(pointer, EXIF_TAG_PIXEL_X_DIMENSION, EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->width, sizeof(attributes->width)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_PIXEL_Y_DIMENSION, + count = exynos_exif_write_data(pointer, EXIF_TAG_PIXEL_Y_DIMENSION, EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->height, sizeof(attributes->height)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_EXPOSURE_MODE, + count = exynos_exif_write_data(pointer, EXIF_TAG_EXPOSURE_MODE, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->exposure_mode, sizeof(attributes->exposure_mode)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_WHITE_BALANCE, + count = exynos_exif_write_data(pointer, EXIF_TAG_WHITE_BALANCE, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->white_balance, sizeof(attributes->white_balance)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_SCENCE_CAPTURE_TYPE, + count = exynos_exif_write_data(pointer, EXIF_TAG_SCENCE_CAPTURE_TYPE, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->scene_capture_type, sizeof(attributes->scene_capture_type)); pointer += count; @@ -723,7 +734,7 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif // GPS if (attributes->enableGps) { pointer = (unsigned char *) exif_ifd_gps; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_IFD_POINTER, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_IFD_POINTER, EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset)); pointer = (unsigned char *) exif_ifd_start + offset; @@ -738,35 +749,35 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif offset += NUM_SIZE + value * IFD_SIZE + OFFSET_SIZE; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_VERSION_ID, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_VERSION_ID, EXIF_TYPE_BYTE, 4, NULL, NULL, &attributes->gps_version_id, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE_REF, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE_REF, EXIF_TYPE_ASCII, 2, NULL, NULL, &attributes->gps_latitude_ref, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LATITUDE, EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &attributes->gps_latitude, sizeof(attributes->gps_latitude[0])); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE_REF, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE_REF, EXIF_TYPE_ASCII, 2, NULL, NULL, &attributes->gps_longitude_ref, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_LONGITUDE, EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &attributes->gps_longitude, sizeof(attributes->gps_longitude[0])); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE_REF, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE_REF, EXIF_TYPE_BYTE, 1, NULL, NULL, &attributes->gps_altitude_ref, sizeof(char)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_ALTITUDE, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->gps_altitude, sizeof(attributes->gps_altitude)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_TIMESTAMP, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_TIMESTAMP, EXIF_TYPE_RATIONAL, 3, &offset, exif_ifd_start, &attributes->gps_timestamp, sizeof(attributes->gps_timestamp[0])); pointer += count; @@ -778,14 +789,14 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif memcpy(data, &exif_ascii_prefix, sizeof(exif_ascii_prefix)); memcpy((void *) ((int) data + (int) sizeof(exif_ascii_prefix)), attributes->gps_processing_method, value); - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_PROCESSING_METHOD, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_PROCESSING_METHOD, EXIF_TYPE_UNDEFINED, value + sizeof(exif_ascii_prefix), &offset, exif_ifd_start, data, sizeof(char)); pointer += count; free(data); } - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_GPS_DATESTAMP, + count = exynos_exif_write_data(pointer, EXIF_TAG_GPS_DATESTAMP, EXIF_TYPE_ASCII, 11, &offset, exif_ifd_start, &attributes->gps_datestamp, 1); pointer += count; @@ -806,41 +817,41 @@ int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif offset += NUM_SIZE + NUM_1TH_IFD_TIFF * IFD_SIZE + OFFSET_SIZE; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH, + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_WIDTH, EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->widthThumb, sizeof(attributes->widthThumb)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT, + count = exynos_exif_write_data(pointer, EXIF_TAG_IMAGE_HEIGHT, EXIF_TYPE_LONG, 1, NULL, NULL, &attributes->heightThumb, sizeof(attributes->heightThumb)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_COMPRESSION_SCHEME, + count = exynos_exif_write_data(pointer, EXIF_TAG_COMPRESSION_SCHEME, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->compression_scheme, sizeof(attributes->compression_scheme)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_ORIENTATION, + count = exynos_exif_write_data(pointer, EXIF_TAG_ORIENTATION, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->orientation, sizeof(attributes->orientation)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_X_RESOLUTION, + count = exynos_exif_write_data(pointer, EXIF_TAG_X_RESOLUTION, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->x_resolution, sizeof(attributes->x_resolution)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_Y_RESOLUTION, + count = exynos_exif_write_data(pointer, EXIF_TAG_Y_RESOLUTION, EXIF_TYPE_RATIONAL, 1, &offset, exif_ifd_start, &attributes->y_resolution, sizeof(attributes->y_resolution)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_RESOLUTION_UNIT, + count = exynos_exif_write_data(pointer, EXIF_TAG_RESOLUTION_UNIT, EXIF_TYPE_SHORT, 1, NULL, NULL, &attributes->resolution_unit, sizeof(attributes->resolution_unit)); pointer += count; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, + count = exynos_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT, EXIF_TYPE_LONG, 1, NULL, NULL, &offset, sizeof(offset)); pointer += count; value = (unsigned int) jpeg_thumbnail_size; - count = smdk4x12_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, + count = exynos_exif_write_data(pointer, EXIF_TAG_JPEG_INTERCHANGE_FORMAT_LEN, EXIF_TYPE_LONG, 1, NULL, NULL, &value, sizeof(value)); pointer += count; diff --git a/camera/smdk4x12_ion.c b/camera/exynos_ion.c index 39b2b06..6adf7cc 100644 --- a/camera/smdk4x12_ion.c +++ b/camera/exynos_ion.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2013 Paul Kocialkowski * * 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 @@ -22,21 +22,21 @@ #include <malloc.h> #include <ctype.h> -#include <ion.h> +#include <linux/ion.h> -#define LOG_TAG "smdk4x12_ion" +#define LOG_TAG "exynos_ion" #include <utils/Log.h> -#include "smdk4x12_camera.h" +#include "exynos_camera.h" -int smdk4x12_ion_init(struct smdk4x12_camera *smdk4x12_camera) +int exynos_ion_init(struct exynos_camera *exynos_camera) { - smdk4x12_camera->ion_fd = -1; + exynos_camera->ion_fd = -1; return 0; } -int smdk4x12_ion_open(struct smdk4x12_camera *smdk4x12_camera) +int exynos_ion_open(struct exynos_camera *exynos_camera) { int fd; @@ -46,20 +46,20 @@ int smdk4x12_ion_open(struct smdk4x12_camera *smdk4x12_camera) return -1; } - smdk4x12_camera->ion_fd = fd; + exynos_camera->ion_fd = fd; return 0; } -void smdk4x12_ion_close(struct smdk4x12_camera *smdk4x12_camera) +void exynos_ion_close(struct exynos_camera *exynos_camera) { - if (smdk4x12_camera->ion_fd >= 0) - close(smdk4x12_camera->ion_fd); + if (exynos_camera->ion_fd >= 0) + close(exynos_camera->ion_fd); - smdk4x12_camera->ion_fd = -1; + exynos_camera->ion_fd = -1; } -int smdk4x12_ion_alloc(struct smdk4x12_camera *smdk4x12_camera, int size) +int exynos_ion_alloc(struct exynos_camera *exynos_camera, int size) { struct ion_allocation_data alloc_data; struct ion_fd_data share_data; @@ -70,7 +70,7 @@ int smdk4x12_ion_alloc(struct smdk4x12_camera *smdk4x12_camera, int size) page_size = getpagesize(); - fd = smdk4x12_camera->ion_fd; + fd = exynos_camera->ion_fd; if (fd < 0) return -1; @@ -100,13 +100,13 @@ int smdk4x12_ion_alloc(struct smdk4x12_camera *smdk4x12_camera, int size) return share_data.fd; } -int smdk4x12_ion_free(struct smdk4x12_camera *smdk4x12_camera, int fd) +int exynos_ion_free(struct exynos_camera *exynos_camera, int fd) { close(fd); return 0; } -int smdk4x12_ion_phys(struct smdk4x12_camera *smdk4x12_camera, int fd) +int exynos_ion_phys(struct exynos_camera *exynos_camera, int fd) { struct ion_custom_data custom_data; struct ion_phys_data phys_data; @@ -119,7 +119,7 @@ int smdk4x12_ion_phys(struct smdk4x12_camera *smdk4x12_camera, int fd) custom_data.cmd = ION_EXYNOS_CUSTOM_PHYS; custom_data.arg = (unsigned long) &phys_data; - fd = smdk4x12_camera->ion_fd; + fd = exynos_camera->ion_fd; if (fd < 0) return -1; @@ -130,7 +130,7 @@ int smdk4x12_ion_phys(struct smdk4x12_camera *smdk4x12_camera, int fd) return (int) phys_data.phys; } -int smdk4x12_ion_msync(struct smdk4x12_camera *smdk4x12_camera, int fd, +int exynos_ion_msync(struct exynos_camera *exynos_camera, int fd, int offset, int size) { struct ion_custom_data custom_data; @@ -147,7 +147,7 @@ int smdk4x12_ion_msync(struct smdk4x12_camera *smdk4x12_camera, int fd, custom_data.cmd = ION_EXYNOS_CUSTOM_MSYNC; custom_data.arg = (unsigned long) &msync_data; - fd = smdk4x12_camera->ion_fd; + fd = exynos_camera->ion_fd; if (fd < 0) return -1; diff --git a/camera/smdk4x12_jpeg.c b/camera/exynos_jpeg.c index 88cdd71..24e74fc 100644 --- a/camera/smdk4x12_jpeg.c +++ b/camera/exynos_jpeg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2013 Paul Kocialkowski * * 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 @@ -28,13 +28,14 @@ #include <asm/types.h> -#define LOG_TAG "smdk4x12_jpeg" +#define LOG_TAG "exynos_jpeg" #include <utils/Log.h> -#include "smdk4x12_camera.h" +#include "exynos_camera.h" -int smdk4x12_jpeg_start(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_jpeg *jpeg) +#ifdef EXYNOS_JPEG_HW +int exynos_jpeg_start(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg) { struct jpeg_config config; struct jpeg_buf *buffer_in; @@ -47,7 +48,7 @@ int smdk4x12_jpeg_start(struct smdk4x12_camera *smdk4x12_camera, int fd = -1; int rc; - if (smdk4x12_camera == NULL || jpeg == NULL) + if (exynos_camera == NULL || jpeg == NULL) return -EINVAL; ALOGD("%s()", __func__); @@ -116,18 +117,18 @@ int smdk4x12_jpeg_start(struct smdk4x12_camera *smdk4x12_camera, // Input buffer_in->memory = V4L2_MEMORY_USERPTR; - buffer_in->length[0] = smdk4x12_camera_buffer_length(jpeg->width, jpeg->height, jpeg->format); + buffer_in->length[0] = exynos_camera_buffer_length(jpeg->width, jpeg->height, jpeg->format); - memory_ion_fd = smdk4x12_ion_alloc(smdk4x12_camera, buffer_in->length[0]); + memory_ion_fd = exynos_ion_alloc(exynos_camera, buffer_in->length[0]); if (memory_ion_fd < 0) { ALOGE("%s: Unable to alloc input ION memory", __func__); goto error; } - address = smdk4x12_ion_phys(smdk4x12_camera, memory_ion_fd); + address = exynos_ion_phys(exynos_camera, memory_ion_fd); - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - memory = smdk4x12_camera->callbacks.request_memory(memory_ion_fd, buffer_in->length[0], 1, smdk4x12_camera->callbacks.user); + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(memory_ion_fd, buffer_in->length[0], 1, exynos_camera->callbacks.user); if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { ALOGE("%s: Unable to request memory", __func__); goto error; @@ -153,16 +154,16 @@ int smdk4x12_jpeg_start(struct smdk4x12_camera *smdk4x12_camera, buffer_out->memory = V4L2_MEMORY_USERPTR; buffer_out->length[0] = jpeg->width * jpeg->height * 4; - memory_ion_fd = smdk4x12_ion_alloc(smdk4x12_camera, buffer_out->length[0]); + memory_ion_fd = exynos_ion_alloc(exynos_camera, buffer_out->length[0]); if (memory_ion_fd < 0) { ALOGE("%s: Unable to alloc output ION memory", __func__); goto error; } - address = smdk4x12_ion_phys(smdk4x12_camera, memory_ion_fd); + address = exynos_ion_phys(exynos_camera, memory_ion_fd); - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - memory = smdk4x12_camera->callbacks.request_memory(memory_ion_fd, buffer_out->length[0], 1, smdk4x12_camera->callbacks.user); + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(memory_ion_fd, buffer_out->length[0], 1, exynos_camera->callbacks.user); if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { ALOGE("%s: Unable to request memory", __func__); goto error; @@ -215,7 +216,7 @@ error: jpeg->memory_in = NULL; #ifdef EXYNOS_ION if (jpeg->memory_in_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, jpeg->memory_in_ion_fd); + exynos_ion_free(exynos_camera, jpeg->memory_in_ion_fd); jpeg->memory_in_ion_fd = -1; } #endif @@ -227,7 +228,7 @@ error: #ifdef EXYNOS_ION if (jpeg->memory_out_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, jpeg->memory_out_ion_fd); + exynos_ion_free(exynos_camera, jpeg->memory_out_ion_fd); jpeg->memory_out_ion_fd = -1; } #endif @@ -239,15 +240,15 @@ complete: return rc; } -void smdk4x12_jpeg_stop(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_jpeg *jpeg) +void exynos_jpeg_stop(struct exynos_camera *exynos_camera, + struct exynos_jpeg *jpeg) { struct jpeg_buf *buffer_in; struct jpeg_buf *buffer_out; int fd = -1; int rc; - if (smdk4x12_camera == NULL || jpeg == NULL) + if (exynos_camera == NULL || jpeg == NULL) return; ALOGD("%s()", __func__); @@ -272,7 +273,7 @@ void smdk4x12_jpeg_stop(struct smdk4x12_camera *smdk4x12_camera, jpeg->memory_in = NULL; #ifdef EXYNOS_ION if (jpeg->memory_in_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, jpeg->memory_in_ion_fd); + exynos_ion_free(exynos_camera, jpeg->memory_in_ion_fd); jpeg->memory_in_ion_fd = -1; } #endif @@ -284,7 +285,7 @@ void smdk4x12_jpeg_stop(struct smdk4x12_camera *smdk4x12_camera, #ifdef EXYNOS_ION if (jpeg->memory_out_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, jpeg->memory_out_ion_fd); + exynos_ion_free(exynos_camera, jpeg->memory_out_ion_fd); jpeg->memory_out_ion_fd = -1; } #endif @@ -293,7 +294,7 @@ void smdk4x12_jpeg_stop(struct smdk4x12_camera *smdk4x12_camera, jpeg->enabled = 0; } -int smdk4x12_jpeg(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_jpeg *jpeg) +int exynos_jpeg(struct exynos_camera *exynos_camera, struct exynos_jpeg *jpeg) { struct jpeg_buf *buffer_in; struct jpeg_buf *buffer_out; @@ -301,7 +302,7 @@ int smdk4x12_jpeg(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_jpeg int fd = -1; int rc; - if (smdk4x12_camera == NULL || jpeg == NULL) + if (exynos_camera == NULL || jpeg == NULL) return -EINVAL; ALOGD("%s()", __func__); @@ -322,7 +323,7 @@ int smdk4x12_jpeg(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_jpeg #ifdef EXYNOS_ION if (jpeg->memory_in != NULL && jpeg->memory_in_ion_fd >= 0) { - rc = smdk4x12_ion_msync(smdk4x12_camera, jpeg->memory_in_ion_fd, 0, buffer_in->length[0]); + rc = exynos_ion_msync(exynos_camera, jpeg->memory_in_ion_fd, 0, buffer_in->length[0]); if (rc < 0) { ALOGE("%s: Unable to sync ION memory", __func__); goto error; @@ -346,7 +347,7 @@ int smdk4x12_jpeg(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_jpeg #ifdef EXYNOS_ION if (jpeg->memory_out != NULL && jpeg->memory_out_ion_fd >= 0) { - rc = smdk4x12_ion_msync(smdk4x12_camera, jpeg->memory_out_ion_fd, 0, memory_size); + rc = exynos_ion_msync(exynos_camera, jpeg->memory_out_ion_fd, 0, memory_size); if (rc < 0) { ALOGE("%s: Unable to sync ION memory", __func__); goto error; @@ -377,7 +378,7 @@ error: #ifdef EXYNOS_ION if (jpeg->memory_in_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, jpeg->memory_in_ion_fd); + exynos_ion_free(exynos_camera, jpeg->memory_in_ion_fd); jpeg->memory_in_ion_fd = -1; } #endif @@ -389,7 +390,7 @@ error: #ifdef EXYNOS_ION if (jpeg->memory_out_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, jpeg->memory_out_ion_fd); + exynos_ion_free(exynos_camera, jpeg->memory_out_ion_fd); jpeg->memory_out_ion_fd = -1; } #endif @@ -400,3 +401,4 @@ error: complete: return rc; } +#endif diff --git a/camera/smdk4x12_param.c b/camera/exynos_param.c index b39ec7e..f41f4f6 100644 --- a/camera/smdk4x12_param.c +++ b/camera/exynos_param.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2013 Paul Kocialkowski * * 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 @@ -22,22 +22,22 @@ #include <malloc.h> #include <ctype.h> -#define LOG_TAG "smdk4x12_param" +#define LOG_TAG "exynos_param" #include <utils/Log.h> -#include "smdk4x12_camera.h" +#include "exynos_camera.h" -int smdk4x12_param_register(struct smdk4x12_camera *smdk4x12_camera, char *key, - union smdk4x12_param_data data, enum smdk4x12_param_type type) +int exynos_param_register(struct exynos_camera *exynos_camera, char *key, + union exynos_param_data data, enum exynos_param_type type) { struct list_head *list_end; struct list_head *list; - struct smdk4x12_param *param; + struct exynos_param *param; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return -EINVAL; - param = (struct smdk4x12_param *) calloc(1, sizeof(struct smdk4x12_param)); + param = (struct exynos_param *) calloc(1, sizeof(struct exynos_param)); if (param == NULL) return -ENOMEM; @@ -58,15 +58,15 @@ int smdk4x12_param_register(struct smdk4x12_camera *smdk4x12_camera, char *key, } param->type = type; - list_end = (struct list_head *) smdk4x12_camera->params; + list_end = (struct list_head *) exynos_camera->params; while (list_end != NULL && list_end->next != NULL) list_end = list_end->next; list = (struct list_head *) param; list_head_insert(list, list_end, NULL); - if (smdk4x12_camera->params == NULL) - smdk4x12_camera->params = param; + if (exynos_camera->params == NULL) + exynos_camera->params = param; return 0; @@ -81,26 +81,26 @@ error: return -1; } -void smdk4x12_param_unregister(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_param *param) +void exynos_param_unregister(struct exynos_camera *exynos_camera, + struct exynos_param *param) { struct list_head *list; - if (smdk4x12_camera == NULL || param == NULL) + if (exynos_camera == NULL || param == NULL) return; - list = (struct list_head *) smdk4x12_camera->params; + list = (struct list_head *) exynos_camera->params; while (list != NULL) { if ((void *) list == (void *) param) { list_head_remove(list); - if ((void *) list == (void *) smdk4x12_camera->params) - smdk4x12_camera->params = (struct smdk4x12_param *) list->next; + if ((void *) list == (void *) exynos_camera->params) + exynos_camera->params = (struct exynos_param *) list->next; if (param->type == EXYNOS_PARAM_STRING && param->data.string != NULL) free(param->data.string); - memset(param, 0, sizeof(struct smdk4x12_param)); + memset(param, 0, sizeof(struct exynos_param)); free(param); break; @@ -111,18 +111,18 @@ list_continue: } } -struct smdk4x12_param *smdk4x12_param_find_key(struct smdk4x12_camera *smdk4x12_camera, +struct exynos_param *exynos_param_find_key(struct exynos_camera *exynos_camera, char *key) { - struct smdk4x12_param *param; + struct exynos_param *param; struct list_head *list; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return NULL; - list = (struct list_head *) smdk4x12_camera->params; + list = (struct list_head *) exynos_camera->params; while (list != NULL) { - param = (struct smdk4x12_param *) list; + param = (struct exynos_param *) list; if (param->key == NULL) goto list_continue; @@ -136,12 +136,12 @@ list_continue: return NULL; } -int smdk4x12_param_data_set(struct smdk4x12_camera *smdk4x12_camera, char *key, - union smdk4x12_param_data data, enum smdk4x12_param_type type) +int exynos_param_data_set(struct exynos_camera *exynos_camera, char *key, + union exynos_param_data data, enum exynos_param_type type) { - struct smdk4x12_param *param; + struct exynos_param *param; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return -EINVAL; if (strchr(key, '=') || strchr(key, ';')) @@ -151,10 +151,10 @@ int smdk4x12_param_data_set(struct smdk4x12_camera *smdk4x12_camera, char *key, (strchr(data.string, '=') || strchr(data.string, ';'))) return -EINVAL; - param = smdk4x12_param_find_key(smdk4x12_camera, key); + param = exynos_param_find_key(exynos_camera, key); if (param == NULL) { // The key isn't in the list yet - smdk4x12_param_register(smdk4x12_camera, key, data, type); + exynos_param_register(exynos_camera, key, data, type); return 0; } @@ -183,15 +183,15 @@ int smdk4x12_param_data_set(struct smdk4x12_camera *smdk4x12_camera, char *key, return 0; } -int smdk4x12_param_data_get(struct smdk4x12_camera *smdk4x12_camera, char *key, - union smdk4x12_param_data *data, enum smdk4x12_param_type type) +int exynos_param_data_get(struct exynos_camera *exynos_camera, char *key, + union exynos_param_data *data, enum exynos_param_type type) { - struct smdk4x12_param *param; + struct exynos_param *param; - if (smdk4x12_camera == NULL || key == NULL || data == NULL) + if (exynos_camera == NULL || key == NULL || data == NULL) return -EINVAL; - param = smdk4x12_param_find_key(smdk4x12_camera, key); + param = exynos_param_find_key(exynos_camera, key); if (param == NULL || param->type != type) return -1; @@ -200,16 +200,16 @@ int smdk4x12_param_data_get(struct smdk4x12_camera *smdk4x12_camera, char *key, return 0; } -int smdk4x12_param_int_get(struct smdk4x12_camera *smdk4x12_camera, +int exynos_param_int_get(struct exynos_camera *exynos_camera, char *key) { - union smdk4x12_param_data data; + union exynos_param_data data; int rc; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return -EINVAL; - rc = smdk4x12_param_data_get(smdk4x12_camera, key, &data, EXYNOS_PARAM_INT); + rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_INT); if (rc < 0) { ALOGE("%s: Unable to get data for key %s", __func__, key); return -1; @@ -218,16 +218,16 @@ int smdk4x12_param_int_get(struct smdk4x12_camera *smdk4x12_camera, return data.integer; } -float smdk4x12_param_float_get(struct smdk4x12_camera *smdk4x12_camera, +float exynos_param_float_get(struct exynos_camera *exynos_camera, char *key) { - union smdk4x12_param_data data; + union exynos_param_data data; int rc; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return -EINVAL; - rc = smdk4x12_param_data_get(smdk4x12_camera, key, &data, EXYNOS_PARAM_FLOAT); + rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_FLOAT); if (rc < 0) { ALOGE("%s: Unable to get data for key %s", __func__, key); return -1; @@ -236,16 +236,16 @@ float smdk4x12_param_float_get(struct smdk4x12_camera *smdk4x12_camera, return data.floating; } -char *smdk4x12_param_string_get(struct smdk4x12_camera *smdk4x12_camera, +char *exynos_param_string_get(struct exynos_camera *exynos_camera, char *key) { - union smdk4x12_param_data data; + union exynos_param_data data; int rc; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return NULL; - rc = smdk4x12_param_data_get(smdk4x12_camera, key, &data, EXYNOS_PARAM_STRING); + rc = exynos_param_data_get(exynos_camera, key, &data, EXYNOS_PARAM_STRING); if (rc < 0) { ALOGE("%s: Unable to get data for key %s", __func__, key); return NULL; @@ -254,18 +254,18 @@ char *smdk4x12_param_string_get(struct smdk4x12_camera *smdk4x12_camera, return data.string; } -int smdk4x12_param_int_set(struct smdk4x12_camera *smdk4x12_camera, +int exynos_param_int_set(struct exynos_camera *exynos_camera, char *key, int integer) { - union smdk4x12_param_data data; + union exynos_param_data data; int rc; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return -EINVAL; data.integer = integer; - rc = smdk4x12_param_data_set(smdk4x12_camera, key, data, EXYNOS_PARAM_INT); + rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_INT); if (rc < 0) { ALOGE("%s: Unable to set data for key %s", __func__, key); return -1; @@ -274,18 +274,18 @@ int smdk4x12_param_int_set(struct smdk4x12_camera *smdk4x12_camera, return 0; } -int smdk4x12_param_float_set(struct smdk4x12_camera *smdk4x12_camera, +int exynos_param_float_set(struct exynos_camera *exynos_camera, char *key, float floating) { - union smdk4x12_param_data data; + union exynos_param_data data; int rc; - if (smdk4x12_camera == NULL || key == NULL) + if (exynos_camera == NULL || key == NULL) return -EINVAL; data.floating = floating; - rc = smdk4x12_param_data_set(smdk4x12_camera, key, data, EXYNOS_PARAM_FLOAT); + rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_FLOAT); if (rc < 0) { ALOGE("%s: Unable to set data for key %s", __func__, key); return -1; @@ -294,18 +294,18 @@ int smdk4x12_param_float_set(struct smdk4x12_camera *smdk4x12_camera, return 0; } -int smdk4x12_param_string_set(struct smdk4x12_camera *smdk4x12_camera, +int exynos_param_string_set(struct exynos_camera *exynos_camera, char *key, char *string) { - union smdk4x12_param_data data; + union exynos_param_data data; int rc; - if (smdk4x12_camera == NULL || key == NULL || string == NULL) + if (exynos_camera == NULL || key == NULL || string == NULL) return -EINVAL; data.string = string; - rc = smdk4x12_param_data_set(smdk4x12_camera, key, data, EXYNOS_PARAM_STRING); + rc = exynos_param_data_set(exynos_camera, key, data, EXYNOS_PARAM_STRING); if (rc < 0) { ALOGE("%s: Unable to set data for key %s", __func__, key); return -1; @@ -314,21 +314,21 @@ int smdk4x12_param_string_set(struct smdk4x12_camera *smdk4x12_camera, return 0; } -char *smdk4x12_params_string_get(struct smdk4x12_camera *smdk4x12_camera) +char *exynos_params_string_get(struct exynos_camera *exynos_camera) { - struct smdk4x12_param *param; + struct exynos_param *param; struct list_head *list; char *string = NULL; char *s = NULL; int length = 0; int l = 0; - if (smdk4x12_camera == NULL) + if (exynos_camera == NULL) return NULL; - list = (struct list_head *) smdk4x12_camera->params; + list = (struct list_head *) exynos_camera->params; while (list != NULL) { - param = (struct smdk4x12_param *) list; + param = (struct exynos_param *) list; if (param->key == NULL) goto list_continue_length; @@ -360,9 +360,9 @@ list_continue_length: string = calloc(1, length); s = string; - list = (struct list_head *) smdk4x12_camera->params; + list = (struct list_head *) exynos_camera->params; while (list != NULL) { - param = (struct smdk4x12_param *) list; + param = (struct exynos_param *) list; if (param->key == NULL) goto list_continue; @@ -402,10 +402,10 @@ list_continue: return string; } -int smdk4x12_params_string_set(struct smdk4x12_camera *smdk4x12_camera, char *string) +int exynos_params_string_set(struct exynos_camera *exynos_camera, char *string) { - union smdk4x12_param_data data; - enum smdk4x12_param_type type; + union exynos_param_data data; + enum exynos_param_type type; char *d = NULL; char *s = NULL; @@ -418,7 +418,7 @@ int smdk4x12_params_string_set(struct smdk4x12_camera *smdk4x12_camera, char *st int rc; int i; - if (smdk4x12_camera == NULL || string == NULL) + if (exynos_camera == NULL || string == NULL) return -1; d = strdup(string); @@ -467,7 +467,7 @@ int smdk4x12_params_string_set(struct smdk4x12_camera *smdk4x12_camera, char *st goto error; } - rc = smdk4x12_param_data_set(smdk4x12_camera, key, data, type); + rc = exynos_param_data_set(exynos_camera, key, data, type); if (rc < 0) { ALOGE("%s: Unable to set data for key %s", __func__, key); goto error; diff --git a/camera/smdk4x12_utils.c b/camera/exynos_utils.c index 90d2167..c969656 100644 --- a/camera/smdk4x12_utils.c +++ b/camera/exynos_utils.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2013 Paul Kocialkowski * * 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 @@ -22,10 +22,10 @@ #include <malloc.h> #include <ctype.h> -#define LOG_TAG "smdk4x12_utils" +#define LOG_TAG "exynos_utils" #include <utils/Log.h> -#include "smdk4x12_camera.h" +#include "exynos_camera.h" int list_head_insert(struct list_head *list, struct list_head *prev, struct list_head *next) @@ -56,7 +56,7 @@ void list_head_remove(struct list_head *list) } -int smdk4x12_camera_buffer_length(int width, int height, int format) +int exynos_camera_buffer_length(int width, int height, int format) { float bpp; int buffer_length; @@ -82,8 +82,8 @@ int smdk4x12_camera_buffer_length(int width, int height, int format) case V4L2_PIX_FMT_YUV420: case V4L2_PIX_FMT_YVU420: bpp = 1.5f; - buffer_length = SMDK4x12_CAMERA_ALIGN(width * height); - buffer_length += SMDK4x12_CAMERA_ALIGN(width * height / 2); + buffer_length = EXYNOS_CAMERA_ALIGN(width * height); + buffer_length += EXYNOS_CAMERA_ALIGN(width * height / 2); break; case V4L2_PIX_FMT_NV21: bpp = 1.5f; @@ -100,7 +100,7 @@ int smdk4x12_camera_buffer_length(int width, int height, int format) return buffer_length; } -void smdk4x12_camera_yuv_planes(int width, int height, int format, int address, int *address_y, int *address_cb, int *address_cr) +void exynos_camera_yuv_planes(int width, int height, int format, int address, int *address_y, int *address_cb, int *address_cr) { switch (format) { case V4L2_PIX_FMT_RGB32: @@ -116,12 +116,12 @@ void smdk4x12_camera_yuv_planes(int width, int height, int format, int address, if (address_y != NULL) *address_y = address; - address += SMDK4x12_CAMERA_ALIGN(width * height); + address += EXYNOS_CAMERA_ALIGN(width * height); if (address_cb != NULL) *address_cb = address; - address += SMDK4x12_CAMERA_ALIGN(width * height / 4); + address += EXYNOS_CAMERA_ALIGN(width * height / 4); if (address_cr != NULL) *address_cr = address; @@ -131,7 +131,7 @@ void smdk4x12_camera_yuv_planes(int width, int height, int format, int address, if (address_y != NULL) *address_y = address; - address += SMDK4x12_CAMERA_ALIGN(width * height); + address += EXYNOS_CAMERA_ALIGN(width * height); if (address_cb != NULL) *address_cb = address; @@ -156,19 +156,3 @@ void smdk4x12_camera_yuv_planes(int width, int height, int format, int address, break; } } - -int smdk4x12_gralloc_format(int format) -{ - switch (format) { - case V4L2_PIX_FMT_NV21: - return HAL_PIXEL_FORMAT_YCrCb_420_SP; - case V4L2_PIX_FMT_YUV420: - return HAL_PIXEL_FORMAT_YV12; - case V4L2_PIX_FMT_RGB565: - return HAL_PIXEL_FORMAT_RGB_565; - case V4L2_PIX_FMT_RGB32: - return HAL_PIXEL_FORMAT_RGBX_8888; - default: - return HAL_PIXEL_FORMAT_YCrCb_420_SP; - } -} diff --git a/camera/exynos_v4l2.c b/camera/exynos_v4l2.c new file mode 100644 index 0000000..2768676 --- /dev/null +++ b/camera/exynos_v4l2.c @@ -0,0 +1,802 @@ +/* + * Copyright (C) 2013 Paul Kocialkowski + * + * Based on crespo libcamera and exynos4 hal libcamera: + * Copyright 2008, The Android Open Source Project + * Copyright 2010, Samsung Electronics Co. LTD + * + * 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 3 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/>. + */ + +#include <fcntl.h> +#include <unistd.h> +#include <errno.h> +#include <malloc.h> +#include <poll.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> +#include <sys/mman.h> +#include <sys/ioctl.h> + +#include <asm/types.h> + +#define LOG_TAG "exynos_v4l2" +#include <utils/Log.h> + +#include "exynos_camera.h" + +int exynos_v4l2_init(struct exynos_camera *exynos_camera) +{ + int i; + + for (i = 0; i < EXYNOS_CAMERA_MAX_V4L2_NODES_COUNT; i++) + exynos_camera->v4l2_fds[i] = -1; + + return 0; +} + +int exynos_v4l2_index(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + int index; + int i; + + if (exynos_camera == NULL || exynos_camera->config == NULL || + exynos_camera->config->v4l2_nodes == NULL) + return -EINVAL; + + if (exynos_v4l2_id > exynos_camera->config->v4l2_nodes_count) + return -1; + + index = -1; + for (i = 0; i < exynos_camera->config->v4l2_nodes_count; i++) { + if (exynos_camera->config->v4l2_nodes[i].id == exynos_v4l2_id && + exynos_camera->config->v4l2_nodes[i].node != NULL) { + index = i; + } + } + + return index; +} + +int exynos_v4l2_fd(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + int index; + + if (exynos_camera == NULL) + return -EINVAL; + + index = exynos_v4l2_index(exynos_camera, exynos_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 index for id %d", __func__, exynos_v4l2_id); + return -1; + } + + return exynos_camera->v4l2_fds[index]; +} + +int exynos_v4l2_open(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + char *node; + int index; + int fd; + + if (exynos_camera == NULL || exynos_camera->config == NULL || + exynos_camera->config->v4l2_nodes == NULL) + return -EINVAL; + + index = exynos_v4l2_index(exynos_camera, exynos_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 node for id %d", __func__, exynos_v4l2_id); + return -1; + } + + node = exynos_camera->config->v4l2_nodes[index].node; + fd = open(node, O_RDWR); + if (fd < 0) { + ALOGE("%s: Unable to open v4l2 node for id %d", __func__, exynos_v4l2_id); + return -1; + } + + exynos_camera->v4l2_fds[index] = fd; + + return 0; +} + +void exynos_v4l2_close(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + int index; + + if (exynos_camera == NULL || exynos_camera->config == NULL || + exynos_camera->config->v4l2_nodes == NULL) + return; + + index = exynos_v4l2_index(exynos_camera, exynos_v4l2_id); + if (index < 0) { + ALOGE("%s: Unable to get v4l2 node for id %d", __func__, exynos_v4l2_id); + return; + } + + if (exynos_camera->v4l2_fds[index] >= 0) + close(exynos_camera->v4l2_fds[index]); + + exynos_camera->v4l2_fds[index] = -1; +} + +int exynos_v4l2_ioctl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int request, void *data) +{ + int fd; + + if (exynos_camera == NULL) + return -EINVAL; + + fd = exynos_v4l2_fd(exynos_camera, exynos_v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, exynos_v4l2_id); + return -1; + } + + return ioctl(fd, request, data); +} + +int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id) +{ + struct pollfd events; + int fd; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + fd = exynos_v4l2_fd(exynos_camera, exynos_v4l2_id); + if (fd < 0) { + ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, exynos_v4l2_id); + return -1; + } + + memset(&events, 0, sizeof(events)); + events.fd = fd; + events.events = POLLIN | POLLERR; + + rc = poll(&events, 1, 1000); + if (rc < 0 || events.revents & POLLERR) + return -1; + + return rc; +} + +int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory, int index, unsigned long userptr) +{ + struct v4l2_buffer buffer; + int rc; + + if (exynos_camera == NULL || index < 0) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + buffer.index = index; + + if (userptr) + buffer.m.userptr = userptr; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QBUF, &buffer); + return rc; +} + +int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index) +{ + return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, index, 0); +} + +int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int index, unsigned long userptr) +{ + return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, index, userptr); +} + +int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int memory) +{ + struct v4l2_buffer buffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_DQBUF, &buffer); + if (rc < 0) + return rc; + + return buffer.index; +} + +int exynos_v4l2_s_ext_ctrl_face_detection(struct exynos_camera *exynos_camera, + int id, void *value) +{ + struct v4l2_ext_control ext_ctrl_fd[111]; + struct v4l2_ext_controls ext_ctrls_fd; + struct v4l2_ext_controls *ctrls; + camera_frame_metadata_t *facedata = (camera_frame_metadata_t *)value; + int i, ret; + + ext_ctrl_fd[0].id = V4L2_CID_IS_FD_GET_FACE_COUNT; + for (i = 0; i < exynos_camera->max_detected_faces; i++) { + ext_ctrl_fd[22*i+1].id = V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER; + ext_ctrl_fd[22*i+2].id = V4L2_CID_IS_FD_GET_FACE_CONFIDENCE; + ext_ctrl_fd[22*i+3].id = V4L2_CID_IS_FD_GET_FACE_SMILE_LEVEL; + ext_ctrl_fd[22*i+4].id = V4L2_CID_IS_FD_GET_FACE_BLINK_LEVEL; + ext_ctrl_fd[22*i+5].id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_X; + ext_ctrl_fd[22*i+6].id = V4L2_CID_IS_FD_GET_FACE_TOPLEFT_Y; + ext_ctrl_fd[22*i+7].id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+8].id = V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+9].id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_X; + ext_ctrl_fd[22*i+10].id = V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_Y; + ext_ctrl_fd[22*i+11].id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+12].id = V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+13].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_X; + ext_ctrl_fd[22*i+14].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_Y; + ext_ctrl_fd[22*i+15].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+16].id = V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+17].id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_X; + ext_ctrl_fd[22*i+18].id = V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_Y; + ext_ctrl_fd[22*i+19].id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_X; + ext_ctrl_fd[22*i+20].id = V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_Y; + ext_ctrl_fd[22*i+21].id = V4L2_CID_IS_FD_GET_ANGLE; + ext_ctrl_fd[22*i+22].id = V4L2_CID_IS_FD_GET_NEXT; + } + + ext_ctrls_fd.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + ext_ctrls_fd.count = 111; + ext_ctrls_fd.controls = ext_ctrl_fd; + ctrls = &ext_ctrls_fd; + + ret = exynos_v4l2_ioctl(exynos_camera, id, VIDIOC_G_EXT_CTRLS, &ext_ctrls_fd); + + facedata->number_of_faces = ext_ctrls_fd.controls[0].value; + + for(i = 0; i < facedata->number_of_faces; i++) { + facedata->faces[i].rect[0] = ext_ctrl_fd[22*i+5].value; + facedata->faces[i].rect[1] = ext_ctrl_fd[22*i+6].value; + facedata->faces[i].rect[2] = ext_ctrl_fd[22*i+7].value; + facedata->faces[i].rect[3] = ext_ctrl_fd[22*i+8].value; + facedata->faces[i].score = ext_ctrl_fd[22*i+2].value; + /* TODO : id is unique value for each face. We need to suppot this. */ + facedata->faces[i].id = 0; + facedata->faces[i].left_eye[0] = (ext_ctrl_fd[22*i+9].value + ext_ctrl_fd[22*i+11].value) / 2; + facedata->faces[i].left_eye[1] = (ext_ctrl_fd[22*i+10].value + ext_ctrl_fd[22*i+12].value) / 2; + facedata->faces[i].right_eye[0] = (ext_ctrl_fd[22*i+13].value + ext_ctrl_fd[22*i+15].value) / 2; + facedata->faces[i].right_eye[1] = (ext_ctrl_fd[22*i+14].value + ext_ctrl_fd[22*i+16].value) / 2; + facedata->faces[i].mouth[0] = (ext_ctrl_fd[22*i+17].value + ext_ctrl_fd[22*i+19].value) / 2; + facedata->faces[i].mouth[1] = (ext_ctrl_fd[22*i+18].value + ext_ctrl_fd[22*i+20].value) / 2; + } + + return ret; +} + +int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP); +} + +int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR); +} + +int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int count) +{ + struct v4l2_requestbuffers requestbuffers; + int rc; + + if (exynos_camera == NULL || count < 0) + return -EINVAL; + + requestbuffers.type = type; + requestbuffers.count = count; + requestbuffers.memory = memory; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_REQBUFS, &requestbuffers); + if (rc < 0) + return rc; + + return requestbuffers.count; +} + +int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count) +{ + return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, count); +} + +int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int count) +{ + return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, count); +} + +int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int memory, int index) +{ + struct v4l2_buffer buffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = type; + buffer.memory = memory; + buffer.index = index; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYBUF, &buffer); + if (rc < 0) + return rc; + + return buffer.length; +} + +int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index) +{ + return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_MEMORY_MMAP, index); +} + +int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int index) +{ + return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + V4L2_MEMORY_USERPTR, index); +} + +int exynos_v4l2_querycap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int flags) +{ + struct v4l2_capability cap; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYCAP, &cap); + if (rc < 0) + return rc; + + if (!(cap.capabilities & flags)) + return -1; + + return 0; +} + +int exynos_v4l2_querycap_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_querycap(exynos_camera, exynos_v4l2_id, V4L2_CAP_VIDEO_CAPTURE); +} + +int exynos_v4l2_querycap_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_querycap(exynos_camera, exynos_v4l2_id, V4L2_CAP_VIDEO_OUTPUT); +} + +int exynos_v4l2_streamon(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type) +{ + enum v4l2_buf_type buf_type; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + buf_type = type; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_STREAMON, &buf_type); + return rc; +} + +int exynos_v4l2_streamon_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamon(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); +} + +int exynos_v4l2_streamon_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamon(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); +} + +int exynos_v4l2_streamoff(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type) +{ + enum v4l2_buf_type buf_type; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + buf_type = type; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_STREAMOFF, &buf_type); + return rc; +} + +int exynos_v4l2_streamoff_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamoff(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); +} + +int exynos_v4l2_streamoff_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id) +{ + return exynos_v4l2_streamoff(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); +} + +int exynos_v4l2_g_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int *width, int *height, int *fmt) +{ + struct v4l2_format format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + format.type = type; + format.fmt.pix.field = V4L2_FIELD_NONE; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FMT, &format); + if (rc < 0) + return rc; + + if (width != NULL) + *width = format.fmt.pix.width; + if (height != NULL) + *height = format.fmt.pix.height; + if (fmt != NULL) + *fmt = format.fmt.pix.pixelformat; + + return 0; +} + +int exynos_v4l2_g_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt) +{ + return exynos_v4l2_g_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + width, height, fmt); +} + +int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int *width, int *height, int *fmt) +{ + return exynos_v4l2_g_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + width, height, fmt); +} + +int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int width, int height, int fmt, int field, + int priv) +{ + struct v4l2_format format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&format, 0, sizeof(format)); + format.type = type; + format.fmt.pix.width = width; + format.fmt.pix.height = height; + format.fmt.pix.pixelformat = fmt; + format.fmt.pix.field = field; + format.fmt.pix.priv = priv; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format); + return rc; + + return 0; +} + +int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv) +{ + return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + width, height, fmt, V4L2_FIELD_NONE, priv); +} + +int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int width, int height, int fmt, int priv) +{ + return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + width, height, fmt, V4L2_FIELD_NONE, priv); +} + +int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height) +{ + struct v4l2_format format; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&format, 0, sizeof(format)); + format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; + format.fmt.win.w.left = left; + format.fmt.win.w.top = top; + format.fmt.win.w.width = width; + format.fmt.win.w.height = height; + + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format); + return rc; +} + +int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int type, int fmt) +{ + struct v4l2_fmtdesc fmtdesc; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + fmtdesc.type = type; + fmtdesc.index = 0; + + do { + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_ENUM_FMT, &fmtdesc); + if (rc < 0) + return rc; + + if (fmtdesc.pixelformat == (unsigned int) fmt) + return 0; + + fmtdesc.index++; + } while (rc >= 0); + + return -1; +} + +int exynos_v4l2_enum_fmt_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt) +{ + return exynos_v4l2_enum_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + fmt); +} + +int exynos_v4l2_enum_fmt_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int fmt) +{ + return exynos_v4l2_enum_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + fmt); +} + +int exynos_v4l2_enum_input(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int id) +{ + struct v4l2_input input; + int rc; + + if (exynos_camera == NULL || id < 0) + return -EINVAL; + + input.index = id; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_ENUMINPUT, &input); + if (rc < 0) + return rc; + + if (input.name[0] == '\0') + return -1; + + return 0; +} + +int exynos_v4l2_s_input(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id) +{ + struct v4l2_input input; + int rc; + + if (exynos_camera == NULL || id < 0) + return -EINVAL; + + input.index = id; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_INPUT, &input); + return rc; +} + +int exynos_v4l2_g_ext_ctrls(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_ext_control *control, int count) +{ + struct v4l2_ext_controls controls; + int rc; + + if (exynos_camera == NULL || control == NULL) + return -EINVAL; + + memset(&controls, 0, sizeof(controls)); + controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; + controls.count = count; + controls.controls = control; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_EXT_CTRLS, &controls); + return rc; +} + +int exynos_v4l2_g_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int *value) +{ + struct v4l2_control control; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + control.id = id; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_CTRL, &control); + if (rc < 0) + return rc; + + if (value != NULL) + *value = control.value; + + return 0; +} + +int exynos_v4l2_s_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int id, int value) +{ + struct v4l2_control control; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + control.id = id; + control.value = value; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CTRL, &control); + if (rc < 0) + return rc; + + return control.value; +} + +int exynos_v4l2_s_parm(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, struct v4l2_streamparm *streamparm) +{ + int rc; + + if (exynos_camera == NULL || streamparm == NULL) + return -EINVAL; + + streamparm->type = type; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_PARM, streamparm); + return rc; +} + +int exynos_v4l2_s_parm_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm) +{ + return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + streamparm); +} + +int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, struct v4l2_streamparm *streamparm) +{ + return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + streamparm); +} + +int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + int type, int left, int top, int width, int height) +{ + struct v4l2_crop crop; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + crop.type = type; + crop.c.left = left; + crop.c.top = top; + crop.c.width = width; + crop.c.height = height; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CROP, &crop); + return rc; +} + +int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height) +{ + return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, + left, top, width, height); +} + +int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, + int exynos_v4l2_id, int left, int top, int width, int height) +{ + return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, + left, top, width, height); +} + +int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void **base, int *width, int *height, int *fmt) +{ + struct v4l2_framebuffer framebuffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FBUF, &framebuffer); + if (rc < 0) + return rc; + + if (base != NULL) + *base = framebuffer.base; + if (width != NULL) + *width = framebuffer.fmt.width; + if (height != NULL) + *height = framebuffer.fmt.height; + if (fmt != NULL) + *fmt = framebuffer.fmt.pixelformat; + + return 0; +} + +int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id, + void *base, int width, int height, int fmt) +{ + struct v4l2_framebuffer framebuffer; + int rc; + + if (exynos_camera == NULL) + return -EINVAL; + + memset(&framebuffer, 0, sizeof(framebuffer)); + framebuffer.base = base; + framebuffer.fmt.width = width; + framebuffer.fmt.height = height; + framebuffer.fmt.pixelformat = fmt; + + rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FBUF, &framebuffer); + return rc; +} diff --git a/camera/smdk4x12_v4l2_output.c b/camera/exynos_v4l2_output.c index 0f8cad2..2a39fd2 100644 --- a/camera/smdk4x12_v4l2_output.c +++ b/camera/exynos_v4l2_output.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> + * Copyright (C) 2013 Paul Kocialkowski * * 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 @@ -28,13 +28,13 @@ #include <asm/types.h> -#define LOG_TAG "smdk4x12_v4l2_output" +#define LOG_TAG "exynos_v4l2_output" #include <utils/Log.h> -#include "smdk4x12_camera.h" +#include "exynos_camera.h" -int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output) +int exynos_v4l2_output_start(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output) { int width, height, format; int buffer_width, buffer_height, buffer_format; @@ -50,7 +50,7 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, int rc; int i; - if (smdk4x12_camera == NULL || output == NULL) + if (exynos_camera == NULL || output == NULL) return -EINVAL; // ALOGD("%s()", __func__); @@ -76,28 +76,28 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, goto error; } - buffer_length = smdk4x12_camera_buffer_length(width, height, format); + buffer_length = exynos_camera_buffer_length(width, height, format); - rc = smdk4x12_v4l2_open(smdk4x12_camera, v4l2_id); + rc = exynos_v4l2_open(exynos_camera, v4l2_id); if (rc < 0) { ALOGE("%s: Unable to open v4l2 device", __func__); goto error; } - rc = smdk4x12_v4l2_querycap_out(smdk4x12_camera, v4l2_id); + rc = exynos_v4l2_querycap_out(exynos_camera, v4l2_id); if (rc < 0) { ALOGE("%s: Unable to query capabilities", __func__); goto error; } - rc = smdk4x12_v4l2_g_fmt_out(smdk4x12_camera, v4l2_id, NULL, NULL, NULL); + rc = exynos_v4l2_g_fmt_out(exynos_camera, v4l2_id, NULL, NULL, NULL); if (rc < 0) { ALOGE("%s: Unable to get format", __func__); goto error; } value = 0; - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, v4l2_id, V4L2_CID_RESERVED_MEM_BASE_ADDR, &value); + rc = exynos_v4l2_g_ctrl(exynos_camera, v4l2_id, V4L2_CID_RESERVED_MEM_BASE_ADDR, &value); if (rc < 0) { ALOGE("%s: Unable to get address", __func__); goto error; @@ -106,7 +106,7 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, memory_address = value; value = 0; - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, v4l2_id, V4L2_CID_RESERVED_MEM_SIZE, &value); + rc = exynos_v4l2_g_ctrl(exynos_camera, v4l2_id, V4L2_CID_RESERVED_MEM_SIZE, &value); if (rc < 0) { ALOGE("%s: Unable to get size", __func__); goto error; @@ -114,25 +114,25 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, memory_size = value * 1024; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, v4l2_id, V4L2_CID_OVLY_MODE, FIMC_OVLY_NONE_MULTI_BUF); + rc = exynos_v4l2_s_ctrl(exynos_camera, v4l2_id, V4L2_CID_OVLY_MODE, FIMC_OVLY_NONE_MULTI_BUF); if (rc < 0) { ALOGE("%s: Unable to set overlay mode", __func__); goto error; } - rc = smdk4x12_v4l2_s_fmt_pix_out(smdk4x12_camera, v4l2_id, buffer_width, buffer_height, buffer_format, 0); + rc = exynos_v4l2_s_fmt_pix_out(exynos_camera, v4l2_id, buffer_width, buffer_height, buffer_format, 0); if (rc < 0) { ALOGE("%s: Unable to set output pixel format!", __func__); goto error; } - rc = smdk4x12_v4l2_s_crop_out(smdk4x12_camera, v4l2_id, 0, 0, buffer_width, buffer_height); + rc = exynos_v4l2_s_crop_out(exynos_camera, v4l2_id, 0, 0, buffer_width, buffer_height); if (rc < 0) { ALOGE("%s: Unable to crop", __func__); goto error; } - rc = smdk4x12_v4l2_reqbufs_out(smdk4x12_camera, v4l2_id, 1); + rc = exynos_v4l2_reqbufs_out(exynos_camera, v4l2_id, 1); if (rc < 0) { ALOGE("%s: Unable to request buffers", __func__); goto error; @@ -151,14 +151,14 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, buffers_count = i; ALOGD("Found %d buffers available for output!", buffers_count); - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - fd = smdk4x12_v4l2_fd(smdk4x12_camera, v4l2_id); + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + fd = exynos_v4l2_fd(exynos_camera, v4l2_id); if (fd < 0) { ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, v4l2_id); goto error; } - memory = smdk4x12_camera->callbacks.request_memory(fd, buffer_length, buffers_count, smdk4x12_camera->callbacks.user); + memory = exynos_camera->callbacks.request_memory(fd, buffer_length, buffers_count, exynos_camera->callbacks.user); if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { ALOGE("%s: Unable to request memory", __func__); goto error; @@ -169,14 +169,14 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, } } else { #ifdef EXYNOS_ION - memory_ion_fd = smdk4x12_ion_alloc(smdk4x12_camera, buffers_count * buffer_length); + memory_ion_fd = exynos_ion_alloc(exynos_camera, buffers_count * buffer_length); if (memory_ion_fd < 0) { ALOGE("%s: Unable to alloc ION memory", __func__); goto error; } - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - memory = smdk4x12_camera->callbacks.request_memory(memory_ion_fd, buffer_length, buffers_count, smdk4x12_camera->callbacks.user); + if (EXYNOS_CAMERA_CALLBACK_DEFINED(request_memory)) { + memory = exynos_camera->callbacks.request_memory(memory_ion_fd, buffer_length, buffers_count, exynos_camera->callbacks.user); if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { ALOGE("%s: Unable to request memory", __func__); goto error; @@ -186,7 +186,7 @@ int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, goto error; } - memory_address = smdk4x12_ion_phys(smdk4x12_camera, memory_ion_fd); + memory_address = exynos_ion_phys(exynos_camera, memory_ion_fd); #else ALOGE("%s: Unable to find memory", __func__); goto error; @@ -215,10 +215,10 @@ error: #ifdef EXYNOS_ION if (memory_ion_fd >= 0) - smdk4x12_ion_free(smdk4x12_camera, memory_ion_fd); + exynos_ion_free(exynos_camera, memory_ion_fd); #endif - smdk4x12_v4l2_close(smdk4x12_camera, v4l2_id); + exynos_v4l2_close(exynos_camera, v4l2_id); rc = -1; @@ -226,13 +226,13 @@ complete: return rc; } -void smdk4x12_v4l2_output_stop(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output) +void exynos_v4l2_output_stop(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output) { int v4l2_id; int rc; - if (smdk4x12_camera == NULL || output == NULL) + if (exynos_camera == NULL || output == NULL) return; // ALOGD("%s()", __func__); @@ -244,7 +244,7 @@ void smdk4x12_v4l2_output_stop(struct smdk4x12_camera *smdk4x12_camera, v4l2_id = output->v4l2_id; - rc = smdk4x12_v4l2_reqbufs_out(smdk4x12_camera, v4l2_id, 0); + rc = exynos_v4l2_reqbufs_out(exynos_camera, v4l2_id, 0); if (rc < 0) ALOGE("%s: Unable to request buffers", __func__); @@ -255,18 +255,18 @@ void smdk4x12_v4l2_output_stop(struct smdk4x12_camera *smdk4x12_camera, #ifdef EXYNOS_ION if (output->memory_ion_fd >= 0) { - smdk4x12_ion_free(smdk4x12_camera, output->memory_ion_fd); + exynos_ion_free(exynos_camera, output->memory_ion_fd); output->memory_ion_fd = -1; } #endif - smdk4x12_v4l2_close(smdk4x12_camera, v4l2_id); + exynos_v4l2_close(exynos_camera, v4l2_id); output->enabled = 0; } -int smdk4x12_v4l2_output(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output, int buffer_address) +int exynos_v4l2_output(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output, int buffer_address) { struct fimc_buf fimc_buffer; void *fb_base; @@ -277,7 +277,7 @@ int smdk4x12_v4l2_output(struct smdk4x12_camera *smdk4x12_camera, int v4l2_id; int rc; - if (smdk4x12_camera == NULL || output == NULL) + if (exynos_camera == NULL || output == NULL) return -EINVAL; // ALOGD("%s()", __func__); @@ -298,13 +298,13 @@ int smdk4x12_v4l2_output(struct smdk4x12_camera *smdk4x12_camera, buffer_length = output->buffer_length; v4l2_id = output->v4l2_id; - rc = smdk4x12_v4l2_g_fbuf(smdk4x12_camera, v4l2_id, &fb_base, NULL, NULL, NULL); + rc = exynos_v4l2_g_fbuf(exynos_camera, v4l2_id, &fb_base, NULL, NULL, NULL); if (rc < 0) { ALOGE("%s: Unable to get fbuf", __func__); goto error; } - rc = smdk4x12_v4l2_s_fbuf(smdk4x12_camera, v4l2_id, fb_base, width, height, format); + rc = exynos_v4l2_s_fbuf(exynos_camera, v4l2_id, fb_base, width, height, format); if (rc < 0) { ALOGE("%s: Unable to set fbuf", __func__); goto error; @@ -314,21 +314,21 @@ int smdk4x12_v4l2_output(struct smdk4x12_camera *smdk4x12_camera, address = output->memory_address + buffer_length * output->memory_index; - smdk4x12_camera_yuv_planes(width, height, format, address, (int *) &fimc_buffer.base[0], (int *) &fimc_buffer.base[1], (int *) &fimc_buffer.base[2]); + exynos_camera_yuv_planes(width, height, format, address, (int *) &fimc_buffer.base[0], (int *) &fimc_buffer.base[1], (int *) &fimc_buffer.base[2]); - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, v4l2_id, V4L2_CID_DST_INFO, (int) &fimc_buffer); + rc = exynos_v4l2_s_ctrl(exynos_camera, v4l2_id, V4L2_CID_DST_INFO, (int) &fimc_buffer); if (rc < 0) { ALOGE("%s: Unable to set dst info", __func__); goto error; } - rc = smdk4x12_v4l2_s_fmt_win(smdk4x12_camera, v4l2_id, 0, 0, width, height); + rc = exynos_v4l2_s_fmt_win(exynos_camera, v4l2_id, 0, 0, width, height); if (rc < 0) { ALOGE("%s: Unable to set overlay win", __func__); goto error; } - rc = smdk4x12_v4l2_streamon_out(smdk4x12_camera, v4l2_id); + rc = exynos_v4l2_streamon_out(exynos_camera, v4l2_id); if (rc < 0) { ALOGE("%s: Unable to start stream", __func__); goto error; @@ -336,21 +336,21 @@ int smdk4x12_v4l2_output(struct smdk4x12_camera *smdk4x12_camera, memset(&fimc_buffer, 0, sizeof(fimc_buffer)); - smdk4x12_camera_yuv_planes(buffer_width, buffer_height, buffer_format, buffer_address, (int *) &fimc_buffer.base[0], (int *) &fimc_buffer.base[1], (int *) &fimc_buffer.base[2]); + exynos_camera_yuv_planes(buffer_width, buffer_height, buffer_format, buffer_address, (int *) &fimc_buffer.base[0], (int *) &fimc_buffer.base[1], (int *) &fimc_buffer.base[2]); - rc = smdk4x12_v4l2_qbuf_out(smdk4x12_camera, v4l2_id, 0, (unsigned long) &fimc_buffer); + rc = exynos_v4l2_qbuf_out(exynos_camera, v4l2_id, 0, (unsigned long) &fimc_buffer); if (rc < 0) { ALOGE("%s: Unable to queue buffer", __func__); goto error; } - rc = smdk4x12_v4l2_dqbuf_out(smdk4x12_camera, v4l2_id); + rc = exynos_v4l2_dqbuf_out(exynos_camera, v4l2_id); if (rc < 0) { ALOGE("%s: Unable to dequeue buffer", __func__); goto error; } - rc = smdk4x12_v4l2_streamoff_out(smdk4x12_camera, v4l2_id); + rc = exynos_v4l2_streamoff_out(exynos_camera, v4l2_id); if (rc < 0) { ALOGE("%s: Unable to stop stream", __func__); goto error; @@ -366,13 +366,13 @@ complete: return rc; } -int smdk4x12_v4l2_output_release(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output) +int exynos_v4l2_output_release(struct exynos_camera *exynos_camera, + struct exynos_v4l2_output *output) { int buffers_count; int memory_index; - if (smdk4x12_camera == NULL || output == NULL) + if (exynos_camera == NULL || output == NULL) return -EINVAL; // ALOGD("%s()", __func__); diff --git a/camera/include/fimc.h b/camera/include/fimc.h deleted file mode 100644 index 3e7732d..0000000 --- a/camera/include/fimc.h +++ /dev/null @@ -1,405 +0,0 @@ -/* linux/drivers/media/video/samsung/fimc/fimc.h - * - * Copyright (c) 2010 Samsung Electronics Co., Ltd. - * http://www.samsung.com/ - * - * Header file for Samsung Camera Interface (FIMC) driver - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. -*/ - - -#ifndef __FIMC_H -#define __FIMC_H __FILE__ - -typedef unsigned int dma_addr_t; -typedef __u32 u32; -typedef __s32 s32; - -#ifdef __KERNEL__ -#include <linux/wait.h> -#include <linux/mutex.h> -#include <linux/i2c.h> -#include <linux/fb.h> -#include <linux/videodev2.h> -#include <linux/platform_device.h> -#include <media/v4l2-common.h> -#include <media/v4l2-device.h> -#include <media/v4l2-ioctl.h> -#include <media/videobuf-core.h> -#ifdef CONFIG_SLP_DMABUF -#include <media/videobuf2-core.h> -#endif -#include <media/v4l2-mediabus.h> -#if defined(CONFIG_BUSFREQ_OPP) || defined(CONFIG_BUSFREQ_LOCK_WRAPPER) -#include <mach/dev.h> -#endif -#include <plat/media.h> -#include <plat/fimc.h> -#include <plat/cpu.h> -#endif - -#ifdef CONFIG_PM_RUNTIME -#include <linux/pm_runtime.h> -#endif - -#define FIMC_NAME "s3c-fimc" -#define FIMC_CMA_NAME "fimc" - -#define FIMC_CORE_CLK "sclk_fimc" - -extern int fimc_clk_rate(void); - -#define EXYNOS_BUSFREQ_NAME "exynos-busfreq" - -#if defined(CONFIG_ARCH_EXYNOS4) -#define FIMC_DEVICES 4 -#define FIMC_PHYBUFS 32 -#define FIMC_MAXCAMS 7 -#else -#define FIMC_DEVICES 3 -#define FIMC_PHYBUFS 4 -#define FIMC_MAXCAMS 5 -#endif - -#define FIMC_SUBDEVS 3 -#define FIMC_OUTBUFS 3 -#define FIMC_INQUEUES 10 -#if defined(CONFIG_SLP) -#define FIMC_MAX_CTXS 8 -#else -#define FIMC_MAX_CTXS 4 -#endif -#define FIMC_TPID 3 -#define FIMC_CAPBUFS 32 -#define FIMC_ONESHOT_TIMEOUT 200 -#define FIMC_DQUEUE_TIMEOUT 1000 - -#define FIMC_FIFOOFF_CNT 1000000 /* Sufficiently big value for stop */ - -#define FORMAT_FLAGS_PACKED 0x1 -#define FORMAT_FLAGS_PLANAR 0x2 - -#define FIMC_ADDR_Y 0 -#define FIMC_ADDR_CB 1 -#define FIMC_ADDR_CR 2 - -#define FIMC_HD_WIDTH 1280 -#define FIMC_HD_HEIGHT 720 - -#define FIMC_FHD_WIDTH 1920 -#define FIMC_FHD_HEIGHT 1080 - -#define FIMC_MMAP_IDX -1 -#define FIMC_USERPTR_IDX -2 - -#define FIMC_HCLK 0 -#define FIMC_SCLK 1 -#define CSI_CH_0 0 -#define CSI_CH_1 1 -#if defined(CONFIG_VIDEO_FIMC_FIFO) -#define FIMC_OVLY_MODE FIMC_OVLY_FIFO -#elif defined(CONFIG_VIDEO_FIMC_DMA_AUTO) -#define FIMC_OVLY_MODE FIMC_OVLY_DMA_AUTO -#endif - -#define PINGPONG_2ADDR_MODE -#if defined(PINGPONG_2ADDR_MODE) -#define FIMC_PINGPONG 2 -#endif - -#define check_bit(data, loc) ((data) & (0x1<<(loc))) -#define FRAME_SEQ 0xf - -#define fimc_cam_use ((pdata->use_cam) ? 1 : 0) - -#define L2_FLUSH_ALL SZ_1M -#define L1_FLUSH_ALL SZ_64K - -/* - * ENUMERATIONS -*/ -enum fimc_status { - FIMC_READY_OFF = 0x00, - FIMC_STREAMOFF = 0x01, - FIMC_READY_ON = 0x02, - FIMC_STREAMON = 0x03, - FIMC_STREAMON_IDLE = 0x04, /* oneshot mode */ - FIMC_OFF_SLEEP = 0x05, - FIMC_ON_SLEEP = 0x06, - FIMC_ON_IDLE_SLEEP = 0x07, /* oneshot mode */ - FIMC_READY_RESUME = 0x08, - FIMC_BUFFER_STOP = 0x09, - FIMC_BUFFER_START = 0x0A, -}; - -enum fimc_fifo_state { - FIFO_CLOSE, - FIFO_SLEEP, -}; - -enum fimc_fimd_state { - FIMD_OFF, - FIMD_ON, -}; - -enum fimc_rot_flip { - FIMC_XFLIP = 0x01, - FIMC_YFLIP = 0x02, - FIMC_ROT = 0x10, -}; - -enum fimc_input { - FIMC_SRC_CAM, - FIMC_SRC_MSDMA, -}; - -enum fimc_overlay_mode { - FIMC_OVLY_NOT_FIXED = 0x0, /* Overlay mode isn't fixed. */ - FIMC_OVLY_FIFO = 0x1, /* Non-destructive Overlay with FIFO */ - FIMC_OVLY_DMA_AUTO = 0x2, /* Non-destructive Overlay with DMA */ - FIMC_OVLY_DMA_MANUAL = 0x3, /* Non-destructive Overlay with DMA */ - FIMC_OVLY_NONE_SINGLE_BUF = 0x4, /* Destructive Overlay with DMA single destination buffer */ - FIMC_OVLY_NONE_MULTI_BUF = 0x5, /* Destructive Overlay with DMA multiple dstination buffer */ -}; - -enum fimc_autoload { - FIMC_AUTO_LOAD, - FIMC_ONE_SHOT, -}; - -enum fimc_log { - FIMC_LOG_DEBUG = 0x1000, - FIMC_LOG_INFO_L2 = 0x0200, - FIMC_LOG_INFO_L1 = 0x0100, - FIMC_LOG_WARN = 0x0010, - FIMC_LOG_ERR = 0x0001, -}; - -enum fimc_range { - FIMC_RANGE_NARROW = 0x0, - FIMC_RANGE_WIDE = 0x1, -}; - -enum fimc_pixel_format_type{ - FIMC_RGB, - FIMC_YUV420, - FIMC_YUV422, - FIMC_YUV444, -}; - -enum fimc_framecnt_seq { - FIMC_FRAMECNT_SEQ_DISABLE, - FIMC_FRAMECNT_SEQ_ENABLE, -}; - -enum fimc_sysmmu_flag { - FIMC_SYSMMU_OFF, - FIMC_SYSMMU_ON, -}; - -enum fimc_id { - FIMC0 = 0x0, - FIMC1 = 0x1, - FIMC2 = 0x2, - FIMC3 = 0x3, -}; - -enum fimc_power_status { - FIMC_POWER_OFF, - FIMC_POWER_ON, - FIMC_POWER_SUSPEND, -}; - -enum cam_mclk_status { - CAM_MCLK_OFF, - CAM_MCLK_ON, -}; - -enum fimc_plane_num { - PLANE_1 = 0x1, - PLANE_2 = 0x2, - PLANE_3 = 0x3, - PLANE_4 = 0x4, -}; - -/* - * STRUCTURES -*/ - -/* for reserved memory */ -struct fimc_meminfo { -#ifdef CONFIG_USE_FIMC_CMA - void *cpu_addr; -#endif - dma_addr_t base; /* buffer base */ - size_t size; /* total length */ - dma_addr_t curr; /* current addr */ - dma_addr_t vaddr_base; /* buffer base */ - dma_addr_t vaddr_curr; /* current addr */ -}; - -struct fimc_buf { - dma_addr_t base[3]; - size_t length[3]; -}; - -struct fimc_overlay_buf { - u32 vir_addr[3]; - size_t size[3]; - u32 phy_addr[3]; -}; - -struct fimc_overlay { - enum fimc_overlay_mode mode; - struct fimc_overlay_buf buf; - s32 req_idx; -}; - -/* for output overlay device */ -struct fimc_idx { - int ctx; - int idx; -}; - -struct fimc_ctx_idx { - struct fimc_idx prev; - struct fimc_idx active; - struct fimc_idx next; -}; - -/* scaler abstraction: local use recommended */ -struct fimc_scaler { - u32 bypass; - u32 hfactor; - u32 vfactor; - u32 pre_hratio; - u32 pre_vratio; - u32 pre_dst_width; - u32 pre_dst_height; - u32 scaleup_h; - u32 scaleup_v; - u32 main_hratio; - u32 main_vratio; - u32 real_width; - u32 real_height; - u32 shfactor; - u32 skipline; -}; - -struct s3cfb_user_window { - int x; - int y; -}; - -enum s3cfb_data_path_t { - DATA_PATH_FIFO = 0, - DATA_PATH_DMA = 1, - DATA_PATH_IPC = 2, -}; - -enum s3cfb_mem_owner_t { - DMA_MEM_NONE = 0, - DMA_MEM_FIMD = 1, - DMA_MEM_OTHER = 2, -}; -#define S3CFB_WIN_OFF_ALL _IO('F', 202) -#define S3CFB_WIN_POSITION _IOW('F', 203, struct s3cfb_user_window) -#define S3CFB_GET_LCD_WIDTH _IOR('F', 302, int) -#define S3CFB_GET_LCD_HEIGHT _IOR('F', 303, int) -#define S3CFB_SET_WRITEBACK _IOW('F', 304, u32) -#define S3CFB_SET_WIN_ON _IOW('F', 305, u32) -#define S3CFB_SET_WIN_OFF _IOW('F', 306, u32) -#define S3CFB_SET_WIN_PATH _IOW('F', 307, enum s3cfb_data_path_t) -#define S3CFB_SET_WIN_ADDR _IOW('F', 308, unsigned long) -#define S3CFB_SET_WIN_MEM _IOW('F', 309, enum s3cfb_mem_owner_t) -/* ------------------------------------------------------------------------ */ - -struct fimc_fbinfo { - struct fb_fix_screeninfo *fix; - struct fb_var_screeninfo *var; - int lcd_hres; - int lcd_vres; - u32 is_enable; - /* lcd fifo control */ - - int (*open_fifo)(int id, int ch, int (*do_priv)(void *), void *param); - int (*close_fifo)(int id, int (*do_priv)(void *), void *param); -}; - -struct fimc_limit { - u32 pre_dst_w; - u32 bypass_w; - u32 trg_h_no_rot; - u32 trg_h_rot; - u32 real_w_no_rot; - u32 real_h_rot; -}; - -enum FIMC_EFFECT_FIN { - FIMC_EFFECT_FIN_BYPASS = 0, - FIMC_EFFECT_FIN_ARBITRARY_CBCR, - FIMC_EFFECT_FIN_NEGATIVE, - FIMC_EFFECT_FIN_ART_FREEZE, - FIMC_EFFECT_FIN_EMBOSSING, - FIMC_EFFECT_FIN_SILHOUETTE, -}; - - -struct fimc_effect { - int ie_on; - int ie_after_sc; - enum FIMC_EFFECT_FIN fin; - int pat_cb; - int pat_cr; -}; - -/* debug macro */ -#define FIMC_LOG_DEFAULT (FIMC_LOG_WARN | FIMC_LOG_ERR) - -#define FIMC_DEBUG(fmt, ...) \ - do { \ - if (ctrl->log & FIMC_LOG_DEBUG) \ - printk(KERN_DEBUG FIMC_NAME "%d: " \ - fmt, ctrl->id, ##__VA_ARGS__); \ - } while (0) - -#define FIMC_INFO_L2(fmt, ...) \ - do { \ - if (ctrl->log & FIMC_LOG_INFO_L2) \ - printk(KERN_INFO FIMC_NAME "%d: " \ - fmt, ctrl->id, ##__VA_ARGS__); \ - } while (0) - -#define FIMC_INFO_L1(fmt, ...) \ - do { \ - if (ctrl->log & FIMC_LOG_INFO_L1) \ - printk(KERN_INFO FIMC_NAME "%d: " \ - fmt, ctrl->id, ##__VA_ARGS__); \ - } while (0) - -#define FIMC_WARN(fmt, ...) \ - do { \ - if (ctrl->log & FIMC_LOG_WARN) \ - printk(KERN_WARNING FIMC_NAME "%d: " \ - fmt, ctrl->id, ##__VA_ARGS__); \ - } while (0) - - -#define FIMC_ERROR(fmt, ...) \ - do { \ - if (ctrl->log & FIMC_LOG_ERR) \ - printk(KERN_ERR FIMC_NAME "%d: " \ - fmt, ctrl->id, ##__VA_ARGS__); \ - } while (0) - - -#define fimc_dbg(fmt, ...) FIMC_DEBUG(fmt, ##__VA_ARGS__) -#define fimc_info2(fmt, ...) FIMC_INFO_L2(fmt, ##__VA_ARGS__) -#define fimc_info1(fmt, ...) FIMC_INFO_L1(fmt, ##__VA_ARGS__) -#define fimc_warn(fmt, ...) FIMC_WARN(fmt, ##__VA_ARGS__) -#define fimc_err(fmt, ...) FIMC_ERROR(fmt, ##__VA_ARGS__) - -#endif /* __FIMC_H */ diff --git a/camera/include/ion.h b/camera/include/linux/ion.h index 29dba57..29dba57 100644 --- a/camera/include/ion.h +++ b/camera/include/linux/ion.h diff --git a/camera/include/s5c73m3.h b/camera/include/linux/s5c73m3.h index ffb582e..ffb582e 100644 --- a/camera/include/s5c73m3.h +++ b/camera/include/linux/s5c73m3.h diff --git a/camera/include/linux/videodev2_exynos_camera.h b/camera/include/linux/videodev2_exynos_camera.h new file mode 100644 index 0000000..557b5e1 --- /dev/null +++ b/camera/include/linux/videodev2_exynos_camera.h @@ -0,0 +1,2047 @@ +/* + * Video for Linux Two header file for samsung + * + * Copyright (C) 2009, Dongsoo Nathaniel Kim<dongsoo45.kim@samsung.com> + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until bein accepted, will be used restrictly in Samsung's + * camera interface driver FIMC. + * + * 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. + */ + +#ifndef __LINUX_VIDEODEV2_SAMSUNG_H +#define __LINUX_VIDEODEV2_SAMSUNG_H + +/* Values for 'capabilities' field */ +/* Object detection device */ +#define V4L2_CAP_OBJ_RECOGNITION 0x10000000 +/* strobe control */ +#define V4L2_CAP_STROBE 0x20000000 + +#define V4L2_CID_FOCUS_MODE (V4L2_CID_CAMERA_CLASS_BASE+17) +/* Focus Methods */ +enum v4l2_focus_mode { + V4L2_FOCUS_MODE_AUTO = 0, + V4L2_FOCUS_MODE_MACRO = 1, + V4L2_FOCUS_MODE_MANUAL = 2, + V4L2_FOCUS_MODE_LASTP = 2, +}; + +#define V4L2_CID_ZOOM_MODE (V4L2_CID_CAMERA_CLASS_BASE+18) +/* Zoom Methods */ +enum v4l2_zoom_mode { + V4L2_ZOOM_MODE_CONTINUOUS = 0, + V4L2_ZOOM_MODE_OPTICAL = 1, + V4L2_ZOOM_MODE_DIGITAL = 2, + V4L2_ZOOM_MODE_LASTP = 2, +}; + +/* Exposure Methods */ +#define V4L2_CID_PHOTOMETRY (V4L2_CID_CAMERA_CLASS_BASE+19) +enum v4l2_photometry_mode { + V4L2_PHOTOMETRY_MULTISEG = 0, /*Multi Segment*/ + V4L2_PHOTOMETRY_CWA = 1, /*Centre Weighted Average*/ + V4L2_PHOTOMETRY_SPOT = 2, + V4L2_PHOTOMETRY_AFSPOT = 3, /*Spot metering on focused point*/ + V4L2_PHOTOMETRY_LASTP = V4L2_PHOTOMETRY_AFSPOT, +}; + +/* Manual exposure control items menu type: iris, shutter, iso */ +#define V4L2_CID_CAM_APERTURE (V4L2_CID_CAMERA_CLASS_BASE+20) +enum v4l2_aperture_mode { + APERTURE_F_AUTO = 0, + APERTURE_F_2_8, + APERTURE_F_3_2, + APERTURE_F_3_6, + APERTURE_F_4_0, + APERTURE_F_4_5, + APERTURE_F_5_1, + APERTURE_F_5_7, + APERTURE_F_6_4, + APERTURE_F_7_2, + APERTURE_MAX, +}; +#define V4L2_CID_CAM_SHUTTER (V4L2_CID_CAMERA_CLASS_BASE+21) +#define V4L2_CID_CAM_ISO (V4L2_CID_CAMERA_CLASS_BASE+22) + +/* Following CIDs are menu type */ +#define V4L2_CID_SCENEMODE (V4L2_CID_CAMERA_CLASS_BASE+23) +#define V4L2_CID_CAM_STABILIZE (V4L2_CID_CAMERA_CLASS_BASE+24) +#define V4L2_CID_CAM_MULTISHOT (V4L2_CID_CAMERA_CLASS_BASE+25) + +/* Control dynamic range */ +#define V4L2_CID_CAM_DR (V4L2_CID_CAMERA_CLASS_BASE+26) + +/* White balance preset control */ +#define V4L2_CID_WHITE_BALANCE_PRESET (V4L2_CID_CAMERA_CLASS_BASE+27) +#define V4L2_CID_CAM_SENSOR_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 28) +#define V4L2_CID_CAM_PHONE_FW_VER (V4L2_CID_CAMERA_CLASS_BASE + 29) + +/* CID extensions */ +#define V4L2_CID_ROTATION (V4L2_CID_PRIVATE_BASE + 0) +#define V4L2_CID_PADDR_Y (V4L2_CID_PRIVATE_BASE + 1) +#define V4L2_CID_PADDR_CB (V4L2_CID_PRIVATE_BASE + 2) +#define V4L2_CID_PADDR_CR (V4L2_CID_PRIVATE_BASE + 3) +#define V4L2_CID_PADDR_CBCR (V4L2_CID_PRIVATE_BASE + 4) +#define V4L2_CID_OVERLAY_AUTO (V4L2_CID_PRIVATE_BASE + 5) +#define V4L2_CID_OVERLAY_VADDR0 (V4L2_CID_PRIVATE_BASE + 6) +#define V4L2_CID_OVERLAY_VADDR1 (V4L2_CID_PRIVATE_BASE + 7) +#define V4L2_CID_OVERLAY_VADDR2 (V4L2_CID_PRIVATE_BASE + 8) +#define V4L2_CID_OVLY_MODE (V4L2_CID_PRIVATE_BASE + 9) +#define V4L2_CID_DST_INFO (V4L2_CID_PRIVATE_BASE + 10) +/* UMP secure id control */ +#define V4L2_CID_GET_UMP_SECURE_ID (V4L2_CID_PRIVATE_BASE + 11) +#define V4L2_CID_GET_PHY_SRC_YADDR (V4L2_CID_PRIVATE_BASE + 12) +#define V4L2_CID_GET_PHY_SRC_CADDR (V4L2_CID_PRIVATE_BASE + 13) +#define V4L2_CID_IMAGE_EFFECT_FN (V4L2_CID_PRIVATE_BASE + 16) +#define V4L2_CID_IMAGE_EFFECT_APPLY (V4L2_CID_PRIVATE_BASE + 17) +#define V4L2_CID_IMAGE_EFFECT_CB (V4L2_CID_PRIVATE_BASE + 18) +#define V4L2_CID_IMAGE_EFFECT_CR (V4L2_CID_PRIVATE_BASE + 19) +#define V4L2_CID_RESERVED_MEM_BASE_ADDR (V4L2_CID_PRIVATE_BASE + 20) +#define V4L2_CID_FIMC_VERSION (V4L2_CID_PRIVATE_BASE + 21) + +#define V4L2_CID_CACHE_FLUSH (V4L2_CID_PRIVATE_BASE + 61) +#define V4L2_CID_RESERVED_MEM_SIZE (V4L2_CID_PRIVATE_BASE + 63) +#define V4L2_CID_STREAM_PAUSE (V4L2_CID_PRIVATE_BASE + 53) +#define V4L2_CID_CACHE_FLUSH (V4L2_CID_PRIVATE_BASE + 61) +#define V4L2_CID_RESERVED_MEM_SIZE (V4L2_CID_PRIVATE_BASE + 63) + +/* CID Extensions for camera sensor operations */ +#define V4L2_CID_CAM_PREVIEW_ONOFF (V4L2_CID_PRIVATE_BASE + 64) +#define V4L2_CID_CAM_CAPTURE (V4L2_CID_PRIVATE_BASE + 65) +/* #define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_PRIVATE_BASE + 66) */ + +#define V4L2_CID_CAM_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 14) +#define V4L2_CID_CAM_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 15) +#define V4L2_CID_CAM_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 22) +#define V4L2_CID_CAM_SENSOR_VER (V4L2_CID_PRIVATE_BASE + 23) +#define V4L2_CID_CAM_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 24) +#define V4L2_CID_CAM_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 25) +#define V4L2_CID_CAM_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 26) +#define V4L2_CID_CAM_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 27) +#define V4L2_CID_CAM_FW_VER (V4L2_CID_PRIVATE_BASE + 28) +#define V4L2_CID_CAM_SET_FW_ADDR (V4L2_CID_PRIVATE_BASE + 29) +#define V4L2_CID_CAM_SET_FW_SIZE (V4L2_CID_PRIVATE_BASE + 30) +#define V4L2_CID_CAM_UPDATE_FW (V4L2_CID_PRIVATE_BASE + 31) +enum v4l2_firmware_mode { + FW_MODE_NONE, + FW_MODE_VERSION, + FW_MODE_UPDATE, + FW_MODE_DUMP, +}; + +#define V4L2_CID_CAM_JPEG_MAIN_SIZE (V4L2_CID_PRIVATE_BASE + 32) +#define V4L2_CID_CAM_JPEG_MAIN_OFFSET (V4L2_CID_PRIVATE_BASE + 33) +#define V4L2_CID_CAM_JPEG_THUMB_SIZE (V4L2_CID_PRIVATE_BASE + 34) +#define V4L2_CID_CAM_JPEG_THUMB_OFFSET (V4L2_CID_PRIVATE_BASE + 35) +#define V4L2_CID_CAM_JPEG_POSTVIEW_OFFSET (V4L2_CID_PRIVATE_BASE + 36) +#define V4L2_CID_CAM_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE + 37) +#define V4L2_CID_CAM_SENSOR_MAKER (V4L2_CID_PRIVATE_BASE + 38) +#define V4L2_CID_CAM_SENSOR_OPTICAL (V4L2_CID_PRIVATE_BASE + 39) +#define V4L2_CID_CAM_AF_VER_LOW (V4L2_CID_PRIVATE_BASE + 40) +#define V4L2_CID_CAM_AF_VER_HIGH (V4L2_CID_PRIVATE_BASE + 41) +#define V4L2_CID_CAM_GAMMA_RG_LOW (V4L2_CID_PRIVATE_BASE + 42) +#define V4L2_CID_CAM_GAMMA_RG_HIGH (V4L2_CID_PRIVATE_BASE + 43) +#define V4L2_CID_CAM_GAMMA_BG_LOW (V4L2_CID_PRIVATE_BASE + 44) +#define V4L2_CID_CAM_GAMMA_BG_HIGH (V4L2_CID_PRIVATE_BASE + 45) +#define V4L2_CID_CAM_DUMP_FW (V4L2_CID_PRIVATE_BASE + 46) +#define V4L2_CID_CAM_GET_DUMP_SIZE (V4L2_CID_PRIVATE_BASE + 47) +#define V4L2_CID_CAMERA_VT_MODE (V4L2_CID_PRIVATE_BASE + 48) +enum cam_vt_mode { + CAM_VT_MODE_NONE , + CAM_VT_MODE_3G , + CAM_VT_MODE_VOIP , +}; + +#define V4L2_CID_CAMERA_VGA_BLUR (V4L2_CID_PRIVATE_BASE + 49) +#define V4L2_CID_CAMERA_CAPTURE (V4L2_CID_PRIVATE_BASE + 50) +#define V4L2_CID_CAMERA_HDR (V4L2_CID_PRIVATE_BASE + 51) +#define V4L2_CID_CAMERA_HYBRID (V4L2_CID_PRIVATE_BASE + 52) + +#define V4L2_CID_MAIN_SW_DATE_INFO_YEAR (V4L2_CID_PRIVATE_BASE + 54) +#define V4L2_CID_MAIN_SW_DATE_INFO_MONTH (V4L2_CID_PRIVATE_BASE + 55) +#define V4L2_CID_MAIN_SW_DATE_INFO_DATE (V4L2_CID_PRIVATE_BASE + 56) +#define V4L2_CID_MAIN_SW_FW_MINOR_VER (V4L2_CID_PRIVATE_BASE + 57) +#define V4L2_CID_MAIN_SW_FW_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 58) +#define V4L2_CID_MAIN_SW_PRM_MINOR_VER (V4L2_CID_PRIVATE_BASE + 59) +#define V4L2_CID_MAIN_SW_PRM_MAJOR_VER (V4L2_CID_PRIVATE_BASE + 60) +#define V4L2_CID_CAMERA_HYBRID_CAPTURE (V4L2_CID_PRIVATE_BASE + 62) +#define V4L2_CID_CAMERA_FAST_MODE (V4L2_CID_PRIVATE_BASE + 66) +enum cam_fast_mode { + FAST_MODE_SUBSAMPLING_NONE , + FAST_MODE_SUBSAMPLING_HALF , + FAST_MODE_SUBSAMPLING_QUARTER , +}; +#define V4L2_CID_CAMERA_POSTVIEW_CAPTURE (V4L2_CID_PRIVATE_BASE + 67) +#define V4L2_CID_CAMERA_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 68) +#define V4L2_CID_CAMERA_YUV_CAPTURE (V4L2_CID_PRIVATE_BASE + 69) + +#define V4L2_CID_FIMC_IS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x1000) +#define V4L2_CID_FIMC_IS_TUNE_BASE (V4L2_CTRL_CLASS_CAMERA | 0x2000) +#define V4L2_CID_FIMC_IS_ISP_DBG_BASE (V4L2_CTRL_CLASS_CAMERA | 0x3000) + +#define V4L2_CID_IS_LOAD_FW (V4L2_CID_FIMC_IS_BASE + 10) +#define V4L2_CID_IS_INIT_PARAM (V4L2_CID_FIMC_IS_BASE + 11) +#define V4L2_CID_IS_RESET (V4L2_CID_FIMC_IS_BASE + 12) +#define V4L2_CID_IS_S_POWER (V4L2_CID_FIMC_IS_BASE + 13) +enum is_set_power { + IS_POWER_OFF, + IS_POWER_ON +}; + +#define V4L2_CID_IS_S_STREAM (V4L2_CID_FIMC_IS_BASE + 14) +enum is_set_stream { + IS_DISABLE_STREAM, + IS_ENABLE_STREAM +}; + +#define V4L2_CID_IS_S_SCENARIO_MODE (V4L2_CID_FIMC_IS_BASE + 15) +#define V4L2_CID_IS_S_FORMAT_SCENARIO (V4L2_CID_FIMC_IS_BASE + 16) +enum scenario_mode { + IS_MODE_PREVIEW_STILL, + IS_MODE_PREVIEW_VIDEO, + IS_MODE_CAPTURE_STILL, + IS_MODE_CAPTURE_VIDEO, + IS_MODE_MAX +}; + +/* global */ +#define V4L2_CID_IS_CAMERA_SHOT_MODE_NORMAL (V4L2_CID_FIMC_IS_BASE + 400) +/* value : 1 : single shot , >=2 : continuous shot */ + +#define V4L2_CID_IS_CAMERA_SENSOR_NUM (V4L2_CID_FIMC_IS_BASE + 201) + +#define V4L2_CID_IS_CAMERA_FOCUS_MODE (V4L2_CID_FIMC_IS_BASE + 401) +enum is_focus_mode { + IS_FOCUS_MODE_AUTO, + IS_FOCUS_MODE_MACRO, + IS_FOCUS_MODE_INFINITY, + IS_FOCUS_MODE_CONTINUOUS, + IS_FOCUS_MODE_TOUCH, + IS_FOCUS_MODE_FACEDETECT, + IS_FOCUS_MODE_IDLE, + IS_FOCUS_MODE_MAX, +}; + +#define V4L2_CID_IS_CAMERA_FLASH_MODE (V4L2_CID_FIMC_IS_BASE + 402) +enum is_flash_mode { + IS_FLASH_MODE_OFF, + IS_FLASH_MODE_AUTO, + IS_FLASH_MODE_AUTO_REDEYE, + IS_FLASH_MODE_ON, + IS_FLASH_MODE_TORCH, + IS_FLASH_MODE_MAX +}; + +#define V4L2_CID_IS_CAMERA_AWB_MODE (V4L2_CID_FIMC_IS_BASE + 403) +enum is_awb_mode { + IS_AWB_AUTO, + IS_AWB_DAYLIGHT, + IS_AWB_CLOUDY, + IS_AWB_TUNGSTEN, + IS_AWB_FLUORESCENT, + IS_AWB_MAX +}; + +#define V4L2_CID_IS_CAMERA_IMAGE_EFFECT (V4L2_CID_FIMC_IS_BASE + 404) +enum is_image_effect { + IS_IMAGE_EFFECT_DISABLE, + IS_IMAGE_EFFECT_MONOCHROME, + IS_IMAGE_EFFECT_NEGATIVE_MONO, + IS_IMAGE_EFFECT_NEGATIVE_COLOR, + IS_IMAGE_EFFECT_SEPIA, + IS_IMAGE_EFFECT_SEPIA_CB, + IS_IMAGE_EFFECT_SEPIA_CR, + IS_IMAGE_EFFECT_NEGATIVE, + IS_IMAGE_EFFECT_ARTFREEZE, + IS_IMAGE_EFFECT_EMBOSSING, + IS_IMAGE_EFFECT_SILHOUETTE, + IS_IMAGE_EFFECT_MAX +}; + +#define V4L2_CID_IS_CAMERA_ISO (V4L2_CID_FIMC_IS_BASE + 405) +enum is_iso { + IS_ISO_AUTO, + IS_ISO_50, + IS_ISO_100, + IS_ISO_200, + IS_ISO_400, + IS_ISO_800, + IS_ISO_1600, + IS_ISO_MAX +}; + +#define V4L2_CID_IS_CAMERA_CONTRAST (V4L2_CID_FIMC_IS_BASE + 406) +enum is_contrast { + IS_CONTRAST_AUTO, + IS_CONTRAST_MINUS_2, + IS_CONTRAST_MINUS_1, + IS_CONTRAST_DEFAULT, + IS_CONTRAST_PLUS_1, + IS_CONTRAST_PLUS_2, + IS_CONTRAST_MAX +}; + +#define V4L2_CID_IS_CAMERA_SATURATION (V4L2_CID_FIMC_IS_BASE + 407) +enum is_saturation { + IS_SATURATION_MINUS_2, + IS_SATURATION_MINUS_1, + IS_SATURATION_DEFAULT, + IS_SATURATION_PLUS_1, + IS_SATURATION_PLUS_2, + IS_SATURATION_MAX +}; + +#define V4L2_CID_IS_CAMERA_SHARPNESS (V4L2_CID_FIMC_IS_BASE + 408) +enum is_sharpness { + IS_SHARPNESS_MINUS_2, + IS_SHARPNESS_MINUS_1, + IS_SHARPNESS_DEFAULT, + IS_SHARPNESS_PLUS_1, + IS_SHARPNESS_PLUS_2, + IS_SHARPNESS_MAX +}; + +#define V4L2_CID_IS_CAMERA_EXPOSURE (V4L2_CID_FIMC_IS_BASE + 409) +enum is_exposure { + IS_EXPOSURE_MINUS_4, + IS_EXPOSURE_MINUS_3, + IS_EXPOSURE_MINUS_2, + IS_EXPOSURE_MINUS_1, + IS_EXPOSURE_DEFAULT, + IS_EXPOSURE_PLUS_1, + IS_EXPOSURE_PLUS_2, + IS_EXPOSURE_PLUS_3, + IS_EXPOSURE_PLUS_4, + IS_EXPOSURE_MAX +}; + +#define V4L2_CID_IS_CAMERA_BRIGHTNESS (V4L2_CID_FIMC_IS_BASE + 410) +enum is_brightness { + IS_BRIGHTNESS_MINUS_2, + IS_BRIGHTNESS_MINUS_1, + IS_BRIGHTNESS_DEFAULT, + IS_BRIGHTNESS_PLUS_1, + IS_BRIGHTNESS_PLUS_2, + IS_BRIGHTNESS_MAX +}; + +#define V4L2_CID_IS_CAMERA_HUE (V4L2_CID_FIMC_IS_BASE + 411) +enum is_hue { + IS_HUE_MINUS_2, + IS_HUE_MINUS_1, + IS_HUE_DEFAULT, + IS_HUE_PLUS_1, + IS_HUE_PLUS_2, + IS_HUE_MAX +}; + +#define V4L2_CID_IS_CAMERA_METERING (V4L2_CID_FIMC_IS_BASE + 412) +enum is_metering { + IS_METERING_AVERAGE, + IS_METERING_SPOT, + IS_METERING_MATRIX, + IS_METERING_CENTER, + IS_METERING_MAX +}; +#define V4L2_CID_IS_CAMERA_METERING_POSITION_X (V4L2_CID_FIMC_IS_BASE + 500) +#define V4L2_CID_IS_CAMERA_METERING_POSITION_Y (V4L2_CID_FIMC_IS_BASE + 501) +#define V4L2_CID_IS_CAMERA_METERING_WINDOW_X (V4L2_CID_FIMC_IS_BASE + 502) +#define V4L2_CID_IS_CAMERA_METERING_WINDOW_Y (V4L2_CID_FIMC_IS_BASE + 503) + +#define V4L2_CID_IS_CAMERA_AFC_MODE (V4L2_CID_FIMC_IS_BASE + 413) +enum is_afc_mode { + IS_AFC_DISABLE, + IS_AFC_AUTO, + IS_AFC_MANUAL_50HZ, + IS_AFC_MANUAL_60HZ, + IS_AFC_MAX +}; + +#define V4L2_CID_IS_AWB_LOCK_UNLOCK (V4L2_CID_FIMC_IS_BASE + 496) +enum is_awb_lock_unlock { + IS_AWB_LOCK, + IS_AWB_UNLOCK, + IS_AWB_LOCK_UNLOCK_MAX +}; + +#define V4L2_CID_IS_AE_LOCK_UNLOCK (V4L2_CID_FIMC_IS_BASE + 497) +enum is_ae_lock_unlock { + IS_AE_LOCK, + IS_AE_UNLOCK, + IS_AE_LOCK_UNLOCK_MAX +}; + +#define V4L2_CID_IS_FD_GET_FACE_COUNT (V4L2_CID_FIMC_IS_BASE + 600) +#define V4L2_CID_IS_FD_GET_FACE_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 601) +#define V4L2_CID_IS_FD_GET_FACE_CONFIDENCE (V4L2_CID_FIMC_IS_BASE + 602) +#define V4L2_CID_IS_FD_GET_FACE_SMILE_LEVEL (V4L2_CID_FIMC_IS_BASE + 603) +#define V4L2_CID_IS_FD_GET_FACE_BLINK_LEVEL (V4L2_CID_FIMC_IS_BASE + 604) +#define V4L2_CID_IS_FD_GET_FACE_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 605) +#define V4L2_CID_IS_FD_GET_FACE_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 606) +#define V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 607) +#define V4L2_CID_IS_FD_GET_FACE_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 608) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 609) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 610) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 611) +#define V4L2_CID_IS_FD_GET_LEFT_EYE_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 612) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 613) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 614) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 615) +#define V4L2_CID_IS_FD_GET_RIGHT_EYE_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 616) +#define V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_X (V4L2_CID_FIMC_IS_BASE + 617) +#define V4L2_CID_IS_FD_GET_MOUTH_TOPLEFT_Y (V4L2_CID_FIMC_IS_BASE + 618) +#define V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_X (V4L2_CID_FIMC_IS_BASE + 619) +#define V4L2_CID_IS_FD_GET_MOUTH_BOTTOMRIGHT_Y (V4L2_CID_FIMC_IS_BASE + 620) +#define V4L2_CID_IS_FD_GET_ANGLE (V4L2_CID_FIMC_IS_BASE + 621) +#define V4L2_CID_IS_FD_GET_YAW_ANGLE (V4L2_CID_FIMC_IS_BASE + 622) +#define V4L2_CID_IS_FD_GET_NEXT (V4L2_CID_FIMC_IS_BASE + 623) +#define V4L2_CID_IS_FD_GET_DATA (V4L2_CID_FIMC_IS_BASE + 624) + +#define V4L2_CID_IS_FD_SET_MAX_FACE_NUMBER (V4L2_CID_FIMC_IS_BASE + 650) +#define V4L2_CID_IS_FD_SET_ROLL_ANGLE (V4L2_CID_FIMC_IS_BASE + 651) + +enum is_fd_roll_angle { + /* 0, 45, 0, -45 */ + IS_FD_ROLL_ANGLE_BASIC = 0, + /* 0, 30, 0, -30, 0, 45, 0, -45 */ + IS_FD_ROLL_ANGLE_PRECISE_BASIC = 1, + /* 0, 90, 0, -90 */ + IS_FD_ROLL_ANGLE_SIDES = 2, + /* 0, 90, 0, -90 0, 45, 0, -45 */ + IS_FD_ROLL_ANGLE_PRECISE_SIDES = 3, + /* 0, 90, 0, -90, 0, 180 */ + IS_FD_ROLL_ANGLE_FULL = 4, + /* 0, 90, 0, -90, 0, 180, 0, 135, 0, -135 */ + IS_FD_ROLL_ANGLE_PRECISE_FULL = 5, +}; + +#define V4L2_CID_IS_FD_SET_YAW_ANGLE (V4L2_CID_FIMC_IS_BASE + 652) +enum is_fd_yaw_angle { + IS_FD_YAW_ANGLE_0 = 0, + IS_FD_YAW_ANGLE_45 = 1, + IS_FD_YAW_ANGLE_90 = 2, + IS_FD_YAW_ANGLE_45_90 = 3, +}; + +#define V4L2_CID_IS_FD_SET_SMILE_MODE (V4L2_CID_FIMC_IS_BASE + 653) +enum is_fd_smile_mode { + IS_FD_SMILE_MODE_DISABLE = 0, + IS_FD_SMILE_MODE_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_BLINK_MODE (V4L2_CID_FIMC_IS_BASE + 654) +enum is_fd_blink_mode { + IS_FD_BLINK_MODE_DISABLE = 0, + IS_FD_BLINK_MODE_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_EYE_DETECT_MODE (V4L2_CID_FIMC_IS_BASE + 655) +enum is_fd_eye_detect_mode { + IS_FD_EYE_DETECT_DISABLE = 0, + IS_FD_EYE_DETECT_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_MOUTH_DETECT_MODE (V4L2_CID_FIMC_IS_BASE + 656) +enum is_fd_mouth_detect_mode { + IS_FD_MOUTH_DETECT_DISABLE = 0, + IS_FD_MOUTH_DETECT_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_ORIENTATION_MODE (V4L2_CID_FIMC_IS_BASE + 657) +enum is_fd_orientation_mode { + IS_FD_ORIENTATION_DISABLE = 0, + IS_FD_ORIENTATION_ENABLE = 1, +}; + +#define V4L2_CID_IS_FD_SET_ORIENTATION (V4L2_CID_FIMC_IS_BASE + 658) +#define V4L2_CID_IS_FD_SET_DATA_ADDRESS (V4L2_CID_FIMC_IS_BASE + 659) + +#define V4L2_CID_IS_SET_ISP (V4L2_CID_FIMC_IS_BASE + 440) +enum is_isp_bypass_mode { + IS_ISP_BYPASS_DISABLE, + IS_ISP_BYPASS_ENABLE, + IS_ISP_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_DRC (V4L2_CID_FIMC_IS_BASE + 441) +enum is_drc_bypass_mode { + IS_DRC_BYPASS_DISABLE, + IS_DRC_BYPASS_ENABLE, + IS_DRC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_FD (V4L2_CID_FIMC_IS_BASE + 442) +enum is_fd_bypass_mode { + IS_FD_BYPASS_DISABLE, + IS_FD_BYPASS_ENABLE, + IS_FD_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_ODC (V4L2_CID_FIMC_IS_BASE + 443) +enum is_odc_bypass_mode { + IS_ODC_BYPASS_DISABLE, + IS_ODC_BYPASS_ENABLE, + IS_ODC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_DIS (V4L2_CID_FIMC_IS_BASE + 444) +enum is_dis_bypass_mode { + IS_DIS_BYPASS_DISABLE, + IS_DIS_BYPASS_ENABLE, + IS_DIS_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_3DNR (V4L2_CID_FIMC_IS_BASE + 445) +enum is_tdnr_bypass_mode { + IS_TDNR_BYPASS_DISABLE, + IS_TDNR_BYPASS_ENABLE, + IS_TDNR_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_SCALERC (V4L2_CID_FIMC_IS_BASE + 446) +enum is_scalerc_bypass_mode { + IS_SCALERC_BYPASS_DISABLE, + IS_SCALERC_BYPASS_ENABLE, + IS_SCALERC_BYPASS_MAX +}; + +#define V4L2_CID_IS_SET_SCALERP (V4L2_CID_FIMC_IS_BASE + 446) +enum is_scalerp_bypass_mode { + IS_SCALERP_BYPASS_DISABLE, + IS_SCALERP_BYPASS_ENABLE, + IS_SCALERP_BYPASS_MAX +}; + +#define V4L2_CID_IS_ROTATION_MODE (V4L2_CID_FIMC_IS_BASE + 450) +enum is_rotation_mode { + IS_ROTATION_0, + IS_ROTATION_90, + IS_ROTATION_180, + IS_ROTATION_270, + IS_ROTATION_MAX +}; + +#define V4L2_CID_IS_3DNR_1ST_FRAME_MODE (V4L2_CID_FIMC_IS_BASE + 451) +enum is_tdnr_1st_frame_mode { + IS_TDNR_1ST_FRAME_NOPROCESSING, + IS_TDNR_1ST_FRAME_2DNR, + IS_TDNR_MAX +}; + +#define V4L2_CID_IS_CAMERA_OBJECT_POSITION_X (V4L2_CID_FIMC_IS_BASE + 452) +#define V4L2_CID_IS_CAMERA_OBJECT_POSITION_Y (V4L2_CID_FIMC_IS_BASE + 453) +#define V4L2_CID_IS_CAMERA_WINDOW_SIZE_X (V4L2_CID_FIMC_IS_BASE + 454) +#define V4L2_CID_IS_CAMERA_WINDOW_SIZE_Y (V4L2_CID_FIMC_IS_BASE + 455) + +#define V4L2_CID_IS_CAMERA_EXIF_EXPTIME (V4L2_CID_FIMC_IS_BASE + 456) +#define V4L2_CID_IS_CAMERA_EXIF_FLASH (V4L2_CID_FIMC_IS_BASE + 457) +#define V4L2_CID_IS_CAMERA_EXIF_ISO (V4L2_CID_FIMC_IS_BASE + 458) +#define V4L2_CID_IS_CAMERA_EXIF_SHUTTERSPEED (V4L2_CID_FIMC_IS_BASE + 459) +#define V4L2_CID_IS_CAMERA_EXIF_BRIGHTNESS (V4L2_CID_FIMC_IS_BASE + 460) + +#define V4L2_CID_IS_CAMERA_ISP_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 461) +enum is_isp_sel_input { + IS_ISP_INPUT_OTF, + IS_ISP_INPUT_DMA1, + IS_ISP_INPUT_DMA2, + IS_ISP_INPUT_DMA12, + IS_ISP_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_ISP_SEL_OUTPUT (V4L2_CID_FIMC_IS_BASE + 462) +enum is_isp_sel_output { + IS_ISP_OUTPUT_OTF, + IS_ISP_OUTPUT_DMA1, + IS_ISP_OUTPUT_DMA2, + IS_ISP_OUTPUT_DMA12, + IS_ISP_OUTPUT_OTF_DMA1, + IS_ISP_OUTPUT_OTF_DMA2, + IS_ISP_OUTPUT_OTF_DMA12, + IS_ISP_OUTPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_DRC_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 463) +enum is_drc_sel_input { + IS_DRC_INPUT_OTF, + IS_DRC_INPUT_DMA, + IS_DRC_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_FD_SEL_INPUT (V4L2_CID_FIMC_IS_BASE + 464) +enum is_fd_sel_input { + IS_FD_INPUT_OTF, + IS_FD_INPUT_DMA, + IS_FD_INPUT_MAX +}; + +#define V4L2_CID_IS_CAMERA_INIT_WIDTH (V4L2_CID_FIMC_IS_BASE + 465) +#define V4L2_CID_IS_CAMERA_INIT_HEIGHT (V4L2_CID_FIMC_IS_BASE + 466) + +#define V4L2_CID_IS_CMD_ISP (V4L2_CID_FIMC_IS_BASE + 467) +enum is_isp_cmd_mode { + IS_ISP_COMMAND_STOP, + IS_ISP_COMMAND_START, + IS_ISP_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_DRC (V4L2_CID_FIMC_IS_BASE + 468) +enum is_drc_cmd_mode { + IS_DRC_COMMAND_STOP, + IS_DRC_COMMAND_START, + IS_DRC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_FD (V4L2_CID_FIMC_IS_BASE + 469) +enum is_fd_cmd_mode { + IS_FD_COMMAND_STOP, + IS_FD_COMMAND_START, + IS_FD_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_ODC (V4L2_CID_FIMC_IS_BASE + 470) +enum is_odc_cmd_mode { + IS_ODC_COMMAND_STOP, + IS_ODC_COMMAND_START, + IS_ODC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_DIS (V4L2_CID_FIMC_IS_BASE + 471) +enum is_dis_cmd_mode { + IS_DIS_COMMAND_STOP, + IS_DIS_COMMAND_START, + IS_DIS_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_TDNR (V4L2_CID_FIMC_IS_BASE + 472) +enum is_tdnr_cmd_mode { + IS_TDNR_COMMAND_STOP, + IS_TDNR_COMMAND_START, + IS_TDNR_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_SCALERC (V4L2_CID_FIMC_IS_BASE + 473) +enum is_scalerc_cmd_mode { + IS_SCALERC_COMMAND_STOP, + IS_SCALERC_COMMAND_START, + IS_SCALERC_COMMAND_MAX +}; + +#define V4L2_CID_IS_CMD_SCALERP (V4L2_CID_FIMC_IS_BASE + 474) +enum is_scalerp_cmd_mode { + IS_SCALERP_COMMAND_STOP, + IS_SCALERP_COMMAND_START, + IS_SCALERP_COMMAND_MAX +}; + +#define V4L2_CID_IS_GET_SENSOR_OFFSET_X (V4L2_CID_FIMC_IS_BASE + 480) +#define V4L2_CID_IS_GET_SENSOR_OFFSET_Y (V4L2_CID_FIMC_IS_BASE + 481) +#define V4L2_CID_IS_GET_SENSOR_WIDTH (V4L2_CID_FIMC_IS_BASE + 482) +#define V4L2_CID_IS_GET_SENSOR_HEIGHT (V4L2_CID_FIMC_IS_BASE + 483) + +#define V4L2_CID_IS_GET_FRAME_VALID (V4L2_CID_FIMC_IS_BASE + 484) +#define V4L2_CID_IS_SET_FRAME_VALID (V4L2_CID_FIMC_IS_BASE + 485) +#define V4L2_CID_IS_GET_FRAME_BADMARK (V4L2_CID_FIMC_IS_BASE + 486) +#define V4L2_CID_IS_SET_FRAME_BADMARK (V4L2_CID_FIMC_IS_BASE + 487) +#define V4L2_CID_IS_GET_FRAME_CAPTURED (V4L2_CID_FIMC_IS_BASE + 488) +#define V4L2_CID_IS_SET_FRAME_CAPTURED (V4L2_CID_FIMC_IS_BASE + 489) +#define V4L2_CID_IS_SET_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 490) +#define V4L2_CID_IS_GET_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 491) +#define V4L2_CID_IS_CLEAR_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 492) +#define V4L2_CID_IS_GET_LOSTED_FRAME_NUMBER (V4L2_CID_FIMC_IS_BASE + 493) +#define V4L2_CID_IS_ISP_DMA_BUFFER_NUM (V4L2_CID_FIMC_IS_BASE + 494) +#define V4L2_CID_IS_ISP_DMA_BUFFER_ADDRESS (V4L2_CID_FIMC_IS_BASE + 495) + +#define V4L2_CID_IS_ZOOM_STATE (V4L2_CID_FIMC_IS_BASE + 660) +#define V4L2_CID_IS_ZOOM_MAX_LEVEL (V4L2_CID_FIMC_IS_BASE + 661) +#define V4L2_CID_IS_ZOOM (V4L2_CID_FIMC_IS_BASE + 662) +#define V4L2_CID_IS_FW_DEBUG_REGION_ADDR (V4L2_CID_FIMC_IS_BASE + 663) + +#define V4L2_CID_IS_TUNE_SEL_ENTRY (V4L2_CID_FIMC_IS_TUNE_BASE) +#define V4L2_CID_IS_TUNE_SENSOR_EXPOSURE (V4L2_CID_FIMC_IS_TUNE_BASE + 1) +#define V4L2_CID_IS_TUNE_SENSOR_ANALOG_GAIN (V4L2_CID_FIMC_IS_TUNE_BASE + 2) +#define V4L2_CID_IS_TUNE_SENSOR_FRAME_RATE (V4L2_CID_FIMC_IS_TUNE_BASE + 3) +#define V4L2_CID_IS_TUNE_SENSOR_ACTUATOR_POS (V4L2_CID_FIMC_IS_TUNE_BASE + 4) + +enum v4l2_blur { + BLUR_LEVEL_0 = 0, + BLUR_LEVEL_1, + BLUR_LEVEL_2, + BLUR_LEVEL_3, + BLUR_LEVEL_MAX, +}; + +#if 1 +#define V4L2_CID_CAMERA_SCENE_MODE (V4L2_CID_PRIVATE_BASE+70) +enum v4l2_scene_mode { + SCENE_MODE_BASE, + SCENE_MODE_NONE, + SCENE_MODE_PORTRAIT, + SCENE_MODE_NIGHTSHOT, + SCENE_MODE_BACK_LIGHT, + SCENE_MODE_LANDSCAPE, + SCENE_MODE_SPORTS, + SCENE_MODE_PARTY_INDOOR, + SCENE_MODE_BEACH_SNOW, + SCENE_MODE_SUNSET, + SCENE_MODE_DUSK_DAWN, + SCENE_MODE_FALL_COLOR, + SCENE_MODE_FIREWORKS, + SCENE_MODE_TEXT, + SCENE_MODE_CANDLE_LIGHT, + SCENE_MODE_LOW_LIGHT, + SCENE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_FLASH_MODE (V4L2_CID_PRIVATE_BASE+71) +enum v4l2_flash_mode { + FLASH_MODE_BASE, + FLASH_MODE_OFF, + FLASH_MODE_AUTO, + FLASH_MODE_ON, + FLASH_MODE_TORCH, + FLASH_MODE_RED_EYE, + FLASH_MODE_FILL_IN, + FLASH_MODE_SLOW_SYNC, + FLASH_MODE_RED_EYE_FIX, + FLASH_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_BRIGHTNESS (V4L2_CID_PRIVATE_BASE+72) +enum v4l2_ev_mode { + EV_MINUS_4 = -4, + EV_MINUS_3 = -3, + EV_MINUS_2 = -2, + EV_MINUS_1 = -1, + EV_DEFAULT = 0, + EV_PLUS_1 = 1, + EV_PLUS_2 = 2, + EV_PLUS_3 = 3, + EV_PLUS_4 = 4, + EV_MAX, + EV_MAX_V4L2 = EV_MAX, +}; + +enum v4l2_exposure { + EXPOSURE_MINUS_6 = -6, + EXPOSURE_MINUS_5 = -5, + EXPOSURE_MINUS_4 = -4, + EXPOSURE_MINUS_3 = -3, + EXPOSURE_MINUS_2 = -2, + EXPOSURE_MINUS_1 = -1, + EXPOSURE_DEFAULT = 0, + EXPOSURE_PLUS_1 = 1, + EXPOSURE_PLUS_2 = 2, + EXPOSURE_PLUS_3 = 3, + EXPOSURE_PLUS_4 = 4, + EXPOSURE_PLUS_5 = 5, + EXPOSURE_PLUS_6 = 6, + EXPOSURE_MAX, +}; + +#define V4L2_CID_CAMERA_WHITE_BALANCE (V4L2_CID_PRIVATE_BASE+73) +enum v4l2_wb_mode { + WHITE_BALANCE_BASE = 0, + WHITE_BALANCE_AUTO, + WHITE_BALANCE_SUNNY, + WHITE_BALANCE_CLOUDY, + WHITE_BALANCE_TUNGSTEN, + WHITE_BALANCE_FLUORESCENT, + WHITE_BALANCE_FLUORESCENT_H, + WHITE_BALANCE_FLUORESCENT_L, + WHITE_BALANCE_CUSTOM, + WHITE_BALANCE_K, + WHITE_BALANCE_INCANDESCENT, + WHITE_BALANCE_PROHIBITION, + WHITE_BALANCE_HORIZON, + WHITE_BALANCE_LEDLIGHT, + WHITE_BALANCE_MAX, +}; + +#define V4L2_CID_CAMERA_EFFECT (V4L2_CID_PRIVATE_BASE+74) +enum v4l2_effect_mode { + IMAGE_EFFECT_BASE = 0, + IMAGE_EFFECT_NONE, + IMAGE_EFFECT_BNW, + IMAGE_EFFECT_SEPIA, + IMAGE_EFFECT_AQUA, + IMAGE_EFFECT_ANTIQUE, + IMAGE_EFFECT_NEGATIVE, + IMAGE_EFFECT_SHARPEN, + IMAGE_EFFECT_SKETCH, + IMAGE_EFFECT_WASHED, + IMAGE_EFFECT_VINTAGE_WARM, + IMAGE_EFFECT_VINTAGE_COLD, + IMAGE_EFFECT_SOLARIZE, + IMAGE_EFFECT_POSTERIZE, + IMAGE_EFFECT_POINT_BLUE, + IMAGE_EFFECT_POINT_RED_YELLOW, + IMAGE_EFFECT_POINT_COLOR_3, + IMAGE_EFFECT_POINT_GREEN, + IMAGE_EFFECT_POINT_RED, + IMAGE_EFFECT_POINT_YELLOW, + IMAGE_EFFECT_CARTOONIZE, + IMAGE_EFFECT_MAX, +}; + +#define V4L2_CID_CAMERA_ISO (V4L2_CID_PRIVATE_BASE+75) +enum v4l2_iso_mode { + ISO_AUTO = 0, + ISO_50, + ISO_100, + ISO_200, + ISO_400, + ISO_800, + ISO_1600, + ISO_3200, + ISO_SPORTS, + ISO_NIGHT, + ISO_MOVIE, + ISO_MAX, +}; + +#define V4L2_CID_CAMERA_METERING (V4L2_CID_PRIVATE_BASE+76) +enum v4l2_metering_mode { + METERING_BASE = 0, + METERING_MATRIX, + METERING_CENTER, + METERING_SPOT, + METERING_MAX, +}; + +#define V4L2_CID_CAMERA_CONTRAST (V4L2_CID_PRIVATE_BASE+77) +enum v4l2_contrast_mode { + CONTRAST_MINUS_2 = 0, + CONTRAST_MINUS_1, + CONTRAST_DEFAULT, + CONTRAST_PLUS_1, + CONTRAST_PLUS_2, + CONTRAST_MAX, +}; + +#define V4L2_CID_CAMERA_SATURATION (V4L2_CID_PRIVATE_BASE+78) +enum v4l2_saturation_mode { + SATURATION_MINUS_2 = 0, + SATURATION_MINUS_1, + SATURATION_DEFAULT, + SATURATION_PLUS_1, + SATURATION_PLUS_2, + SATURATION_MAX, +}; + +#define V4L2_CID_CAMERA_SHARPNESS (V4L2_CID_PRIVATE_BASE+79) +enum v4l2_sharpness_mode { + SHARPNESS_MINUS_2 = 0, + SHARPNESS_MINUS_1, + SHARPNESS_DEFAULT, + SHARPNESS_PLUS_1, + SHARPNESS_PLUS_2, + SHARPNESS_MAX, +}; + +#define V4L2_CID_CAMERA_WDR (V4L2_CID_PRIVATE_BASE+80) +enum v4l2_wdr_mode { + WDR_OFF, + WDR_ON, + WDR_MAX, +}; + +#define V4L2_CID_CAMERA_ANTI_SHAKE (V4L2_CID_PRIVATE_BASE+81) +enum v4l2_anti_shake_mode { + ANTI_SHAKE_OFF, + ANTI_SHAKE_STILL_ON, + ANTI_SHAKE_MOVIE_ON, + ANTI_SHAKE_MAX, +}; + +#define V4L2_CID_CAMERA_TOUCH_AF_START_STOP (V4L2_CID_PRIVATE_BASE+82) +enum v4l2_touch_af { + TOUCH_AF_STOP = 0, + TOUCH_AF_START, + TOUCH_AF_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO (V4L2_CID_PRIVATE_BASE+83) +enum v4l2_smart_auto { + SMART_AUTO_OFF = 0, + SMART_AUTO_ON, + SMART_AUTO_MAX, +}; + +#define V4L2_CID_CAMERA_VINTAGE_MODE (V4L2_CID_PRIVATE_BASE+84) +enum v4l2_vintage_mode { + VINTAGE_MODE_BASE, + VINTAGE_MODE_OFF, + VINTAGE_MODE_NORMAL, + VINTAGE_MODE_WARM, + VINTAGE_MODE_COOL, + VINTAGE_MODE_BNW, + VINTAGE_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_JPEG_QUALITY (V4L2_CID_PRIVATE_BASE+85) +#define V4L2_CID_CAMERA_CAPTURE_THUMB (V4L2_CID_PRIVATE_BASE + 86) +#define V4L2_CID_CAMERA_YUV_SNAPSHOT (V4L2_CID_PRIVATE_BASE + 87) +#define V4L2_CID_CAMERA_LOW_LIGHT_MODE (V4L2_CID_PRIVATE_BASE + 88) +#define V4L2_CID_CAMERA_GPS_LATITUDE (V4L2_CID_CAMERA_CLASS_BASE+30) +/* (V4L2_CID_PRIVATE_BASE+87) */ +#define V4L2_CID_CAMERA_GPS_LONGITUDE (V4L2_CID_CAMERA_CLASS_BASE + 31) +/* (V4L2_CID_PRIVATE_BASE+88) */ +#define V4L2_CID_CAMERA_GPS_TIMESTAMP (V4L2_CID_CAMERA_CLASS_BASE + 32) +/* (V4L2_CID_PRIVATE_BASE+89)*/ +#define V4L2_CID_CAMERA_GPS_ALTITUDE (V4L2_CID_CAMERA_CLASS_BASE + 33) +#define V4L2_CID_CAMERA_EXIF_TIME_INFO (V4L2_CID_CAMERA_CLASS_BASE + 34) +#define V4L2_CID_CAMERA_GPS_PROCESSINGMETHOD (V4L2_CID_CAMERA_CLASS_BASE+35) + +#define V4L2_CID_FOCUS_AUTO_MODE (V4L2_CID_CAMERA_CLASS_BASE+36) +enum v4l2_focus_mode_type { + V4L2_FOCUS_AUTO_NORMAL = 0, + V4L2_FOCUS_AUTO_MACRO, + V4L2_FOCUS_AUTO_CONTINUOUS, + V4L2_FOCUS_AUTO_FACE_DETECTION, + V4L2_FOCUS_AUTO_RECTANGLE, + V4L2_FOCUS_AUTO_MAX, +}; +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_LEFT (V4L2_CID_CAMERA_CLASS_BASE+37) +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_TOP (V4L2_CID_CAMERA_CLASS_BASE+38) +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_WIDTH (V4L2_CID_CAMERA_CLASS_BASE+39) +#define V4L2_CID_FOCUS_AUTO_RECTANGLE_HEIGHT (V4L2_CID_CAMERA_CLASS_BASE+40) + +#define V4L2_CID_CAMERA_ZOOM (V4L2_CID_PRIVATE_BASE+90) +enum v4l2_zoom_level { + ZOOM_LEVEL_0 = 0, + ZOOM_LEVEL_1, + ZOOM_LEVEL_2, + ZOOM_LEVEL_3, + ZOOM_LEVEL_4, + ZOOM_LEVEL_5, + ZOOM_LEVEL_6, + ZOOM_LEVEL_7, + ZOOM_LEVEL_8, + ZOOM_LEVEL_9, + ZOOM_LEVEL_10, + ZOOM_LEVEL_11, + ZOOM_LEVEL_12, + ZOOM_LEVEL_MAX = 31, +}; + +#define V4L2_CID_CAMERA_FACE_DETECTION (V4L2_CID_PRIVATE_BASE+91) +enum v4l2_face_detection { + FACE_DETECTION_OFF = 0, + FACE_DETECTION_ON, + FACE_DETECTION_NOLINE, + FACE_DETECTION_ON_BEAUTY, + FACE_DETECTION_NORMAL, + FACE_DETECTION_SMILE_SHOT, + FACE_DETECTION_BLINK, + FACE_DETECTION_MAX, +}; + +#define V4L2_CID_CAMERA_SMART_AUTO_STATUS (V4L2_CID_PRIVATE_BASE+92) +enum v4l2_smart_auto_status { + SMART_AUTO_STATUS_AUTO = 0, + SMART_AUTO_STATUS_LANDSCAPE, + SMART_AUTO_STATUS_PORTRAIT, + SMART_AUTO_STATUS_MACRO, + SMART_AUTO_STATUS_NIGHT, + SMART_AUTO_STATUS_PORTRAIT_NIGHT, + SMART_AUTO_STATUS_BACKLIT, + SMART_AUTO_STATUS_PORTRAIT_BACKLIT, + SMART_AUTO_STATUS_ANTISHAKE, + SMART_AUTO_STATUS_PORTRAIT_ANTISHAKE, + SMART_AUTO_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_SET_AUTO_FOCUS (V4L2_CID_PRIVATE_BASE+93) +enum v4l2_auto_focus { + AUTO_FOCUS_OFF = 0, + AUTO_FOCUS_ON, + AUTO_FOCUS_MAX, +}; + +#define V4L2_CID_CAMERA_BEAUTY_SHOT (V4L2_CID_PRIVATE_BASE+94) +enum v4l2_beauty_shot { + BEAUTY_SHOT_OFF = 0, + BEAUTY_SHOT_ON, + BEAUTY_SHOT_MAX, +}; + +#define V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE+95) +enum v4l2_ae_awb_lockunlock { + AE_UNLOCK_AWB_UNLOCK = 0, + AE_LOCK_AWB_UNLOCK, + AE_UNLOCK_AWB_LOCK, + AE_LOCK_AWB_LOCK, + AE_AWB_MAX +}; + +#define V4L2_CID_CAMERA_FACEDETECT_LOCKUNLOCK (V4L2_CID_PRIVATE_BASE+96) +enum v4l2_face_lock { + FACE_LOCK_OFF = 0, + FACE_LOCK_ON, + FIRST_FACE_TRACKING, + FACE_LOCK_MAX, +}; + +#define V4L2_CID_CAMERA_OBJECT_POSITION_X (V4L2_CID_PRIVATE_BASE+97) +#define V4L2_CID_CAMERA_OBJECT_POSITION_Y (V4L2_CID_PRIVATE_BASE+98) +#define V4L2_CID_CAMERA_FOCUS_MODE (V4L2_CID_PRIVATE_BASE+99) +enum v4l2_focusmode { + FOCUS_MODE_AUTO = 0, + FOCUS_MODE_MACRO, + FOCUS_MODE_FACEDETECT, + FOCUS_MODE_AUTO_DEFAULT, + FOCUS_MODE_MACRO_DEFAULT, + FOCUS_MODE_FACEDETECT_DEFAULT, + FOCUS_MODE_INFINITY, + FOCUS_MODE_FIXED, + FOCUS_MODE_CONTINOUS, + FOCUS_MODE_CONTINOUS_PICTURE, + FOCUS_MODE_CONTINOUS_PICTURE_MACRO, + FOCUS_MODE_CONTINOUS_VIDEO, + FOCUS_MODE_TOUCH, + FOCUS_MODE_MANUAL, + FOCUS_MODE_MULTI, + FOCUS_MODE_OBJECT_TRACKING, + FOCUS_MODE_MAX, + FOCUS_MODE_DEFAULT = (1 << 8), +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_STATUS (V4L2_CID_PRIVATE_BASE+100) +enum v4l2_obj_tracking_status { + OBJECT_TRACKING_STATUS_BASE = 0, + OBJECT_TRACKING_STATUS_SUCCESS = 1, + OBJECT_TRACKING_STATUS_MISSING = 2, + OBJECT_TRACKING_STATUS_FAIL = 3, + OBJECT_TRACKING_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_OBJ_TRACKING_START_STOP (V4L2_CID_PRIVATE_BASE+101) +enum v4l2_ot_start_stop { + OT_STOP = 0, + OT_START, + OT_MAX, +}; + +#define V4L2_CID_CAMERA_CAF_START_STOP (V4L2_CID_PRIVATE_BASE+102) +enum v4l2_caf_start_stop { + CAF_STOP = 0, + CAF_START, + CAF_MAX, +}; + +#define V4L2_CID_CAMERA_AUTO_FOCUS_RESULT (V4L2_CID_PRIVATE_BASE+103) +enum v4l2_af_status { + CAMERA_AF_STATUS_IN_PROGRESS = 0, + CAMERA_AF_STATUS_SUCCESS, + CAMERA_AF_STATUS_FAIL, + CAMERA_AF_STATUS_1ST_SUCCESS, + CAMERA_AF_STATUS_RESTART, + CAMERA_AF_STATUS_MAX, +}; + +#define V4L2_CID_CAMERA_FRAME_RATE (V4L2_CID_PRIVATE_BASE+104) +enum v4l2_frame_rate { + FRAME_RATE_AUTO = 0, + FRAME_RATE_7 = 7, + FRAME_RATE_15 = 15, + FRAME_RATE_20 = 20, + FRAME_RATE_25 = 25, + FRAME_RATE_30 = 30, + FRAME_RATE_60 = 60, + FRAME_RATE_120 = 120, + FRAME_RATE_MAX +}; + +#define V4L2_CID_CAMERA_ANTI_BANDING (V4L2_CID_PRIVATE_BASE+105) +enum v4l2_anti_banding { + ANTI_BANDING_AUTO = 0, + ANTI_BANDING_50HZ = 1, + ANTI_BANDING_60HZ = 2, + ANTI_BANDING_50_60Hz = 3, + ANTI_BANDING_OFF = 4, +}; + +#define V4L2_CID_CAMERA_SET_GAMMA (V4L2_CID_PRIVATE_BASE+106) +enum v4l2_gamma_mode { + GAMMA_OFF = 0, + GAMMA_ON = 1, + GAMMA_MAX, +}; + +#define V4L2_CID_CAMERA_SET_SLOW_AE (V4L2_CID_PRIVATE_BASE+107) +enum v4l2_slow_ae_mode { + SLOW_AE_OFF, + SLOW_AE_ON, + SLOW_AE_MAX, +}; + +#define V4L2_CID_CAMERA_BATCH_REFLECTION (V4L2_CID_PRIVATE_BASE+108) +#define V4L2_CID_CAMERA_EXIF_ORIENTATION (V4L2_CID_PRIVATE_BASE+109) +#define V4L2_CID_CAMERA_GET_LUX (V4L2_CID_PRIVATE_BASE+110) + +/* s1_camera [ Defense process by ESD input ] */ +#define V4L2_CID_CAMERA_RESET (V4L2_CID_PRIVATE_BASE+111) +#define V4L2_CID_CAMERA_CHECK_DATALINE (V4L2_CID_PRIVATE_BASE+112) +#define V4L2_CID_CAMERA_CHECK_DATALINE_STOP (V4L2_CID_PRIVATE_BASE+113) + +#endif + +/* Modify NTTS1 */ +#if defined(CONFIG_ARIES_NTT) +#define V4L2_CID_CAMERA_AE_AWB_DISABLE_LOCK (V4L2_CID_PRIVATE_BASE+114) +#endif +#define V4L2_CID_CAMERA_THUMBNAIL_NULL (V4L2_CID_PRIVATE_BASE+115) +#define V4L2_CID_CAMERA_SENSOR_MODE (V4L2_CID_PRIVATE_BASE+116) +enum v4l2_sensor_mode { + SENSOR_CAMERA, + SENSOR_MOVIE, +}; + +enum stream_mode_t { + STREAM_MODE_CAM_OFF, + STREAM_MODE_CAM_ON, + STREAM_MODE_MOVIE_OFF, + STREAM_MODE_MOVIE_ON, + STREAM_MODE_WAIT_OFF +}; + +#define V4L2_CID_CAMERA_EXIF_EXPTIME (V4L2_CID_PRIVATE_BASE+117) +#define V4L2_CID_CAMERA_EXIF_FLASH (V4L2_CID_PRIVATE_BASE+118) +#define V4L2_CID_CAMERA_EXIF_ISO (V4L2_CID_PRIVATE_BASE+119) +#define V4L2_CID_CAMERA_EXIF_TV (V4L2_CID_PRIVATE_BASE+120) +#define V4L2_CID_CAMERA_EXIF_BV (V4L2_CID_PRIVATE_BASE+121) +#define V4L2_CID_CAMERA_EXIF_EBV (V4L2_CID_PRIVATE_BASE+122) +#define V4L2_CID_CAMERA_CHECK_ESD (V4L2_CID_PRIVATE_BASE+123) +#define V4L2_CID_CAMERA_APP_CHECK (V4L2_CID_PRIVATE_BASE+124) +#define V4L2_CID_CAMERA_CHECK_SENSOR_STATUS (V4L2_CID_PRIVATE_BASE+150) +#define V4L2_CID_CAMERA_DEFAULT_FOCUS_POSITION (V4L2_CID_PRIVATE_BASE+151) +#define V4L2_CID_CAMERA_BUSFREQ_LOCK (V4L2_CID_PRIVATE_BASE+125) +#define V4L2_CID_CAMERA_BUSFREQ_UNLOCK (V4L2_CID_PRIVATE_BASE+126) + +/* If you would like to control AE and AWB lock with signle command, + * use V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK above. + */ +#define V4L2_CID_CAMERA_AE_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE + 127) +enum v4l2_ae_lockunlock { + AE_UNLOCK = 0, + AE_LOCK, + AE_LOCK_MAX +}; + +#define V4L2_CID_CAMERA_AWB_LOCK_UNLOCK (V4L2_CID_PRIVATE_BASE + 128) +enum v4l2_awb_lockunlock { + AWB_UNLOCK = 0, + AWB_LOCK, + AWB_LOCK_MAX +}; + +#define V4L2_CID_CAMERA_SENSOR_OUTPUT_SIZE (V4L2_CID_PRIVATE_BASE + 129) +#define V4L2_CID_EMBEDDEDDATA_ENABLE (V4L2_CID_PRIVATE_BASE + 130) +#define V4L2_CID_CAMERA_JPEG_RESOLUTION (V4L2_CID_PRIVATE_BASE + 131) +#define V4L2_CID_CAMERA_FACE_ZOOM (V4L2_CID_PRIVATE_BASE + 132) +enum v4l2_face_zoom { + FACE_ZOOM_STOP = 0, + FACE_ZOOM_START +}; + +/* control for post processing block in ISP */ +#define V4L2_CID_CAMERA_SET_ODC (V4L2_CID_PRIVATE_BASE+127) +enum set_odc_mode { + CAMERA_ODC_ON, + CAMERA_ODC_OFF +}; + +#define V4L2_CID_CAMERA_SET_DIS (V4L2_CID_PRIVATE_BASE+128) +enum set_dis_mode { + CAMERA_DIS_ON, + CAMERA_DIS_OFF +}; + +#define V4L2_CID_CAMERA_SET_3DNR (V4L2_CID_PRIVATE_BASE+129) +enum set_3dnr_mode { + CAMERA_3DNR_ON, + CAMERA_3DNR_OFF +}; + +#define V4L2_CID_CAMERA_BRACKET (V4L2_CID_PRIVATE_BASE+134) +enum v4l2_face_bracket_mode { + BRACKET_MODE_OFF = 0, + BRACKET_MODE_AEB, + BRACKET_MODE_WBB, + BRACKET_MODE_MAX, +}; + +#define V4L2_CID_CAMERA_BRACKET_AEB (V4L2_CID_PRIVATE_BASE+135) +enum v4l2_face_bracket_aeb_value { + BRACKET_AEB_VALUE1 = 1, + BRACKET_AEB_VALUE2, + BRACKET_AEB_VALUE3, + BRACKET_AEB_VALUE4, + BRACKET_AEB_VALUE5, + BRACKET_AEB_VALUE6, +}; + +#define V4L2_CID_CAMERA_BRACKET_WBB (V4L2_CID_PRIVATE_BASE+136) +enum v4l2_face_bracket_wbb_value { + BRACKET_WBB_OFF = 0, + BRACKET_WBB_VALUE1 = 1, + BRACKET_WBB_VALUE2, + BRACKET_WBB_VALUE3, + BRACKET_WBB_VALUE4, + BRACKET_WBB_VALUE5, + BRACKET_WBB_VALUE6, +}; + +#define V4L2_CID_CAMERA_DRIVE_DIAL (V4L2_CID_PRIVATE_BASE+137) +enum v4l2_drive_dial { + DRIVEDIAL_SINGLE = 1, + DRIVEDIAL_BKT = 2, + DRIVEDIAL_CONTI_3 = 3, + DRIVEDIAL_CONTI_5 = 5, + DRIVEDIAL_CONTI_10 = 10, +}; + +enum v4l2_running_cap_mode { + RUNNING_MODE_SINGLE = 0, + RUNNING_MODE_CONTINUOUS, + RUNNING_MODE_BEST, + RUNNING_MODE_LOWLIGHT, + RUNNING_MODE_AE_BRACKET, + RUNNING_MODE_WB_BRACKET, + RUNNING_MODE_HDR, + RUNNING_MODE_BLINK, + RUNNING_MODE_RAW, + RUNNING_MODE_BURST, + RUNNING_MODE_MAX +}; + +enum v4l2_continuous_mode { + CONTINUOUS_MODE_OFF = 0, + CONTINUOUS_MODE_ON, + CONTINUOUS_MODE_MAX, +}; + +enum v4l2_continuous_fps { + MULTI_CAPTURE_FPS_1 = 0, + MULTI_CAPTURE_FPS_10, + MULTI_CAPTURE_FPS_5, + MULTI_CAPTURE_FPS_3, + MULTI_CAPTURE_FPS_MAX, +}; + +enum v4l2_burst_mode { + BURST_MODE_OFF = 0, + BURST_MODE_ON, +}; + +enum v4l2_best_mode { + BEST_MODE_OFF = 0, + BEST_MODE_ON, + BEST_MODE_MAX,}; + +enum v4l2_lowlight_mode { + LOWLIGHT_MODE_OFF = 0, + LOWLIGHT_MODE_ON, + LOWLIGHT_MODE_MAX,}; + +#define V4L2_CID_CAMERA_FD_EYE_BLINK_RESULT (V4L2_CID_PRIVATE_BASE+138) + +#define V4L2_CID_CAMERA_OPTICAL_ZOOM_STEP (V4L2_CID_PRIVATE_BASE + 139) +#define V4L2_CID_CAMERA_OPTICAL_ZOOM_CTRL (V4L2_CID_PRIVATE_BASE + 140) +enum v4l2_optical_zoom_ctrl { + V4L2_OPTICAL_ZOOM_STOP, + V4L2_OPTICAL_ZOOM_TELE_START, + V4L2_OPTICAL_ZOOM_WIDE_START, + V4L2_OPTICAL_ZOOM_SLOW_TELE_START, + V4L2_OPTICAL_ZOOM_SLOW_WIDE_START, +}; + +#define V4L2_CID_CAMERA_LDC (V4L2_CID_PRIVATE_BASE+142) +enum set_LDC_mode { + LDC_SET_OFF = 0, + LDC_SET_ON = 1, +}; + +#define V4L2_CID_CAMERA_LSC (V4L2_CID_PRIVATE_BASE+143) +enum set_LSC_mode { + LSC_SET_OFF = 0, + LSC_SET_ON = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_OIS (V4L2_CID_PRIVATE_BASE+147) +enum set_Factory_OIS { + FACTORY_OIS_RETURN_TO_CENTER = 0, + FACTORY_OIS_RUN = 1, + FACTORY_OIS_START = 2, + FACTORY_OIS_STOP = 3, + FACTORY_OIS_MODE_ON = 4, + FACTORY_OIS_MODE_OFF = 5, + FACTORY_OIS_LOG = 6, + FACTORY_OIS_ON = 7, +}; + +#define V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MIN \ + (V4L2_CID_PRIVATE_BASE+148) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_RANGE_CHECK_DATA_MAX \ + (V4L2_CID_PRIVATE_BASE+149) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MIN \ + (V4L2_CID_PRIVATE_BASE+152) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_SLOPE_CHECK_DATA_MAX \ + (V4L2_CID_PRIVATE_BASE+153) +#define V4L2_CID_CAMERA_FACTORY_ZOOM_STEP (V4L2_CID_PRIVATE_BASE+154) +#define V4L2_CID_CAMERA_FACTORY_ZOOM (V4L2_CID_PRIVATE_BASE+155) +enum set_Factory_Zoom { + FACTORY_ZOOM_MOVE_STEP = 0, + FACTORY_ZOOM_RANGE_CHECK_START = 1, + FACTORY_ZOOM_RANGE_CHECK_STOP = 2, + FACTORY_ZOOM_SLOPE_CHECK_START = 3, + FACTORY_ZOOM_SLOPE_CHECK_STOP = 4, + FACTORY_ZOOM_SET_RANGE_CHECK_DATA = 5, + FACTORY_ZOOM_SET_SLOPE_CHECK_DATA = 6, + FACTORY_ZOOM_STEP_TELE = 7, + FACTORY_ZOOM_STEP_WIDE = 8, + FACTORY_ZOOM_MOVE_END_CHECK = 9, +}; + +#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MIN \ + (V4L2_CID_PRIVATE_BASE+156) +#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_MAX \ + (V4L2_CID_PRIVATE_BASE+157) +#define V4L2_CID_CAMERA_FACTORY_PUNT_RANGE_DATA_NUM \ + (V4L2_CID_PRIVATE_BASE+158) +#define V4L2_CID_CAMERA_FACTORY_PUNT (V4L2_CID_PRIVATE_BASE+159) +enum set_Factory_Punt { + FACTORY_PUNT_RANGE_START = 0, + FACTORY_PUNT_RANGE_STOP = 1, + FACTORY_PUNT_SHORT_SCAN_DATA = 2, + FACTORY_PUNT_SHORT_SCAN_START = 3, + FACTORY_PUNT_SHORT_SCAN_STOP = 4, + FACTORY_PUNT_LONG_SCAN_DATA = 5, + FACTORY_PUNT_LONG_SCAN_START = 6, + FACTORY_PUNT_LONG_SCAN_STOP = 7, + FACTORY_PUNT_LOG = 8, + FACTORY_PUNT_SET_RANGE_DATA = 9, + FACTORY_PUNT_EEP_WRITE = 10, +}; + +#define V4L2_CID_CAMERA_FACTORY_FAIL_STOP (V4L2_CID_PRIVATE_BASE+160) +enum set_Factory_Fail_Stop { + FACTORY_FAIL_STOP_ON = 0, + FACTORY_FAIL_STOP_OFF = 1, + FACTORY_FAIL_STOP_RUN = 2, + FACTORY_FAIL_STOP_STOP = 3, +}; + +#define V4L2_CID_CAMERA_FACTORY_NODEFOCUS (V4L2_CID_PRIVATE_BASE+161) +enum set_Factory_NoDeFocus { + FACTORY_NODEFOCUSYES_ON = 0, + FACTORY_NODEFOCUSYES_OFF = 1, + FACTORY_NODEFOCUSYES_RUN = 2, + FACTORY_NODEFOCUSYES_STOP = 3, +}; + +#define V4L2_CID_CAMERA_FACTORY_INTERPOLATION (V4L2_CID_PRIVATE_BASE+162) +enum set_Factory_Interpolation { + FACTORY_INTERPOLATION_USE = 0, + FACTORY_INTERPOLATION_RELEASE = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_DOWN_RESULT (V4L2_CID_PRIVATE_BASE+163) +#define V4L2_CID_CAMERA_FACTORY_END_RESULT (V4L2_CID_PRIVATE_BASE+164) +#define V4L2_CID_CAMERA_FACTORY_COMMON (V4L2_CID_PRIVATE_BASE+165) +enum set_Factory_Common { + FACTORY_FIRMWARE_DOWNLOAD = 0, + FACTORY_DOWNLOAD_CHECK = 1, + FACTORY_END_CHECK = 2, + FACTORY_COMMON_SET_FOCUS_ZONE_MACRO = 3, + FACTORY_FPS30_ON = 4, + FACTORY_FPS30_OFF = 5, +}; + +#define V4L2_CID_CAMERA_FACTORY_VIB (V4L2_CID_PRIVATE_BASE+166) +enum set_Factory_Vib { + FACTORY_VIB_START = 0, + FACTORY_VIB_STOP = 1, + FACTORY_VIB_LOG = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_GYRO (V4L2_CID_PRIVATE_BASE+167) +enum set_Factory_Gyro { + FACTORY_GYRO_START = 0, + FACTORY_GYRO_STOP = 1, + FACTORY_GYRO_LOG = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_BACKLASH (V4L2_CID_PRIVATE_BASE+168) +enum set_Factory_Backlash { + FACTORY_BACKLASH_INPUT = 0, + FACTORY_BACKLASH_MAX_THR = 1, + FACTORY_BACKLASH_WIDE_RUN = 2, + FACTORY_BACKLASH_LOG = 3, +}; + +#define V4L2_CID_CAMERA_FACTORY_AF_STEP_SET (V4L2_CID_PRIVATE_BASE+169) +#define V4L2_CID_CAMERA_FACTORY_AF_POSITION (V4L2_CID_PRIVATE_BASE+170) +#define V4L2_CID_CAMERA_FACTORY_AF_INT_RESULT (V4L2_CID_PRIVATE_BASE+171) +#define V4L2_CID_CAMERA_FACTORY_AF (V4L2_CID_PRIVATE_BASE+172) +enum set_Factory_AF { + FACTORY_AF_LOCK_ON_SET = 0, + FACTORY_AF_LOCK_OFF_SET = 1, + FACTORY_AF_MOVE = 2, + FACTORY_AF_STEP_LOG = 3, + FACTORY_AF_LOCK_START = 4, + FACTORY_AF_LOCK_STOP = 5, + FACTORY_AF_FOCUS_LOG = 6, + FACTORY_AF_INT_SET = 7, + FACTORY_AF_SCAN_LIMIT_START = 8, + FACTORY_AF_SCAN_LIMIT_STOP = 10, + FACTORY_AF_SCAN_RANGE_START = 11, + FACTORY_AF_SCAN_RANGE_STOP = 12, + FACTORY_AF_STEP_SAVE = 13, + FACTORY_AF_LED_END_CHECK = 14, + FACTORY_AF_LED_LOG = 15, + FACTORY_AF_MOVE_END_CHECK = 16, + FACTORY_AF_SCAN_END_CHECK = 17, +}; + +#define V4L2_CID_CAMERA_FACTORY_DEFOCUS_WIDE (V4L2_CID_PRIVATE_BASE+173) +#define V4L2_CID_CAMERA_FACTORY_DEFOCUS_TELE (V4L2_CID_PRIVATE_BASE+174) +#define V4L2_CID_CAMERA_FACTORY_DEFOCUS (V4L2_CID_PRIVATE_BASE+175) +enum set_Factory_DeFocus { + FACTORY_DEFOCUS_RUN = 0, + FACTORY_DEFOCUS_STOP = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_RESOL_CAP (V4L2_CID_PRIVATE_BASE+176) +enum set_Factory_Resol_Cap { + FACTORY_CAP_COMP_ON = 0, + FACTORY_CAP_COMP_OFF = 1, + FACTORY_CAP_BARREL_ON = 2, + FACTORY_CAP_BARREL_OFF = 3, + FACTORY_CAP_BARREL_START = 4, + FACTORY_CAP_BARREL_STOP = 5, + FACTORY_CAP_COMP_START = 6, + FACTORY_CAP_COMP_STOP = 7, +}; + +#define V4L2_CID_CAMERA_SET_G_VALUE (V4L2_CID_PRIVATE_BASE + 177) +#define V4L2_CID_CAMERA_SET_B_VALUE (V4L2_CID_PRIVATE_BASE + 178) +#define V4L2_CID_CAMERA_SET_A_VALUE (V4L2_CID_PRIVATE_BASE + 179) +#define V4L2_CID_CAMERA_SET_M_VALUE (V4L2_CID_PRIVATE_BASE + 180) +#define V4L2_CID_CAMERA_SET_GBAM (V4L2_CID_PRIVATE_BASE + 181) +#define V4L2_CID_CAMERA_SET_K_VALUE (V4L2_CID_PRIVATE_BASE + 182) +#define V4L2_CID_CAMERA_SET_FLASH_EVC_STEP (V4L2_CID_PRIVATE_BASE + 183) + +#define V4L2_CID_CAMERA_APERTURE_CMD (V4L2_CID_PRIVATE_BASE+184) +enum set_Factory_Aperture_Cmd { + FACTORY_CMD_PREVIEW = 0, + FACTORY_CMD_CAPTURE = 1, +}; + +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MIN (V4L2_CID_PRIVATE_BASE+185) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_MAX (V4L2_CID_PRIVATE_BASE+186) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MIN (V4L2_CID_PRIVATE_BASE+187) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_Y_MAX (V4L2_CID_PRIVATE_BASE+188) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_X_GAIN \ + (V4L2_CID_PRIVATE_BASE+189) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_X \ + (V4L2_CID_PRIVATE_BASE+190) +#define V4L2_CID_CAMERA_FACTORY_OIS_RANGE_DATA_PEAK_Y \ + (V4L2_CID_PRIVATE_BASE+191) + +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MIN (V4L2_CID_PRIVATE_BASE+192) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_X_MAX (V4L2_CID_PRIVATE_BASE+193) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MIN (V4L2_CID_PRIVATE_BASE+194) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_Y_MAX (V4L2_CID_PRIVATE_BASE+195) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_X \ + (V4L2_CID_PRIVATE_BASE+196) +#define V4L2_CID_CAMERA_FACTORY_VIB_RANGE_DATA_PEAK_Y \ + (V4L2_CID_PRIVATE_BASE+197) + +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MIN \ + (V4L2_CID_PRIVATE_BASE+198) +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_X_MAX \ + (V4L2_CID_PRIVATE_BASE+199) +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MIN \ + (V4L2_CID_PRIVATE_BASE+200) +#define V4L2_CID_CAMERA_FACTORY_GYRO_RANGE_DATA_Y_MAX \ + (V4L2_CID_PRIVATE_BASE+202) + +#define V4L2_CID_CAMERA_FACTORY_TEST_NUMBER (V4L2_CID_PRIVATE_BASE+203) + +#define V4L2_CID_CAMERA_FACTORY_BACKLASH_COUNT (V4L2_CID_PRIVATE_BASE+204) +#define V4L2_CID_CAMERA_FACTORY_BACKLASH_MAXTHRESHOLD \ + (V4L2_CID_PRIVATE_BASE+205) + +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_CTRL (V4L2_CID_PRIVATE_BASE + 206) +enum set_Factory_Cap_Ctrl { + FACTORY_STILL_CAP_NORMAL = 0, + FACTORY_STILL_CAP_DUALCAP = 1, + FACTORY_DUAL_CAP_ON = 2, + FACTORY_DUAL_CAP_OFF = 3, +}; + +#define V4L2_CID_CAMERA_DUAL_POSTVIEW (V4L2_CID_PRIVATE_BASE + 207) +#define V4L2_CID_CAMERA_DUAL_CAPTURE (V4L2_CID_PRIVATE_BASE + 208) +#define V4L2_CID_CAMERA_SET_DUAL_CAPTURE (V4L2_CID_PRIVATE_BASE + 209) +#define V4L2_CID_CAMERA_DUAL_CAPTURE_MODE (V4L2_CID_PRIVATE_BASE + 210) + +#define V4L2_CID_CAMERA_FOCUS_AREA_MODE (V4L2_CID_PRIVATE_BASE + 211) +enum set_fouce_area { + V4L2_FOCUS_AREA_CENTER = 0, + V4L2_FOCUS_AREA_MULTI = 1, + V4L2_FOCUS_AREA_SMART_TOUCH = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MIN (V4L2_CID_PRIVATE_BASE+212) +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_LIMIT_MAX (V4L2_CID_PRIVATE_BASE+213) +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MIN (V4L2_CID_PRIVATE_BASE+214) +#define V4L2_CID_CAMERA_FACTORY_AF_SCAN_RANGE_MAX (V4L2_CID_PRIVATE_BASE+215) +#define V4L2_CID_CAM_APERTURE_PREVIEW (V4L2_CID_PRIVATE_BASE+216) +#define V4L2_CID_CAM_APERTURE_CAPTURE (V4L2_CID_PRIVATE_BASE+217) + +#define V4L2_CID_CAMERA_FACTORY_AF_ZONE (V4L2_CID_PRIVATE_BASE+218) +enum set_Factory_AFZone_Cmd { + FACTORY_AFZONE_NORMAL = 0, + FACTORY_AFZONE_MACRO, + FACTORY_AFZONE_AUTO, +}; + +#define V4L2_CID_CAMERA_FACTORY_OIS_SHIFT (V4L2_CID_PRIVATE_BASE+219) +#define V4L2_CID_CAMERA_FACTORY_FLICKER (V4L2_CID_PRIVATE_BASE+220) +enum set_Factory_Flicker_Cmd { + FACTORY_FLICKER_AUTO = 0, + FACTORY_FLICKER_50HZ, + FACTORY_FLICKER_60HZ, + FACTORY_FLICKER_50_60, + FACTORY_FLICKER_OFF, +}; + +#define V4L2_CID_CAMERA_FACTORY_AF_LENS (V4L2_CID_PRIVATE_BASE+221) +enum set_Factory_AFLENS_Cmd { + FACTORY_AFLENS_OPEN = 0, + FACTORY_AFLENS_CLOSE, +}; + +#define V4L2_CID_CAMERA_FACTORY_LV_TARGET (V4L2_CID_PRIVATE_BASE+222) + +#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MIN (V4L2_CID_PRIVATE_BASE+223) +#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS_RANGE_MAX (V4L2_CID_PRIVATE_BASE+224) +#define V4L2_CID_CAMERA_FACTORY_ADJ_IRIS (V4L2_CID_PRIVATE_BASE+225) +enum set_Factory_Adj_IRIS_Cmd { + FACTORY_ADJ_IRIS_RUN = 0, + FACTORY_ADJ_IRIS_STOP, + FACTORY_ADJ_IRIS_END_CHECK, + FACTORY_ADJ_IRIS_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE+226) +#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE+227) +#define V4L2_CID_CAMERA_FACTORY_ADJ_GAIN_LIVEVIEW (V4L2_CID_PRIVATE_BASE+228) +enum set_Factory_Adj_Gain_LiveView_Cmd { + FACTORY_ADJ_GAIN_LIVEVIEW_RUN = 0, + FACTORY_ADJ_GAIN_LIVEVIEW_STOP, + FACTORY_ADJ_GAIN_LIVEVIEW_END_CHECK, + FACTORY_ADJ_GAIN_LIVEVIEW_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_IRIS_NUM (V4L2_CID_PRIVATE_BASE+229) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SET_IRIS (V4L2_CID_PRIVATE_BASE+230) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_ISO (V4L2_CID_PRIVATE_BASE+231) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_RANGE (V4L2_CID_PRIVATE_BASE+232) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_X (V4L2_CID_PRIVATE_BASE+233) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE_SPEEDTIME_Y (V4L2_CID_PRIVATE_BASE+234) +#define V4L2_CID_CAMERA_FACTORY_SH_CLOSE (V4L2_CID_PRIVATE_BASE+235) +enum set_Factory_SH_Close_Cmd { + FACTORY_SH_CLOSE_RUN = 0, + FACTORY_SH_CLOSE_STOP, + FACTORY_SH_CLOSE_END_CHECK, + FACTORY_SH_CLOSE_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE+236) +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE+237) +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN (V4L2_CID_PRIVATE_BASE+238) +enum set_Factory_Capture_Gain_Cmd { + FACTORY_CAPTURE_GAIN_RUN = 0, + FACTORY_CAPTURE_GAIN_STOP, + FACTORY_CAPTURE_GAIN_END_CHECK, + FACTORY_CAPTURE_GAIN_LOG, +}; + +#define V4L2_CID_CAMERA_FACTORY_LSC_TABLE (V4L2_CID_PRIVATE_BASE+239) +#define V4L2_CID_CAMERA_FACTORY_LSC_REFERENCE (V4L2_CID_PRIVATE_BASE+240) + +#define V4L2_CID_CAMERA_FACTORY_PUNT_SHORT_SCAN_DATA (V4L2_CID_PRIVATE_BASE+241) +#define V4L2_CID_CAMERA_FACTORY_PUNT_LONG_SCAN_DATA (V4L2_CID_PRIVATE_BASE+242) + +#define V4L2_CID_CAMERA_PASM_MODE (V4L2_CID_PRIVATE_BASE + 243) +enum set_camera_mode_Cmd { + MODE_SMART_AUTO = 0, + MODE_PROGRAM, + MODE_A, + MODE_S, + MODE_M, + MODE_VIDEO, + MODE_BACKGROUND_BLUR, + MODE_HIGH_SPEED, + MODE_LIGHT_TRAIL_SHOT, + MODE_WATERFALL, + MODE_SILHOUETTE, + MODE_SUNSET, + MODE_CLOSE_UP, + MODE_FIREWORKS, + MODE_CROSS_FILTER, + MODE_BACKLIGHT, + MODE_BLUE_SKY, + MODE_NATURAL_GREEN, + MODE_BEST_GROUP_POSE, + MODE_FOOD, + MODE_START_FILTER, + MODE_MOVING_SHOT, +}; + +#define V4L2_CID_CAMERA_SHUTTER_SPEED (V4L2_CID_PRIVATE_BASE + 244) +#define V4L2_CID_CAMERA_F_NUMBER (V4L2_CID_PRIVATE_BASE + 245) + +#define V4L2_CID_CAMERA_IMAGE_STABILIZER (V4L2_CID_PRIVATE_BASE + 246) +enum set_Image_Stabilizer { + V4L2_IMAGE_STABILIZER_OFF = 0, + V4L2_IMAGE_STABILIZER_OIS = 1, + V4L2_IMAGE_STABILIZER_DUALIS = 2, +}; + +#define V4L2_CID_CAMERA_IS_OIS_MODE (V4L2_CID_PRIVATE_BASE + 247) +enum set_IS_OIS_mode { + V4L2_IS_OIS_NONE = 0, + V4L2_IS_OIS_MOVIE = 1, + V4L2_IS_OIS_STILL = 2, + V4L2_IS_OIS_MULTI = 3, + V4L2_IS_OIS_VSS = 4, +}; + +#define V4L2_CID_CAMERA_FACTORY_AE_TARGET (V4L2_CID_PRIVATE_BASE + 248) + +#define V4L2_CID_CAMERA_AV (V4L2_CID_PRIVATE_BASE + 249) +#define V4L2_CID_CAMERA_TV (V4L2_CID_PRIVATE_BASE + 250) +#define V4L2_CID_CAMERA_SV (V4L2_CID_PRIVATE_BASE + 251) +#define V4L2_CID_CAMERA_EV (V4L2_CID_PRIVATE_BASE + 252) + +#define V4L2_CID_CAMERA_SCENE_SUB_MODE (V4L2_CID_PRIVATE_BASE + 253) + +#define V4L2_CID_CAMERA_WB_CUSTOM_X (V4L2_CID_PRIVATE_BASE + 254) +#define V4L2_CID_CAMERA_WB_CUSTOM_Y (V4L2_CID_PRIVATE_BASE + 255) +#define V4L2_CID_CAMERA_WB_CUSTOM_VALUE (V4L2_CID_PRIVATE_BASE + 256) + +#define V4L2_CID_CAMERA_RED_EYE_FIX_RESULT (V4L2_CID_PRIVATE_BASE + 257) +#define V4L2_CID_CAMERA_FACTORY_FLASH (V4L2_CID_PRIVATE_BASE + 258) +enum set_Factory_Flash_Cmd { + FACTORY_FLASH_STROBE_CHECK_ON = 0, + FACTORY_FLASH_STROBE_CHECK_OFF = 1, + FACTORY_FLASH_CHARGE = 2, + FACTORY_FLASH_LOG = 3, + FACTORY_FLASH_CHARGE_END_CHECK = 4, + FACTORY_FLASH_STROBE_CHARGE_END_CHECK = 5, + FACTORY_FLASH_WB_LOG = 6, + FACTORY_ADJ_FLASH_WB_LOG = 7, + FACTORY_ADJ_FLASH_WB_END_CHECK = 8, +}; + +#define V4L2_CID_CAMERA_FACTORY_WB (V4L2_CID_PRIVATE_BASE + 259) +enum set_Factory_WB_Cmd { + FACTORY_WB_INDOOR_RUN = 0, + FACTORY_WB_INDOOR_END_CHECK = 1, + FACTORY_WB_OUTDOOR_RUN = 2, + FACTORY_WB_OUTDOOR_END_CHECK = 3, + FACTORY_WB_LOG = 4, +}; + +#define V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_X (V4L2_CID_PRIVATE_BASE + 260) +#define V4L2_CID_CAMERA_FACTORY_FLASH_RANGE_Y (V4L2_CID_PRIVATE_BASE + 261) + +#define V4L2_CID_CAMERA_FACTORY_WB_IN_RG_VALUE (V4L2_CID_PRIVATE_BASE + 262) +#define V4L2_CID_CAMERA_FACTORY_WB_IN_BG_VALUE (V4L2_CID_PRIVATE_BASE + 263) +#define V4L2_CID_CAMERA_FACTORY_WB_OUT_RG_VALUE (V4L2_CID_PRIVATE_BASE + 264) +#define V4L2_CID_CAMERA_FACTORY_WB_OUT_BG_VALUE (V4L2_CID_PRIVATE_BASE + 265) + +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_X \ + (V4L2_CID_PRIVATE_BASE + 266) +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_X \ + (V4L2_CID_PRIVATE_BASE + 267) +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_START_Y \ + (V4L2_CID_PRIVATE_BASE + 268) +#define V4L2_CID_CAMERA_FACTORY_AFLED_RANGE_DATA_END_Y \ + (V4L2_CID_PRIVATE_BASE + 269) + +#define V4L2_CID_CAMERA_FACTORY_AF_LED_TIME (V4L2_CID_PRIVATE_BASE + 270) + +#define V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MIN (V4L2_CID_PRIVATE_BASE + 271) +#define V4L2_CID_CAMERA_FACTORY_AF_DIFF_CHECK_MAX (V4L2_CID_PRIVATE_BASE + 272) + +#define V4L2_CID_CAMERA_FACTORY_DEFECTPIXEL (V4L2_CID_PRIVATE_BASE + 273) +enum set_Factory_DefectPixel_Cmd { + FACTORY_DEFECTPIXEL_SCENARIO_6 = 0, + FACTORY_DEFECTPIXEL_RUN, + FACTORY_DEFECTPIXEL_END_CHECK, + FACTORY_DEFECTPIXEL_LOG, + FACTORY_DEFECTPIXEL_CID_1, + FACTORY_DEFECTPIXEL_CID_2, + FACTORY_DEFECTPIXEL_CID_3, + FACTORY_DEFECTPIXEL_WRITE_BLACK, + FACTORY_DEFECTPIXEL_WRITE_WHITE, + FACTORY_DEFECTPIXEL_CID_WRITE, + FACTORY_DEFECTPIXEL_FLASH_MERGE, + FACTORY_DEFECTPIXEL_DOT_WRITE_CHECK, +}; + +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_CAP (V4L2_CID_PRIVATE_BASE + 274) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR0 (V4L2_CID_PRIVATE_BASE + 275) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1 (V4L2_CID_PRIVATE_BASE + 276) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR2 (V4L2_CID_PRIVATE_BASE + 277) +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR_HS (V4L2_CID_PRIVATE_BASE + 278) + +#define V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MIN (V4L2_CID_PRIVATE_BASE + 279) +#define V4L2_CID_CAMERA_FACTORY_AF_LED_LV_MAX (V4L2_CID_PRIVATE_BASE + 280) + +#define V4L2_CID_CAMERA_FACTORY_CAM_SYS_MODE (V4L2_CID_PRIVATE_BASE + 281) +enum set_Factory_Sysmode_Cmd { + FACTORY_SYSMODE_CAPTURE = 0, + FACTORY_SYSMODE_MONITOR = 1, + FACTORY_SYSMODE_PARAM = 2, +}; + +#define V4L2_CID_CAMERA_FACTORY_ISP_FW_CHECK (V4L2_CID_PRIVATE_BASE + 282) +#define V4L2_CID_CAMERA_FACTORY_OIS_VER_CHECK (V4L2_CID_PRIVATE_BASE + 283) + +#define V4L2_CID_CAMERA_SMART_SCENE_DETECT (V4L2_CID_PRIVATE_BASE+284) +enum set_smartscenedetect_mode { + SMART_SCENE_DETECT_OFF = 0, + SMART_SCENE_DETECT_ON = 1, +}; +#define V4L2_CID_CAMERA_SMART_MOVIE_RECORDING (V4L2_CID_PRIVATE_BASE+285) +#define V4L2_CID_CAMERA_SMART_AUTO_S1_PUSH (V4L2_CID_PRIVATE_BASE+286) + +#define V4L2_CID_CAMERA_FACTORY_WB_RANGE_FLASH_WRITE \ + (V4L2_CID_PRIVATE_BASE + 287) + +#define V4L2_CID_CAMERA_FACTORY_FLASH_CHR_CHK_TM \ + (V4L2_CID_PRIVATE_BASE + 288) + +#define V4L2_CID_CAMERA_EXIF_AV (V4L2_CID_PRIVATE_BASE + 289) +#define V4L2_CID_CAMERA_FACE_DETECT_NUMBER (V4L2_CID_PRIVATE_BASE+290) +#define V4L2_CID_CAMERA_EXIF_FL (V4L2_CID_PRIVATE_BASE + 291) + +#define V4L2_CID_CAMERA_SMART_ZOOM (V4L2_CID_PRIVATE_BASE + 292) +enum set_Smart_Zoom { + V4L2_SMART_ZOOM_OFF = 0, + V4L2_SMART_ZOOM_ON = 1, +}; + +#define V4L2_CID_CAMERA_CAF (V4L2_CID_PRIVATE_BASE + 293) + +#define V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_MARK \ + (V4L2_CID_PRIVATE_BASE + 294) +#define V4L2_CID_CAMERA_FACTORY_LIVEVIEW_OFFSET_VAL \ + (V4L2_CID_PRIVATE_BASE + 295) + +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_MARK \ + (V4L2_CID_PRIVATE_BASE + 296) +#define V4L2_CID_CAMERA_FACTORY_CAPTURE_GAIN_OFFSET_VAL \ + (V4L2_CID_PRIVATE_BASE + 297) + +#define V4L2_CID_CAMERA_FACTORY_WB_RANGE (V4L2_CID_PRIVATE_BASE + 298) + +#define V4L2_CID_CAMERA_LV (V4L2_CID_PRIVATE_BASE + 299) + +#define V4L2_CID_PHYSICAL_ROTATION (V4L2_CID_PRIVATE_BASE + 300) + +#define V4L2_CID_CAMERA_FOCUS_RANGE (V4L2_CID_PRIVATE_BASE + 301) +enum set_fouce_range { + V4L2_FOCUS_RANGE_AUTO = 0, + V4L2_FOCUS_RANGE_MACRO = 1, + V4L2_FOCUS_RANGE_AUTO_MACRO = 2, +}; + +#define V4L2_CID_CAMERA_TIME_INFO (V4L2_CID_PRIVATE_BASE + 302) + +#define V4L2_CID_CAMERA_AF_LED (V4L2_CID_PRIVATE_BASE + 303) +enum set_AF_LED { + V4L2_AF_LED_OFF = 0, + V4L2_AF_LED_ON = 1, +}; + +#define V4L2_CID_CAMERA_LENS_TIMER (V4L2_CID_PRIVATE_BASE + 304) + +#define V4L2_CID_CAMERA_FLASH_BATT_INFO (V4L2_CID_PRIVATE_BASE + 305) +enum set_FLASH_BATT_INFO { + V4L2_FLASH_NORMAL_BATT = 0, + V4L2_FLASH_LOW_BATT = 1, +}; + +#define V4L2_CID_CAMERA_STREAM_PART2 (V4L2_CID_PRIVATE_BASE + 306) + +#define V4L2_CID_CAMERA_WIDGET_MODE_LEVEL (V4L2_CID_PRIVATE_BASE+307) +enum v4l2_widget_mode_level { + V4L2_WIDGET_MODE_LEVEL_1 = 1, + V4L2_WIDGET_MODE_LEVEL_2 = 2, + V4L2_WIDGET_MODE_LEVEL_3 = 3, +}; + +#define V4L2_CID_CAMERA_SMART_READ1 (V4L2_CID_PRIVATE_BASE + 308) +#define V4L2_CID_CAMERA_SMART_READ2 (V4L2_CID_PRIVATE_BASE + 309) + +#define V4L2_CID_CAMERA_PREVIEW_WIDTH (V4L2_CID_PRIVATE_BASE + 310) +#define V4L2_CID_CAMERA_PREVIEW_HEIGHT (V4L2_CID_PRIVATE_BASE + 311) +#define V4L2_CID_CAMERA_PREVIEW_SIZE (V4L2_CID_PRIVATE_BASE + 312) + +#define V4L2_CID_CAMERA_WARNING_CONDITION (V4L2_CID_PRIVATE_BASE + 313) +#define V4L2_CID_CAMERA_EXIF_FL_35mm (V4L2_CID_PRIVATE_BASE + 314) + +#define V4L2_CID_CAMERA_LENS_STATUS (V4L2_CID_PRIVATE_BASE + 315) +#define V4L2_CID_CAMERA_HOLD_LENS (V4L2_CID_PRIVATE_BASE + 316) + +/* Pixel format FOURCC depth Description */ +enum v4l2_pix_format_mode { + V4L2_PIX_FMT_MODE_PREVIEW, + V4L2_PIX_FMT_MODE_CAPTURE, + V4L2_PIX_FMT_MODE_HDR, + V4L2_PIX_FMT_MODE_VT_MIRROR, + V4L2_PIX_FMT_MODE_VT_NONMIRROR, +}; + +#define V4L2_CID_SET_CONTINUE_FPS (V4L2_CID_PRIVATE_BASE + 500) +#define V4L2_CID_CONTINUESHOT_PROC (V4L2_CID_PRIVATE_BASE + 501) +enum v4l2_continuecshot_proc_state { + V4L2_INT_STATE_FRAME_SYNC = 0, + V4L2_INT_STATE_CAPTURE_SYNC, + V4L2_INT_STATE_CONTINUE_CANCEL, + V4L2_INT_STATE_CONTINUE_END, + V4L2_INT_STATE_START_CAPTURE, +}; + +#define V4L2_CID_CAMERA_GET_MODE (V4L2_CID_PRIVATE_BASE + 502) + +#define V4L2_CID_CAMERA_FACTORY_SEND_SETTING \ + (V4L2_CID_PRIVATE_BASE + 503) +#define V4L2_CID_CAMERA_FACTORY_SEND_VALUE \ + (V4L2_CID_PRIVATE_BASE + 504) + +#define V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MIN \ + (V4L2_CID_PRIVATE_BASE + 505) +#define V4L2_CID_CAMERA_FACTORY_TILT_SCAN_MAX \ + (V4L2_CID_PRIVATE_BASE + 506) +#define V4L2_CID_CAMERA_FACTORY_TILT_FIELD \ + (V4L2_CID_PRIVATE_BASE + 507) +#define V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE + 508) +#define V4L2_CID_CAMERA_FACTORY_TILT_AF_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE + 509) +#define V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MIN \ + (V4L2_CID_PRIVATE_BASE + 510) +#define V4L2_CID_CAMERA_FACTORY_TILT_DIFF_RANGE_MAX \ + (V4L2_CID_PRIVATE_BASE + 511) + +#define V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MIN \ + (V4L2_CID_PRIVATE_BASE + 512) +#define V4L2_CID_CAMERA_FACTORY_IR_R_GAIN_MAX \ + (V4L2_CID_PRIVATE_BASE + 513) +#define V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MIN \ + (V4L2_CID_PRIVATE_BASE + 514) +#define V4L2_CID_CAMERA_FACTORY_IR_B_GAIN_MAX \ + (V4L2_CID_PRIVATE_BASE + 515) + +#define V4L2_CID_CAMERA_FACTORY_FLASH_MAN_CHARGE \ + (V4L2_CID_PRIVATE_BASE + 516) +#define V4L2_CID_CAMERA_FACTORY_FLASH_MAN_EN \ + (V4L2_CID_PRIVATE_BASE + 517) + +#define V4L2_CID_CAMERA_FACTORY_SEND_WORD_VALUE \ + (V4L2_CID_PRIVATE_BASE + 518) +#define V4L2_CID_CAMERA_FACTORY_SEND_LONG_VALUE \ + (V4L2_CID_PRIVATE_BASE + 519) + +#define V4L2_CID_CAMERA_FACTORY_DFPX_NLV_DR1_HD \ + (V4L2_CID_PRIVATE_BASE + 520) + +#define V4L2_CID_BURSTSHOT_PROC (V4L2_CID_PRIVATE_BASE + 521) +enum v4l2_burst_proc_state { + V4L2_INT_STATE_BURST_START = 0, + V4L2_INT_STATE_BURST_SYNC, + V4L2_INT_STATE_BURST_STOP, +}; + +#define V4L2_CID_CAMERA_FACTORY_TILT \ + (V4L2_CID_PRIVATE_BASE + 522) +enum set_Factory_Tilt { + FACTORY_TILT_ONE_SCRIPT_RUN = 0, + FACTORY_TILT_ONE_SCRIPT_DISP1, + FACTORY_TILT_ONE_SCRIPT_DISP2, + FACTORY_TILT_ONE_SCRIPT_DISP3, + FACTORY_TILT_ONE_SCRIPT_DISP4, + FACTORY_TILT_ONE_SCRIPT_DISP5, +}; + +#define V4L2_CID_CAMERA_FACTORY_IR_CHECK \ + (V4L2_CID_PRIVATE_BASE + 523) +enum set_Factory_IR_Check { + FACTORY_IR_CHECK_LOG = 0, +}; + +#define V4L2_CID_BURSTSHOT_SET_POSTVIEW_SIZE (V4L2_CID_PRIVATE_BASE + 524) + +#define V4L2_CID_BURSTSHOT_SET_SNAPSHOT_SIZE (V4L2_CID_PRIVATE_BASE + 525) + +/* ISP DEBUG CODE */ +#define V4L2_CID_ISP_DEBUG_READ (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 1) +#define V4L2_CID_ISP_DEBUG_WRITE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 2) +#define V4L2_CID_ISP_DEBUG_READ_MEM (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 3) +#define V4L2_CID_ISP_DEBUG_WRITE_MEM (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 4) +#define V4L2_CID_ISP_DEBUG_READ_FILE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 5) +#define V4L2_CID_ISP_DEBUG_WRITE_FILE (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 6) +#define V4L2_CID_ISP_DEBUG_LOGV (V4L2_CID_FIMC_IS_ISP_DBG_BASE + 7) + +/* 12 Y/CbCr 4:2:0 64x32 macroblocks */ +#define V4L2_PIX_FMT_NV12T v4l2_fourcc('T', 'V', '1', '2') +#define V4L2_PIX_FMT_NV21T v4l2_fourcc('T', 'V', '2', '1') +#define V4L2_PIX_FMT_INTERLEAVED v4l2_fourcc('I', 'T', 'L', 'V') + +/* + * * V4L2 extention for digital camera + * */ +/* Strobe flash light */ +enum v4l2_strobe_control { + /* turn off the flash light */ + V4L2_STROBE_CONTROL_OFF = 0, + /* turn on the flash light */ + V4L2_STROBE_CONTROL_ON = 1, + /* act guide light before splash */ + V4L2_STROBE_CONTROL_AFGUIDE = 2, + /* charge the flash light */ + V4L2_STROBE_CONTROL_CHARGE = 3, +}; + +enum v4l2_strobe_conf { + V4L2_STROBE_OFF = 0, /* Always off */ + V4L2_STROBE_ON = 1, /* Always splashes */ + /* Auto control presets */ + V4L2_STROBE_AUTO = 2, + V4L2_STROBE_REDEYE_REDUCTION = 3, + V4L2_STROBE_SLOW_SYNC = 4, + V4L2_STROBE_FRONT_CURTAIN = 5, + V4L2_STROBE_REAR_CURTAIN = 6, + /* Extra manual control presets */ + /* keep turned on until turning off */ + V4L2_STROBE_PERMANENT = 7, + V4L2_STROBE_EXTERNAL = 8, +}; + +enum v4l2_strobe_status { + V4L2_STROBE_STATUS_OFF = 0, + /* while processing configurations */ + V4L2_STROBE_STATUS_BUSY = 1, + V4L2_STROBE_STATUS_ERR = 2, + V4L2_STROBE_STATUS_CHARGING = 3, + V4L2_STROBE_STATUS_CHARGED = 4, +}; + +/* capabilities field */ +/* No strobe supported */ +#define V4L2_STROBE_CAP_NONE 0x0000 +/* Always flash off mode */ +#define V4L2_STROBE_CAP_OFF 0x0001 +/* Always use flash light mode */ +#define V4L2_STROBE_CAP_ON 0x0002 +/* Flashlight works automatic */ +#define V4L2_STROBE_CAP_AUTO 0x0004 +/* Red-eye reduction */ +#define V4L2_STROBE_CAP_REDEYE 0x0008 +/* Slow sync */ +#define V4L2_STROBE_CAP_SLOWSYNC 0x0010 +/* Front curtain */ +#define V4L2_STROBE_CAP_FRONT_CURTAIN 0x0020 +/* Rear curtain */ +#define V4L2_STROBE_CAP_REAR_CURTAIN 0x0040 +/* keep turned on until turning off */ +#define V4L2_STROBE_CAP_PERMANENT 0x0080 +/* use external strobe */ +#define V4L2_STROBE_CAP_EXTERNAL 0x0100 + +/* Set mode and Get status */ +struct v4l2_strobe { + /* off/on/charge:0/1/2 */ + enum v4l2_strobe_control control; + /* supported strobe capabilities */ + __u32 capabilities; + enum v4l2_strobe_conf mode; + enum v4l2_strobe_status status; /* read only */ +/* default is 0 and range of value varies from each models */ + __u32 flash_ev; + __u32 reserved[4]; +}; + +#define VIDIOC_S_STROBE _IOWR('V', 83, struct v4l2_strobe) +#define VIDIOC_G_STROBE _IOR('V', 84, struct v4l2_strobe) + +/* Object recognition and collateral actions */ +enum v4l2_recog_mode { + V4L2_RECOGNITION_MODE_OFF = 0, + V4L2_RECOGNITION_MODE_ON = 1, + V4L2_RECOGNITION_MODE_LOCK = 2, +}; + +enum v4l2_recog_action { + V4L2_RECOGNITION_ACTION_NONE = 0, /* only recognition */ + V4L2_RECOGNITION_ACTION_BLINK = 1, /* Capture on blinking */ + V4L2_RECOGNITION_ACTION_SMILE = 2, /* Capture on smiling */ +}; + +enum v4l2_recog_pattern { + V4L2_RECOG_PATTERN_FACE = 0, /* Face */ + V4L2_RECOG_PATTERN_HUMAN = 1, /* Human */ + V4L2_RECOG_PATTERN_CHAR = 2, /* Character */ +}; + +struct v4l2_recog_rect { + enum v4l2_recog_pattern p; /* detected pattern */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recog_data { + __u8 detect_cnt; /* detected object counter */ + struct v4l2_rect o; /* detected area */ + __u32 reserved[4]; +}; + +struct v4l2_recognition { + enum v4l2_recog_mode mode; + + /* Which pattern to detect */ + enum v4l2_recog_pattern pattern; + + /* How many object to detect */ + __u8 obj_num; + + /* select detected object */ + __u32 detect_idx; + + /* read only :Get object coordination */ + struct v4l2_recog_data data; + + enum v4l2_recog_action action; + __u32 reserved[4]; +}; + +#define VIDIOC_S_RECOGNITION _IOWR('V', 85, struct v4l2_recognition) +#define VIDIOC_G_RECOGNITION _IOR('V', 86, struct v4l2_recognition) + +#endif /* __LINUX_VIDEODEV2_SAMSUNG_H */ diff --git a/camera/include/linux/videodev2_exynos_media.h b/camera/include/linux/videodev2_exynos_media.h new file mode 100644 index 0000000..2768201 --- /dev/null +++ b/camera/include/linux/videodev2_exynos_media.h @@ -0,0 +1,225 @@ +/* + * Video for Linux Two header file for Exynos + * + * Copyright (c) 2012 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * This header file contains several v4l2 APIs to be proposed to v4l2 + * community and until being accepted, will be used restrictly for Exynos. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef __LINUX_VIDEODEV2_EXYNOS_H +#define __LINUX_VIDEODEV2_EXYNOS_H + +/* Pixel format FOURCC depth Description */ + +/* two planes -- one Y, one Cr + Cb interleaved */ +#define V4L2_PIX_FMT_YUV444_2P v4l2_fourcc('Y', 'U', '2', 'P') /* 24 Y/CbCr */ +#define V4L2_PIX_FMT_YVU444_2P v4l2_fourcc('Y', 'V', '2', 'P') /* 24 Y/CrCb */ + +/* three planes -- one Y, one Cr, one Cb */ +#define V4L2_PIX_FMT_YUV444_3P v4l2_fourcc('Y', 'U', '3', 'P') /* 24 Y/Cb/Cr */ + +/* two non contiguous planes - one Y, one Cr + Cb interleaved */ +/* 21 Y/CrCb 4:2:0 */ +#define V4L2_PIX_FMT_NV21M v4l2_fourcc('N', 'M', '2', '1') +/* 12 Y/CbCr 4:2:0 16x16 macroblocks */ +#define V4L2_PIX_FMT_NV12MT_16X16 v4l2_fourcc('V', 'M', '1', '2') + +/* three non contiguous planes - Y, Cb, Cr */ +/* 12 YVU420 planar */ +#define V4L2_PIX_FMT_YVU420M v4l2_fourcc('Y', 'V', 'U', 'M') + +/* compressed formats */ +#define V4L2_PIX_FMT_H264_MVC v4l2_fourcc('M', '2', '6', '4') /* H264 MVC */ +#define V4L2_PIX_FMT_FIMV v4l2_fourcc('F', 'I', 'M', 'V') /* FIMV */ +#define V4L2_PIX_FMT_FIMV1 v4l2_fourcc('F', 'I', 'M', '1') /* FIMV1 */ +#define V4L2_PIX_FMT_FIMV2 v4l2_fourcc('F', 'I', 'M', '2') /* FIMV2 */ +#define V4L2_PIX_FMT_FIMV3 v4l2_fourcc('F', 'I', 'M', '3') /* FIMV3 */ +#define V4L2_PIX_FMT_FIMV4 v4l2_fourcc('F', 'I', 'M', '4') /* FIMV4 */ +#define V4L2_PIX_FMT_VP8 v4l2_fourcc('V', 'P', '8', '0') /* VP8 */ + +/* yuv444 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_444 v4l2_fourcc('J', 'P', 'G', '4') +/* yuv422 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_422 v4l2_fourcc('J', 'P', 'G', '2') +/* yuv420 of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_420 v4l2_fourcc('J', 'P', 'G', '0') +/* grey of JFIF JPEG */ +#define V4L2_PIX_FMT_JPEG_GRAY v4l2_fourcc('J', 'P', 'G', 'G') + +/* + * C O N T R O L S + */ +/* CID base for Exynos controls (USER_CLASS) */ +#define V4L2_CID_EXYNOS_BASE (V4L2_CTRL_CLASS_USER | 0x2000) + +/* for rgb alpha function */ +#define V4L2_CID_GLOBAL_ALPHA (V4L2_CID_EXYNOS_BASE + 1) + +/* cacheable configuration */ +#define V4L2_CID_CACHEABLE (V4L2_CID_EXYNOS_BASE + 10) + +/* jpeg captured size */ +#define V4L2_CID_CAM_JPEG_MEMSIZE (V4L2_CID_EXYNOS_BASE + 20) +#define V4L2_CID_CAM_JPEG_ENCODEDSIZE (V4L2_CID_EXYNOS_BASE + 21) + +#define V4L2_CID_SET_SHAREABLE (V4L2_CID_EXYNOS_BASE + 40) + +/* TV configuration */ +#define V4L2_CID_TV_LAYER_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 50) +#define V4L2_CID_TV_LAYER_BLEND_ALPHA (V4L2_CID_EXYNOS_BASE + 51) +#define V4L2_CID_TV_PIXEL_BLEND_ENABLE (V4L2_CID_EXYNOS_BASE + 52) +#define V4L2_CID_TV_CHROMA_ENABLE (V4L2_CID_EXYNOS_BASE + 53) +#define V4L2_CID_TV_CHROMA_VALUE (V4L2_CID_EXYNOS_BASE + 54) +#define V4L2_CID_TV_HPD_STATUS (V4L2_CID_EXYNOS_BASE + 55) +#define V4L2_CID_TV_LAYER_PRIO (V4L2_CID_EXYNOS_BASE + 56) +#define V4L2_CID_TV_SET_DVI_MODE (V4L2_CID_EXYNOS_BASE + 57) + +/* for color space conversion equation selection */ +#define V4L2_CID_CSC_EQ_MODE (V4L2_CID_EXYNOS_BASE + 100) +#define V4L2_CID_CSC_EQ (V4L2_CID_EXYNOS_BASE + 101) +#define V4L2_CID_CSC_RANGE (V4L2_CID_EXYNOS_BASE + 102) + +/* for DRM playback scenario */ +#define V4L2_CID_USE_SYSMMU (V4L2_CID_EXYNOS_BASE + 200) +#define V4L2_CID_M2M_CTX_NUM (V4L2_CID_EXYNOS_BASE + 201) + +/* CID base for MFC controls (MPEG_CLASS) */ +#define V4L2_CID_MPEG_MFC_BASE (V4L2_CTRL_CLASS_MPEG | 0x2000) + +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_AVAIL \ + (V4L2_CID_MPEG_MFC_BASE + 1) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRGMENT_ID \ + (V4L2_CID_MPEG_MFC_BASE + 2) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_INFO \ + (V4L2_CID_MPEG_MFC_BASE + 3) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_GRID_POS \ + (V4L2_CID_MPEG_MFC_BASE + 4) + +#define V4L2_CID_MPEG_MFC51_VIDEO_PACKED_PB \ + (V4L2_CID_MPEG_MFC_BASE + 5) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TAG \ + (V4L2_CID_MPEG_MFC_BASE + 6) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_ENABLE \ + (V4L2_CID_MPEG_MFC_BASE + 7) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA \ + (V4L2_CID_MPEG_MFC_BASE + 8) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA \ + (V4L2_CID_MPEG_MFC_BASE + 9) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_LUMA_BOT \ + (V4L2_CID_MPEG_MFC_BASE + 10) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_DATA_CHROMA_BOT \ + (V4L2_CID_MPEG_MFC_BASE + 11) +#define V4L2_CID_MPEG_MFC51_VIDEO_CRC_GENERATED \ + (V4L2_CID_MPEG_MFC_BASE + 12) +#define V4L2_CID_MPEG_MFC51_VIDEO_CHECK_STATE \ + (V4L2_CID_MPEG_MFC_BASE + 13) +#define V4L2_CID_MPEG_MFC51_VIDEO_DISPLAY_STATUS \ + (V4L2_CID_MPEG_MFC_BASE + 14) + +#define V4L2_CID_MPEG_MFC51_VIDEO_LUMA_ADDR \ + (V4L2_CID_MPEG_MFC_BASE + 15) +#define V4L2_CID_MPEG_MFC51_VIDEO_CHROMA_ADDR \ + (V4L2_CID_MPEG_MFC_BASE + 16) + +#define V4L2_CID_MPEG_MFC51_VIDEO_STREAM_SIZE \ + (V4L2_CID_MPEG_MFC_BASE + 17) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_COUNT \ + (V4L2_CID_MPEG_MFC_BASE + 18) +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 19) +enum v4l2_mpeg_mfc51_video_frame_type { + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_NOT_CODED = 0, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_I_FRAME = 1, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_P_FRAME = 2, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_B_FRAME = 3, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_SKIPPED = 4, + V4L2_MPEG_MFC51_VIDEO_FRAME_TYPE_OTHERS = 5, +}; + +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_INTERLACE \ + (V4L2_CID_MPEG_MFC_BASE + 20) +#define V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 21) +#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_TIME_RES \ + (V4L2_CID_MPEG_MFC_BASE + 22) +#define V4L2_CID_MPEG_MFC51_VIDEO_MPEG4_VOP_FRM_DELTA \ + (V4L2_CID_MPEG_MFC_BASE + 23) +#define V4L2_CID_MPEG_MFC51_VIDEO_H263_RC_FRAME_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 24) + +#define V4L2_CID_MPEG_MFC6X_VIDEO_FRAME_DELTA \ + (V4L2_CID_MPEG_MFC_BASE + 25) + +#define V4L2_CID_MPEG_MFC51_VIDEO_I_PERIOD_CH V4L2_CID_MPEG_VIDEO_GOP_SIZE +#define V4L2_CID_MPEG_MFC51_VIDEO_FRAME_RATE_CH \ + V4L2_CID_MPEG_MFC51_VIDEO_H264_RC_FRAME_RATE +#define V4L2_CID_MPEG_MFC51_VIDEO_BIT_RATE_CH V4L2_CID_MPEG_VIDEO_BITRATE + +/* proposed CIDs, based on 3.3-rc3 */ +#define V4L2_CID_MPEG_VIDEO_VBV_DELAY (V4L2_CID_MPEG_MFC_BASE + 26) + +#define V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_S_B \ + V4L2_MPEG_VIDEO_H264_LOOP_FILTER_MODE_DISABLED_AT_SLICE_BOUNDARY + +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FRAME_PACKING \ + (V4L2_CID_MPEG_MFC_BASE + 27) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_CURRENT_FRAME_0 \ + (V4L2_CID_MPEG_MFC_BASE + 28) +#define V4L2_CID_MPEG_VIDEO_H264_SEI_FP_ARRANGEMENT_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 29) +enum v4l2_mpeg_video_h264_sei_fp_arrangement_type { + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_CHEKERBOARD = 0, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_COLUMN = 1, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_ROW = 2, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_SIDE_BY_SIDE = 3, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TOP_BOTTOM = 4, + V4L2_MPEG_VIDEO_H264_SEI_FP_TYPE_TEMPORAL = 5, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO (V4L2_CID_MPEG_MFC_BASE + 30) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_MAP_TYPE (V4L2_CID_MPEG_MFC_BASE + 31) +enum v4l2_mpeg_video_h264_fmo_map_type { + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_INTERLEAVED_SLICES = 0, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_SCATTERED_SLICES = 1, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_FOREGROUND_WITH_LEFT_OVER = 2, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_BOX_OUT = 3, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_RASTER_SCAN = 4, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_WIPE_SCAN = 5, + V4L2_MPEG_VIDEO_H264_FMO_MAP_TYPE_EXPLICIT = 6, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_SLICE_GROUP \ + (V4L2_CID_MPEG_MFC_BASE + 32) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_DIRECTION \ + (V4L2_CID_MPEG_MFC_BASE + 33) +enum v4l2_mpeg_video_h264_fmo_change_dir { + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_RIGHT = 0, + V4L2_MPEG_VIDEO_H264_FMO_CHANGE_DIR_LEFT = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_FMO_CHANGE_RATE \ + (V4L2_CID_MPEG_MFC_BASE + 34) +#define V4L2_CID_MPEG_VIDEO_H264_FMO_RUN_LENGTH \ + (V4L2_CID_MPEG_MFC_BASE + 35) +#define V4L2_CID_MPEG_VIDEO_H264_ASO \ + (V4L2_CID_MPEG_MFC_BASE + 36) +#define V4L2_CID_MPEG_VIDEO_H264_ASO_SLICE_ORDER \ + (V4L2_CID_MPEG_MFC_BASE + 37) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING \ + (V4L2_CID_MPEG_MFC_BASE + 38) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_TYPE \ + (V4L2_CID_MPEG_MFC_BASE + 39) +enum v4l2_mpeg_video_h264_hierarchical_coding_type { + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_B = 0, + V4L2_MPEG_VIDEO_H264_HIERARCHICAL_CODING_P = 1, +}; +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER \ + (V4L2_CID_MPEG_MFC_BASE + 40) +#define V4L2_CID_MPEG_VIDEO_H264_HIERARCHICAL_CODING_LAYER_QP \ + (V4L2_CID_MPEG_MFC_BASE + 41) +#define V4L2_CID_MPEG_VIDEO_H264_MVC_VIEW_ID \ + (V4L2_CID_MPEG_MFC_BASE + 42) +#endif /* __LINUX_VIDEODEV2_EXYNOS_H */ diff --git a/camera/smdk4x12_camera.c b/camera/smdk4x12_camera.c deleted file mode 100644 index 53cc16f..0000000 --- a/camera/smdk4x12_camera.c +++ /dev/null @@ -1,4530 +0,0 @@ -/* - * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> - * - * Based on crespo libcamera and exynos4 hal libcamera: - * Copyright 2008, The Android Open Source Project - * Copyright 2010, Samsung Electronics Co. LTD - * - * 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 3 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/>. - */ - -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> -#include <time.h> -#include <errno.h> -#include <malloc.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/mman.h> -#include <sys/ioctl.h> - -#include <asm/types.h> - -#define LOG_TAG "smdk4x12_camera" -#include <utils/Log.h> -#include <utils/Timers.h> - -#include "smdk4x12_camera.h" - -#define BIG2LITTLE_ENDIAN(big) ((big & 0xff) << 24 | (big & 0xff00) << 8 | (big & 0xff0000) >> 8 | (big & 0xff000000) >> 24) - -/* - * Devices configurations - */ - -struct smdk4x12_camera_mbus_resolution smdk4x12_camera_mbus_resolutions_s5k6a3_galaxys3[] = { - // 16:9 ratio - { 1280, 720, 1344, 756 }, - // 4:3 ratio - { 1280, 960, 1392, 1044 }, - { 960, 720, 1392, 1044 }, - { 640, 480, 1392, 1044 }, - { 320, 240, 1392, 1044 }, - // 1:1 ratio - { 1392, 1392, 1392, 1392 }, - { 704, 704, 1392, 1392 }, - { 320, 320, 1392, 1392 }, -}; - -struct smdk4x12_camera_preset smdk4x12_camera_presets_galaxys3[] = { - { - .name = "S5C73M3", - .facing = CAMERA_FACING_BACK, - .orientation = 90, - .rotation = 0, - .hflip = 0, - .vflip = 0, - .capture_format = V4L2_PIX_FMT_INTERLEAVED, - .picture_format = 0, - .fimc_is = 0, - .focal_length = 3.7f, - .horizontal_view_angle = 63.0f, - .vertical_view_angle = 49.3f, - .metering = METERING_CENTER, - .params = { - .preview_size_values = "960x720,1280x720,1184x666,960x640,704x576,640x480,352x288,320x240", - .preview_size = "960x720", - .preview_format_values = "yuv420sp,yuv420p,rgb565", - .preview_format = "rgb565", - .preview_frame_rate_values = "30,20,15", - .preview_frame_rate = 30, - .preview_fps_range_values = "(15000,15000),(15000,30000),(30000,30000)", - .preview_fps_range = "15000,30000", - - .picture_size_values = "640x480,1024x768,1280x720,1600x1200,2560x1920,3264x2448,2048x1536,3264x1836,2048x1152,3264x2176", - .picture_size = "3264x2448", - .picture_format_values = "jpeg", - .picture_format = "jpeg", - .jpeg_thumbnail_size_values = "160x120,160x90,144x96", - .jpeg_thumbnail_width = 160, - .jpeg_thumbnail_height = 120, - .jpeg_thumbnail_quality = 100, - .jpeg_quality = 90, - - .video_snapshot_supported = 0, - .full_video_snap_supported = 0, - - .recording_size = "1280x720", - .recording_size_values = "1280x720,1920x1080,720x480,640x480,352x288,320x240,176x144", - .recording_format = "yuv420sp", - - .focus_mode = "continuous-picture", - .focus_mode_values = "auto,infinity,macro,fixed,continuous-picture,continuous-video", - .focus_distances = "0.15,1.20,Infinity", - .focus_areas = NULL, - .max_num_focus_areas = 1, - - .zoom_supported = 1, - .smooth_zoom_supported = 0, - .zoom_ratios = "100,102,104,109,111,113,119,121,124,131,134,138,146,150,155,159,165,170,182,189,200,213,222,232,243,255,283,300,319,364,400", - .zoom = 0, - .max_zoom = 30, - - .auto_exposure_lock_supported = 1, - .auto_exposure_lock = 0, - - .auto_white_balance_lock_supported = 1, - .auto_white_balance_lock = 0, - - .flash_mode = "auto", - .flash_mode_values = "auto,on,torch,off", - - .exposure_compensation = 0, - .exposure_compensation_step = 0.5, - .min_exposure_compensation = -4, - .max_exposure_compensation = 4, - - .whitebalance = "auto", - .whitebalance_values = "auto,incandescent,fluorescent,daylight,cloudy-daylight", - - .antibanding = "auto", - .antibanding_values = "auto,60hz,50hz,off", - - .scene_mode = "auto", - .scene_mode_values = "auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight,dusk-dawn,fall-color,text,back-light", - - .effect = "none", - .effect_values = "none,mono,negative,sepia,solarize,posterize,washed,vintage-warm,vintage-cold,point-blue,point-red-yellow,point-green", - - .iso = "auto", - .iso_values = "auto,ISO100,ISO200,ISO400,ISO800", - - .image_stabilization = "off", - .image_stabilization_values = "on,off", - }, - .mbus_resolutions = NULL, - .mbus_resolutions_count = 0, - }, - { - .name = "S5K6A3", - .facing = CAMERA_FACING_FRONT, - .orientation = 270, - .rotation = 0, - .hflip = 0, - .vflip = 0, - .capture_format = 0, - .picture_format = V4L2_PIX_FMT_YUYV, - .fimc_is = 1, - .focal_length = 2.73f, - .horizontal_view_angle = 52.58f, - .vertical_view_angle = 52.58f, - .metering = METERING_CENTER, - .params = { - .preview_size_values = "1280x720,960x720,640x480,320x240,704x704,320x320", - .preview_size = "960x720", - .preview_format_values = "yuv420sp,yuv420p,rgb565", - .preview_format = "rgb565", - .preview_frame_rate_values = "30,20,15,8", - .preview_frame_rate = 30, - .preview_fps_range_values = "(8000,8000),(15000,15000),(15000,30000),(30000,30000)", - .preview_fps_range = "15000,30000", - - .picture_size_values = "1344x756,1280x720,1392x1044,1280x960,960x720,640x480,1392x1392", - .picture_size = "1280x960", - .picture_format_values = "jpeg", - .picture_format = "jpeg", - .jpeg_thumbnail_size_values = "160x120,160x160,160x90,144x96", - .jpeg_thumbnail_width = 160, - .jpeg_thumbnail_height = 120, - .jpeg_thumbnail_quality = 100, - .jpeg_quality = 90, - - .video_snapshot_supported = 0, - .full_video_snap_supported = 0, - - .recording_size = "1280x720", - .recording_size_values = "1280x720,720x480,640x480,352x288,320x320,320x240,176x144", - .recording_format = "yuv420sp", - - .focus_mode = "fixed", - .focus_mode_values = "infinity,fixed", - .focus_distances = "0.20,0.25,Infinity", - .focus_areas = NULL, - .max_num_focus_areas = 0, - - .zoom_supported = 0, - - .auto_exposure_lock_supported = 0, - .auto_exposure_lock = 0, - - .auto_white_balance_lock_supported = 0, - .auto_white_balance_lock = 0, - - .flash_mode = NULL, - .flash_mode_values = NULL, - - .exposure_compensation = 0, - .exposure_compensation_step = 0.5, - .min_exposure_compensation = -4, - .max_exposure_compensation = 4, - - .whitebalance = "auto", - .whitebalance_values = "auto,incandescent,fluorescent,daylight,cloudy-daylight", - - .antibanding = NULL, - .antibanding_values = NULL, - - .scene_mode = NULL, - .scene_mode_values = NULL, - - .effect = "none", - .effect_values = "none,mono,negative,sepia,solarize,posterize,washed,vintage-warm,vintage-cold,point-blue,point-red-yellow,point-green", - - .iso = "auto", - .iso_values = "auto", - - .image_stabilization = "off", - .image_stabilization_values = "off", - }, - .mbus_resolutions = (struct smdk4x12_camera_mbus_resolution *) &smdk4x12_camera_mbus_resolutions_s5k6a3_galaxys3, - .mbus_resolutions_count = 8, - }, -}; - -struct smdk4x12_v4l2_node smdk4x12_v4l2_nodes_galaxys3[] = { - { // FIMC0 is used for capture - .id = 0, - .node = "/dev/video0", - }, - { // FIMC1 is used for preview output - .id = 1, - .node = "/dev/video1", - }, - { // FIMC2 is used for picture output - .id = 2, - .node = "/dev/video2", - }, - { // FIMC3 is used for recording output - .id = 3, - .node = "/dev/video3", - }, -}; - -struct exynox_camera_config smdk4x12_camera_config_galaxys3 = { - .presets = (struct smdk4x12_camera_preset *) &smdk4x12_camera_presets_galaxys3, - .presets_count = 2, - .v4l2_nodes = (struct smdk4x12_v4l2_node *) &smdk4x12_v4l2_nodes_galaxys3, - .v4l2_nodes_count = 4, -}; - -/* - * SMDK4x12 Camera - */ - -struct exynox_camera_config *smdk4x12_camera_config = - &smdk4x12_camera_config_galaxys3; - -int smdk4x12_camera_start(struct smdk4x12_camera *smdk4x12_camera, int id) -{ - int rc; - - if (smdk4x12_camera == NULL || id >= smdk4x12_camera->config->presets_count) - return -EINVAL; - - // ION - -#ifdef EXYNOS_ION - rc = smdk4x12_ion_init(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to init ION", __func__); - goto error; - } - - rc = smdk4x12_ion_open(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to open ION", __func__); - goto error; - } -#endif - - // V4L2 - - rc = smdk4x12_v4l2_init(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to init v4l2", __func__); - goto error; - } - - // FIMC0 - - rc = smdk4x12_v4l2_open(smdk4x12_camera, 0); - if (rc < 0) { - ALOGE("%s: Unable to open v4l2 device", __func__); - goto error; - } - - rc = smdk4x12_v4l2_querycap_cap(smdk4x12_camera, 0); - if (rc < 0) { - ALOGE("%s: Unable to query capabilities", __func__); - goto error; - } - - rc = smdk4x12_v4l2_enum_input(smdk4x12_camera, 0, id); - if (rc < 0) { - ALOGE("%s: Unable to enumerate input", __func__); - goto error; - } - - rc = smdk4x12_v4l2_s_input(smdk4x12_camera, 0, id); - if (rc < 0) { - ALOGE("%s: Unable to set inputs", __func__); - goto error; - } - - // Recording - - smdk4x12_camera->recording_metadata = 1; - - // Params - - rc = smdk4x12_camera_params_init(smdk4x12_camera, id); - if (rc < 0) { - ALOGE("%s: Unable to init params", __func__); - goto error; - } - - // Gralloc - - rc = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, (const struct hw_module_t **) &smdk4x12_camera->gralloc); - if (rc) - ALOGE("%s: Unable to get gralloc module", __func__); - - rc = 0; - goto complete; - -error: - smdk4x12_v4l2_close(smdk4x12_camera, 0); - -#ifdef EXYNOS_ION - smdk4x12_ion_close(smdk4x12_camera); -#endif - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - int i; - int id; - - if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL) - return; - - smdk4x12_v4l2_close(smdk4x12_camera, 0); - -#ifdef EXYNOS_ION - smdk4x12_ion_close(smdk4x12_camera); -#endif -} - -// Params - -int smdk4x12_camera_params_init(struct smdk4x12_camera *smdk4x12_camera, int id) -{ - int rc; - - if (smdk4x12_camera == NULL || id >= smdk4x12_camera->config->presets_count) - return -EINVAL; - - // Camera params - - smdk4x12_camera->camera_rotation = smdk4x12_camera->config->presets[id].rotation; - smdk4x12_camera->camera_hflip = smdk4x12_camera->config->presets[id].hflip; - smdk4x12_camera->camera_vflip = smdk4x12_camera->config->presets[id].vflip; - smdk4x12_camera->camera_capture_format = smdk4x12_camera->config->presets[id].capture_format; - smdk4x12_camera->camera_picture_format = smdk4x12_camera->config->presets[id].picture_format; - smdk4x12_camera->camera_fimc_is = smdk4x12_camera->config->presets[id].fimc_is; - smdk4x12_camera->camera_focal_length = (int) (smdk4x12_camera->config->presets[id].focal_length * 100); - smdk4x12_camera->camera_metering = smdk4x12_camera->config->presets[id].metering; - - smdk4x12_camera->camera_mbus_resolutions = smdk4x12_camera->config->presets[id].mbus_resolutions; - smdk4x12_camera->camera_mbus_resolutions_count = smdk4x12_camera->config->presets[id].mbus_resolutions_count; - - // Recording preview - - smdk4x12_param_string_set(smdk4x12_camera, "preferred-preview-size-for-video", - smdk4x12_camera->config->presets[id].params.preview_size); - - // Preview - - smdk4x12_param_string_set(smdk4x12_camera, "preview-size-values", - smdk4x12_camera->config->presets[id].params.preview_size_values); - smdk4x12_param_string_set(smdk4x12_camera, "preview-size", - smdk4x12_camera->config->presets[id].params.preview_size); - smdk4x12_param_string_set(smdk4x12_camera, "preview-format-values", - smdk4x12_camera->config->presets[id].params.preview_format_values); - smdk4x12_param_string_set(smdk4x12_camera, "preview-format", - smdk4x12_camera->config->presets[id].params.preview_format); - smdk4x12_param_string_set(smdk4x12_camera, "preview-frame-rate-values", - smdk4x12_camera->config->presets[id].params.preview_frame_rate_values); - smdk4x12_param_int_set(smdk4x12_camera, "preview-frame-rate", - smdk4x12_camera->config->presets[id].params.preview_frame_rate); - smdk4x12_param_string_set(smdk4x12_camera, "preview-fps-range-values", - smdk4x12_camera->config->presets[id].params.preview_fps_range_values); - smdk4x12_param_string_set(smdk4x12_camera, "preview-fps-range", - smdk4x12_camera->config->presets[id].params.preview_fps_range); - - // Picture - - smdk4x12_param_string_set(smdk4x12_camera, "picture-size-values", - smdk4x12_camera->config->presets[id].params.picture_size_values); - smdk4x12_param_string_set(smdk4x12_camera, "picture-size", - smdk4x12_camera->config->presets[id].params.picture_size); - smdk4x12_param_string_set(smdk4x12_camera, "picture-format-values", - smdk4x12_camera->config->presets[id].params.picture_format_values); - smdk4x12_param_string_set(smdk4x12_camera, "picture-format", - smdk4x12_camera->config->presets[id].params.picture_format); - smdk4x12_param_string_set(smdk4x12_camera, "jpeg-thumbnail-size-values", - smdk4x12_camera->config->presets[id].params.jpeg_thumbnail_size_values); - smdk4x12_param_int_set(smdk4x12_camera, "jpeg-thumbnail-width", - smdk4x12_camera->config->presets[id].params.jpeg_thumbnail_width); - smdk4x12_param_int_set(smdk4x12_camera, "jpeg-thumbnail-height", - smdk4x12_camera->config->presets[id].params.jpeg_thumbnail_height); - smdk4x12_param_int_set(smdk4x12_camera, "jpeg-thumbnail-quality", - smdk4x12_camera->config->presets[id].params.jpeg_thumbnail_quality); - smdk4x12_param_int_set(smdk4x12_camera, "jpeg-quality", - smdk4x12_camera->config->presets[id].params.jpeg_quality); - - if (smdk4x12_camera->config->presets[id].params.video_snapshot_supported == 1) - smdk4x12_param_string_set(smdk4x12_camera, "video-snapshot-supported", "true"); - if (smdk4x12_camera->config->presets[id].params.full_video_snap_supported == 1) - smdk4x12_param_string_set(smdk4x12_camera, "full-video-snap-supported", "true"); - - // Recording - - smdk4x12_param_string_set(smdk4x12_camera, "video-size", - smdk4x12_camera->config->presets[id].params.recording_size); - smdk4x12_param_string_set(smdk4x12_camera, "video-size-values", - smdk4x12_camera->config->presets[id].params.recording_size_values); - smdk4x12_param_string_set(smdk4x12_camera, "video-frame-format", - smdk4x12_camera->config->presets[id].params.recording_format); - - // Focus - - smdk4x12_param_string_set(smdk4x12_camera, "focus-mode", - smdk4x12_camera->config->presets[id].params.focus_mode); - smdk4x12_param_string_set(smdk4x12_camera, "focus-mode-values", - smdk4x12_camera->config->presets[id].params.focus_mode_values); - smdk4x12_param_string_set(smdk4x12_camera, "focus-distances", - smdk4x12_camera->config->presets[id].params.focus_distances); - if (smdk4x12_camera->config->presets[id].params.max_num_focus_areas > 0) { - smdk4x12_param_string_set(smdk4x12_camera, "focus-areas", - smdk4x12_camera->config->presets[id].params.focus_areas); - smdk4x12_param_int_set(smdk4x12_camera, "max-num-focus-areas", - smdk4x12_camera->config->presets[id].params.max_num_focus_areas); - } - - // Zoom - - if (smdk4x12_camera->config->presets[id].params.zoom_supported == 1) { - smdk4x12_param_string_set(smdk4x12_camera, "zoom-supported", "true"); - - if (smdk4x12_camera->config->presets[id].params.smooth_zoom_supported == 1) - smdk4x12_param_string_set(smdk4x12_camera, "smooth-zoom-supported", "true"); - - if (smdk4x12_camera->config->presets[id].params.zoom_ratios != NULL) - smdk4x12_param_string_set(smdk4x12_camera, "zoom-ratios", smdk4x12_camera->config->presets[id].params.zoom_ratios); - - smdk4x12_param_int_set(smdk4x12_camera, "zoom", smdk4x12_camera->config->presets[id].params.zoom); - smdk4x12_param_int_set(smdk4x12_camera, "max-zoom", smdk4x12_camera->config->presets[id].params.max_zoom); - - } else { - smdk4x12_param_string_set(smdk4x12_camera, "zoom-supported", "false"); - } - - // AE lock - - if (smdk4x12_camera->config->presets[id].params.auto_exposure_lock_supported == 1) { - smdk4x12_param_string_set(smdk4x12_camera, "auto-exposure-lock-supported", "true"); - - if (smdk4x12_camera->config->presets[id].params.auto_exposure_lock) - smdk4x12_param_string_set(smdk4x12_camera, "auto-exposure-lock", "true"); - else - smdk4x12_param_string_set(smdk4x12_camera, "auto-exposure-lock", "false"); - } - - // AWB lock - - if (smdk4x12_camera->config->presets[id].params.auto_white_balance_lock_supported == 1) { - smdk4x12_param_string_set(smdk4x12_camera, "auto-whitebalance-lock-supported", "true"); - - if (smdk4x12_camera->config->presets[id].params.auto_white_balance_lock) - smdk4x12_param_string_set(smdk4x12_camera, "auto-whitebalance-lock", "true"); - else - smdk4x12_param_string_set(smdk4x12_camera, "auto-whitebalance-lock", "false"); - } - - // Flash - - smdk4x12_param_string_set(smdk4x12_camera, "flash-mode", - smdk4x12_camera->config->presets[id].params.flash_mode); - smdk4x12_param_string_set(smdk4x12_camera, "flash-mode-values", - smdk4x12_camera->config->presets[id].params.flash_mode_values); - - // Exposure - - smdk4x12_param_int_set(smdk4x12_camera, "exposure-compensation", - smdk4x12_camera->config->presets[id].params.exposure_compensation); - smdk4x12_param_float_set(smdk4x12_camera, "exposure-compensation-step", - smdk4x12_camera->config->presets[id].params.exposure_compensation_step); - smdk4x12_param_int_set(smdk4x12_camera, "min-exposure-compensation", - smdk4x12_camera->config->presets[id].params.min_exposure_compensation); - smdk4x12_param_int_set(smdk4x12_camera, "max-exposure-compensation", - smdk4x12_camera->config->presets[id].params.max_exposure_compensation); - - // Antibanding - - smdk4x12_param_string_set(smdk4x12_camera, "antibanding", - smdk4x12_camera->config->presets[id].params.antibanding); - smdk4x12_param_string_set(smdk4x12_camera, "antibanding-values", - smdk4x12_camera->config->presets[id].params.antibanding_values); - - // WB - - smdk4x12_param_string_set(smdk4x12_camera, "whitebalance", - smdk4x12_camera->config->presets[id].params.whitebalance); - smdk4x12_param_string_set(smdk4x12_camera, "whitebalance-values", - smdk4x12_camera->config->presets[id].params.whitebalance_values); - - // Scene mode - - smdk4x12_param_string_set(smdk4x12_camera, "scene-mode", - smdk4x12_camera->config->presets[id].params.scene_mode); - smdk4x12_param_string_set(smdk4x12_camera, "scene-mode-values", - smdk4x12_camera->config->presets[id].params.scene_mode_values); - - // Effect - - smdk4x12_param_string_set(smdk4x12_camera, "effect", - smdk4x12_camera->config->presets[id].params.effect); - smdk4x12_param_string_set(smdk4x12_camera, "effect-values", - smdk4x12_camera->config->presets[id].params.effect_values); - - // ISO - - smdk4x12_param_string_set(smdk4x12_camera, "iso", - smdk4x12_camera->config->presets[id].params.iso); - smdk4x12_param_string_set(smdk4x12_camera, "iso-values", - smdk4x12_camera->config->presets[id].params.iso_values); - - // Image stabilization - - smdk4x12_param_string_set(smdk4x12_camera, "image-stabilization", - smdk4x12_camera->config->presets[id].params.image_stabilization); - smdk4x12_param_string_set(smdk4x12_camera, "image-stabilization-values", - smdk4x12_camera->config->presets[id].params.image_stabilization_values); - - // Camera - - smdk4x12_param_float_set(smdk4x12_camera, "focal-length", - smdk4x12_camera->config->presets[id].focal_length); - smdk4x12_param_float_set(smdk4x12_camera, "horizontal-view-angle", - smdk4x12_camera->config->presets[id].horizontal_view_angle); - smdk4x12_param_float_set(smdk4x12_camera, "vertical-view-angle", - smdk4x12_camera->config->presets[id].vertical_view_angle); - - rc = smdk4x12_camera_params_apply(smdk4x12_camera, 1); - if (rc < 0) { - ALOGE("%s: Unable to apply params", __func__); - return -1; - } - - return 0; -} - -int smdk4x12_camera_params_apply(struct smdk4x12_camera *smdk4x12_camera, int force) -{ - char *recording_hint_string; - char *recording_preview_size_string; - - char *preview_size_string; - int preview_width = 0; - int preview_height = 0; - char *preview_format_string; - int preview_format; - int preview_fps; - - char *picture_size_string; - int picture_width = 0; - int picture_height = 0; - char *picture_format_string; - int picture_format; - - int jpeg_thumbnail_width; - int jpeg_thumbnail_height; - int jpeg_thumbnail_quality; - int jpeg_quality; - - char *video_size_string; - int recording_width = 0; - int recording_height = 0; - char *video_frame_format_string; - int recording_format; - int camera_sensor_mode; - int fimc_is_mode = 0; - - char *focus_mode_string; - int focus_mode = 0; - char *focus_areas_string; - int focus_left, focus_top, focus_right, focus_bottom, focus_weigth; - int focus_x; - int focus_y; - - char *zoom_supported_string; - int zoom, max_zoom; - - char *ae_lock_supported_string; - char *ae_lock_string; - int ae_lock = 0; - - char *awb_lock_supported_string; - char *awb_lock_string; - int awb_lock = 0; - int aeawb = 0; - - char *flash_mode_string; - int flash_mode; - - int exposure_compensation; - int min_exposure_compensation; - int max_exposure_compensation; - - char *antibanding_string; - int antibanding; - - char *whitebalance_string; - int whitebalance; - - char *scene_mode_string; - int scene_mode; - - char *effect_string; - int effect; - - char *iso_string; - int iso; - - char *image_stabilization_string; - int image_stabilization; - - int w, h; - char *k; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - // Preview - - preview_size_string = smdk4x12_param_string_get(smdk4x12_camera, "preview-size"); - if (preview_size_string != NULL) { - sscanf(preview_size_string, "%dx%d", &preview_width, &preview_height); - - if (preview_width != 0 && preview_width != smdk4x12_camera->preview_width) - smdk4x12_camera->preview_width = preview_width; - if (preview_height != 0 && preview_height != smdk4x12_camera->preview_height) - smdk4x12_camera->preview_height = preview_height; - } - - preview_format_string = smdk4x12_param_string_get(smdk4x12_camera, "preview-format"); - if (preview_format_string != NULL) { - if (strcmp(preview_format_string, "yuv420sp") == 0) { - preview_format = V4L2_PIX_FMT_NV21; - } else if (strcmp(preview_format_string, "yuv420p") == 0) { - preview_format = V4L2_PIX_FMT_YUV420; - } else if (strcmp(preview_format_string, "rgb565") == 0) { - preview_format = V4L2_PIX_FMT_RGB565; - } else if (strcmp(preview_format_string, "rgb8888") == 0) { - preview_format = V4L2_PIX_FMT_RGB32; - } else { - ALOGE("%s: Unsupported preview format: %s", __func__, preview_format_string); - preview_format = V4L2_PIX_FMT_NV21; - } - - if (preview_format != smdk4x12_camera->preview_format) - smdk4x12_camera->preview_format = preview_format; - } - - preview_fps = smdk4x12_param_int_get(smdk4x12_camera, "preview-frame-rate"); - if (preview_fps > 0) - smdk4x12_camera->preview_fps = preview_fps; - else - smdk4x12_camera->preview_fps = 0; - - // Picture - - picture_size_string = smdk4x12_param_string_get(smdk4x12_camera, "picture-size"); - if (picture_size_string != NULL) { - sscanf(picture_size_string, "%dx%d", &picture_width, &picture_height); - - if (picture_width != 0 && picture_height != 0 && (picture_width != smdk4x12_camera->picture_width || picture_height != smdk4x12_camera->picture_height)) { - smdk4x12_camera->picture_width = picture_width; - smdk4x12_camera->picture_height = picture_height; - - if (smdk4x12_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED) { - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_JPEG_RESOLUTION, (picture_width & 0xffff) << 16 | (picture_height & 0xffff)); - if (rc < 0) - ALOGE("%s: Unablet to set jpeg resolution", __func__); - } - } - } - - picture_format_string = smdk4x12_param_string_get(smdk4x12_camera, "picture-format"); - if (picture_format_string != NULL) { - if (strcmp(picture_format_string, "jpeg") == 0) { - picture_format = V4L2_PIX_FMT_JPEG; - } else { - ALOGE("%s: Unsupported picture format: %s", __func__, picture_format_string); - picture_format = V4L2_PIX_FMT_JPEG; - } - - if (picture_format != smdk4x12_camera->picture_format) - smdk4x12_camera->picture_format = picture_format; - } - - jpeg_thumbnail_width = smdk4x12_param_int_get(smdk4x12_camera, "jpeg-thumbnail-width"); - if (jpeg_thumbnail_width > 0) - smdk4x12_camera->jpeg_thumbnail_width = jpeg_thumbnail_width; - - jpeg_thumbnail_height = smdk4x12_param_int_get(smdk4x12_camera, "jpeg-thumbnail-height"); - if (jpeg_thumbnail_height > 0) - smdk4x12_camera->jpeg_thumbnail_height = jpeg_thumbnail_height; - - jpeg_thumbnail_quality = smdk4x12_param_int_get(smdk4x12_camera, "jpeg-thumbnail-quality"); - if (jpeg_thumbnail_quality > 0) - smdk4x12_camera->jpeg_thumbnail_quality = jpeg_thumbnail_quality; - - jpeg_quality = smdk4x12_param_int_get(smdk4x12_camera, "jpeg-quality"); - if (jpeg_quality <= 100 && jpeg_quality >= 0 && (jpeg_quality != smdk4x12_camera->jpeg_quality || force)) { - smdk4x12_camera->jpeg_quality = jpeg_quality; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAM_JPEG_QUALITY, jpeg_quality); - if (rc < 0) - ALOGE("%s: Unable to set jpeg quality", __func__); - } - - // Recording - - video_size_string = smdk4x12_param_string_get(smdk4x12_camera, "video-size"); - if (video_size_string == NULL) - video_size_string = smdk4x12_param_string_get(smdk4x12_camera, "preview-size"); - - if (video_size_string != NULL) { - sscanf(video_size_string, "%dx%d", &recording_width, &recording_height); - - if (recording_width != 0 && recording_width != smdk4x12_camera->recording_width) - smdk4x12_camera->recording_width = recording_width; - if (recording_height != 0 && recording_height != smdk4x12_camera->recording_height) - smdk4x12_camera->recording_height = recording_height; - } - - video_frame_format_string = smdk4x12_param_string_get(smdk4x12_camera, "video-frame-format"); - if (video_frame_format_string != NULL) { - if (strcmp(video_frame_format_string, "yuv420sp") == 0) { - recording_format = V4L2_PIX_FMT_NV12; - } else if (strcmp(video_frame_format_string, "yuv420p") == 0) { - recording_format = V4L2_PIX_FMT_YUV420; - } else if (strcmp(video_frame_format_string, "rgb565") == 0) { - recording_format = V4L2_PIX_FMT_RGB565; - } else if (strcmp(video_frame_format_string, "rgb8888") == 0) { - recording_format = V4L2_PIX_FMT_RGB32; - } else { - ALOGE("%s: Unsupported recording format: %s", __func__, video_frame_format_string); - recording_format = V4L2_PIX_FMT_NV12; - } - - if (recording_format != smdk4x12_camera->recording_format) - smdk4x12_camera->recording_format = recording_format; - } - - recording_hint_string = smdk4x12_param_string_get(smdk4x12_camera, "recording-hint"); - if (recording_hint_string != NULL && strcmp(recording_hint_string, "true") == 0) { - camera_sensor_mode = SENSOR_MOVIE; - - k = smdk4x12_param_string_get(smdk4x12_camera, "preview-size-values"); - while (recording_width != 0 && recording_height != 0) { - if (k == NULL) - break; - - sscanf(k, "%dx%d", &w, &h); - - // Look for same aspect ratio - if ((recording_width * h) / recording_height == w) { - preview_width = w; - preview_height = h; - break; - } - - k = strchr(k, ','); - if (k == NULL) - break; - - k++; - } - - if (preview_width != 0 && preview_width != smdk4x12_camera->preview_width) - smdk4x12_camera->preview_width = preview_width; - if (preview_height != 0 && preview_height != smdk4x12_camera->preview_height) - smdk4x12_camera->preview_height = preview_height; - - if (smdk4x12_camera->camera_fimc_is) - fimc_is_mode = IS_MODE_PREVIEW_VIDEO; - } else { - camera_sensor_mode = SENSOR_CAMERA; - - if (smdk4x12_camera->camera_fimc_is) - fimc_is_mode = IS_MODE_PREVIEW_STILL; - } - - // Switching modes - - if (camera_sensor_mode != smdk4x12_camera->camera_sensor_mode) { - smdk4x12_camera->camera_sensor_mode = camera_sensor_mode; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_SENSOR_MODE, camera_sensor_mode); - if (rc < 0) - ALOGE("%s: Unable to set sensor mode", __func__); - } - - if (smdk4x12_camera->camera_fimc_is && fimc_is_mode != smdk4x12_camera->fimc_is_mode) { - smdk4x12_camera->fimc_is_mode = fimc_is_mode; - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_IS_S_FORMAT_SCENARIO, smdk4x12_camera->fimc_is_mode); - if (rc < 0) - ALOGE("%s: Unable to set FIMC-IS scenario", __func__); - } - - // Focus - - focus_areas_string = smdk4x12_param_string_get(smdk4x12_camera, "focus-areas"); - if (focus_areas_string != NULL) { - focus_left = focus_top = focus_right = focus_bottom = focus_weigth = 0; - - rc = sscanf(focus_areas_string, "(%d,%d,%d,%d,%d)", - &focus_left, &focus_top, &focus_right, &focus_bottom, &focus_weigth); - if (rc != 5) { - ALOGE("%s: Unable to scan focus areas", __func__); - } else if (focus_left != 0 && focus_top != 0 && focus_right != 0 && focus_bottom != 0) { - focus_x = (((focus_left + focus_right) / 2) + 1000) * preview_width / 2000; - focus_y = (((focus_top + focus_bottom) / 2) + 1000) * preview_height / 2000; - - if (focus_x != smdk4x12_camera->focus_x || force) { - smdk4x12_camera->focus_x = focus_x; - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_X, focus_x); - if (rc < 0) - ALOGE("%s: Unable to set object x position", __func__); - } - - if (focus_y != smdk4x12_camera->focus_y || force) { - smdk4x12_camera->focus_y = focus_y; - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_OBJECT_POSITION_Y, focus_y); - if (rc < 0) - ALOGE("%s: Unable to set object y position", __func__); - } - - focus_mode = FOCUS_MODE_TOUCH; - } - } - - focus_mode_string = smdk4x12_param_string_get(smdk4x12_camera, "focus-mode"); - if (focus_mode_string != NULL) { - if (focus_mode == 0) { - if (strcmp(focus_mode_string, "auto") == 0) - focus_mode = FOCUS_MODE_AUTO; - else if (strcmp(focus_mode_string, "infinity") == 0) - focus_mode = FOCUS_MODE_INFINITY; - else if (strcmp(focus_mode_string, "macro") == 0) - focus_mode = FOCUS_MODE_MACRO; - else if (strcmp(focus_mode_string, "fixed") == 0) - focus_mode = FOCUS_MODE_FIXED; - else if (strcmp(focus_mode_string, "facedetect") == 0) - focus_mode = FOCUS_MODE_FACEDETECT; - else if (strcmp(focus_mode_string, "continuous-video") == 0) - focus_mode = FOCUS_MODE_CONTINOUS_VIDEO; - else if (strcmp(focus_mode_string, "continuous-picture") == 0) - focus_mode = FOCUS_MODE_CONTINOUS_PICTURE; - else - focus_mode = FOCUS_MODE_AUTO; - } - - if (focus_mode != smdk4x12_camera->focus_mode || force) { - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_FOCUS_MODE, focus_mode); - if (rc < 0) - ALOGE("%s: Unable to set focus mode", __func__); - } - - smdk4x12_camera->focus_mode = focus_mode; - } - - // Zoom - - zoom_supported_string = smdk4x12_param_string_get(smdk4x12_camera, "zoom-supported"); - if (zoom_supported_string != NULL && strcmp(zoom_supported_string, "true") == 0) { - zoom = smdk4x12_param_int_get(smdk4x12_camera, "zoom"); - max_zoom = smdk4x12_param_int_get(smdk4x12_camera, "max-zoom"); - if (zoom <= max_zoom && zoom >= 0 && (zoom != smdk4x12_camera->zoom || force)) { - smdk4x12_camera->zoom = zoom; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_ZOOM, zoom); - if (rc < 0) - ALOGE("%s: Unable to set camera zoom", __func__); - } - - } - - // AE lock - - ae_lock_supported_string = smdk4x12_param_string_get(smdk4x12_camera, "auto-exposure-lock-supported"); - ae_lock_string = smdk4x12_param_string_get(smdk4x12_camera, "auto-exposure-lock"); - if (ae_lock_supported_string != NULL && ae_lock_string != NULL && strcmp(ae_lock_supported_string, "true") == 0 && strcmp(ae_lock_string, "true") == 0) - ae_lock = 1; - else - ae_lock = 0; - - // AWB lock - - awb_lock_supported_string = smdk4x12_param_string_get(smdk4x12_camera, "auto-whitebalance-lock-supported"); - awb_lock_string = smdk4x12_param_string_get(smdk4x12_camera, "auto-whitebalance-lock"); - if (awb_lock_supported_string != NULL && awb_lock_string != NULL && strcmp(awb_lock_supported_string, "true") == 0 && strcmp(awb_lock_string, "true") == 0) - awb_lock = 1; - else - awb_lock = 0; - - if (ae_lock != smdk4x12_camera->ae_lock || awb_lock != smdk4x12_camera->awb_lock || force) { - smdk4x12_camera->ae_lock = ae_lock; - smdk4x12_camera->awb_lock = awb_lock; - aeawb = (ae_lock ? 0x1 : 0x0) | (awb_lock ? 0x2 : 0x0); - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_AEAWB_LOCK_UNLOCK, aeawb); - if (rc < 0) - ALOGE("%s: Unable to set AEAWB lock", __func__); - } - - // Flash - - flash_mode_string = smdk4x12_param_string_get(smdk4x12_camera, "flash-mode"); - if (flash_mode_string != NULL) { - if (strcmp(flash_mode_string, "off") == 0) - flash_mode = FLASH_MODE_OFF; - else if (strcmp(flash_mode_string, "auto") == 0) - flash_mode = FLASH_MODE_AUTO; - else if (strcmp(flash_mode_string, "on") == 0) - flash_mode = FLASH_MODE_ON; - else if (strcmp(flash_mode_string, "torch") == 0) - flash_mode = FLASH_MODE_TORCH; - else - flash_mode = FLASH_MODE_AUTO; - - if (flash_mode != smdk4x12_camera->flash_mode || force) { - smdk4x12_camera->flash_mode = flash_mode; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_FLASH_MODE, flash_mode); - if (rc < 0) - ALOGE("%s:Unable to set flash mode", __func__); - } - } - - // Exposure - - exposure_compensation = smdk4x12_param_int_get(smdk4x12_camera, "exposure-compensation"); - min_exposure_compensation = smdk4x12_param_int_get(smdk4x12_camera, "min-exposure-compensation"); - max_exposure_compensation = smdk4x12_param_int_get(smdk4x12_camera, "max-exposure-compensation"); - - if (exposure_compensation <= max_exposure_compensation && exposure_compensation >= min_exposure_compensation && - (exposure_compensation != smdk4x12_camera->exposure_compensation || force)) { - smdk4x12_camera->exposure_compensation = exposure_compensation; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_BRIGHTNESS, exposure_compensation); - if (rc < 0) - ALOGE("%s: Unable to set exposure", __func__); - } - - // Antibanding - - antibanding_string = smdk4x12_param_string_get(smdk4x12_camera, "antibanding"); - if (antibanding_string != NULL) { - if (strcmp(antibanding_string, "auto") == 0) - antibanding = ANTI_BANDING_AUTO; - else if (strcmp(antibanding_string, "50hz") == 0) - antibanding = ANTI_BANDING_50HZ; - else if (strcmp(antibanding_string, "60hz") == 0) - antibanding = ANTI_BANDING_60HZ; - else if (strcmp(antibanding_string, "off") == 0) - antibanding = ANTI_BANDING_OFF; - else - antibanding = ANTI_BANDING_AUTO; - - if (antibanding != smdk4x12_camera->antibanding || force) { - smdk4x12_camera->antibanding = antibanding; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_ANTI_BANDING, antibanding); - if (rc < 0) - ALOGE("%s: Unable to set antibanding", __func__); - } - } - - // WB - - whitebalance_string = smdk4x12_param_string_get(smdk4x12_camera, "whitebalance"); - if (whitebalance_string != NULL) { - if (strcmp(whitebalance_string, "auto") == 0) - whitebalance = WHITE_BALANCE_AUTO; - else if (strcmp(whitebalance_string, "incandescent") == 0) - whitebalance = WHITE_BALANCE_TUNGSTEN; - else if (strcmp(whitebalance_string, "fluorescent") == 0) - whitebalance = WHITE_BALANCE_FLUORESCENT; - else if (strcmp(whitebalance_string, "daylight") == 0) - whitebalance = WHITE_BALANCE_SUNNY; - else if (strcmp(whitebalance_string, "cloudy-daylight") == 0) - whitebalance = WHITE_BALANCE_CLOUDY; - else - whitebalance = WHITE_BALANCE_AUTO; - - if (whitebalance != smdk4x12_camera->whitebalance || force) { - smdk4x12_camera->whitebalance = whitebalance; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_WHITE_BALANCE, whitebalance); - if (rc < 0) - ALOGE("%s: Unable to set whitebalance", __func__); - } - } - - // Scene mode - - scene_mode_string = smdk4x12_param_string_get(smdk4x12_camera, "scene-mode"); - if (scene_mode_string != NULL) { - if (strcmp(scene_mode_string, "auto") == 0) - scene_mode = SCENE_MODE_NONE; - else if (strcmp(scene_mode_string, "portrait") == 0) - scene_mode = SCENE_MODE_PORTRAIT; - else if (strcmp(scene_mode_string, "landscape") == 0) - scene_mode = SCENE_MODE_LANDSCAPE; - else if (strcmp(scene_mode_string, "night") == 0) - scene_mode = SCENE_MODE_NIGHTSHOT; - else if (strcmp(scene_mode_string, "beach") == 0) - scene_mode = SCENE_MODE_BEACH_SNOW; - else if (strcmp(scene_mode_string, "snow") == 0) - scene_mode = SCENE_MODE_BEACH_SNOW; - else if (strcmp(scene_mode_string, "sunset") == 0) - scene_mode = SCENE_MODE_SUNSET; - else if (strcmp(scene_mode_string, "fireworks") == 0) - scene_mode = SCENE_MODE_FIREWORKS; - else if (strcmp(scene_mode_string, "sports") == 0) - scene_mode = SCENE_MODE_SPORTS; - else if (strcmp(scene_mode_string, "party") == 0) - scene_mode = SCENE_MODE_PARTY_INDOOR; - else if (strcmp(scene_mode_string, "candlelight") == 0) - scene_mode = SCENE_MODE_CANDLE_LIGHT; - else if (strcmp(scene_mode_string, "dusk-dawn") == 0) - scene_mode = SCENE_MODE_DUSK_DAWN; - else if (strcmp(scene_mode_string, "fall-color") == 0) - scene_mode = SCENE_MODE_FALL_COLOR; - else if (strcmp(scene_mode_string, "back-light") == 0) - scene_mode = SCENE_MODE_BACK_LIGHT; - else if (strcmp(scene_mode_string, "text") == 0) - scene_mode = SCENE_MODE_TEXT; - else - scene_mode = SCENE_MODE_NONE; - - if (scene_mode != smdk4x12_camera->scene_mode || force) { - smdk4x12_camera->scene_mode = scene_mode; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, scene_mode); - if (rc < 0) - ALOGE("%s: Unable to set scene mode", __func__); - } - } - - // Effect - - effect_string = smdk4x12_param_string_get(smdk4x12_camera, "effect"); - if (effect_string != NULL) { - if (strcmp(effect_string, "auto") == 0) - effect = IMAGE_EFFECT_NONE; - if (strcmp(effect_string, "none") == 0) - effect = IMAGE_EFFECT_NONE; - else if (strcmp(effect_string, "mono") == 0) - effect = IMAGE_EFFECT_BNW; - else if (strcmp(effect_string, "negative") == 0) - effect = IMAGE_EFFECT_NEGATIVE; - else if (strcmp(effect_string, "sepia") == 0) - effect = IMAGE_EFFECT_SEPIA; - else if (strcmp(effect_string, "aqua") == 0) - effect = IMAGE_EFFECT_AQUA; - else if (strcmp(effect_string, "solarize") == 0) - effect = IMAGE_EFFECT_SOLARIZE; - else if (strcmp(effect_string, "posterize") == 0) - effect = IMAGE_EFFECT_POSTERIZE; - else if (strcmp(effect_string, "washed") == 0) - effect = IMAGE_EFFECT_WASHED; - else if (strcmp(effect_string, "sketch") == 0) - effect = IMAGE_EFFECT_SKETCH; - else if (strcmp(effect_string, "vintage-warm") == 0) - effect = IMAGE_EFFECT_VINTAGE_WARM; - else if (strcmp(effect_string, "vintage-cold") == 0) - effect = IMAGE_EFFECT_VINTAGE_COLD; - else if (strcmp(effect_string, "point-blue") == 0) - effect = IMAGE_EFFECT_POINT_BLUE; - else if (strcmp(effect_string, "point-red-yellow") == 0) - effect = IMAGE_EFFECT_POINT_RED_YELLOW; - else if (strcmp(effect_string, "point-green") == 0) - effect = IMAGE_EFFECT_POINT_GREEN; - else - effect = IMAGE_EFFECT_NONE; - - if (effect != smdk4x12_camera->effect || force) { - smdk4x12_camera->effect = effect; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_EFFECT, effect); - if (rc < 0) - ALOGE("%s: Unable to set effect", __func__); - } - } - - // ISO - - iso_string = smdk4x12_param_string_get(smdk4x12_camera, "iso"); - if (iso_string != NULL) { - if (strcmp(iso_string, "auto") == 0) - iso = ISO_AUTO; - else if (strcmp(iso_string, "ISO50") == 0) - iso = ISO_50; - else if (strcmp(iso_string, "ISO100") == 0) - iso = ISO_100; - else if (strcmp(iso_string, "ISO200") == 0) - iso = ISO_200; - else if (strcmp(iso_string, "ISO400") == 0) - iso = ISO_400; - else if (strcmp(iso_string, "ISO800") == 0) - iso = ISO_800; - else - iso = ISO_AUTO; - - if (iso != smdk4x12_camera->iso || force) { - smdk4x12_camera->iso = iso; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_ISO, iso); - if (rc < 0) - ALOGE("%s: Unable to set iso", __func__); - } - } - - // Image stabilization - - image_stabilization_string = smdk4x12_param_string_get(smdk4x12_camera, "image-stabilization"); - if (image_stabilization_string != NULL) { - if (strcmp(image_stabilization_string, "on") == 0) - image_stabilization = ANTI_SHAKE_STILL_ON; - else - image_stabilization = ANTI_SHAKE_OFF; - - if (image_stabilization != smdk4x12_camera->image_stabilization || force) { - smdk4x12_camera->image_stabilization = image_stabilization; - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_ANTI_SHAKE, image_stabilization); - if (rc < 0) - ALOGE("%s: Unable to set image-stabilization", __func__); - } - } - - ALOGD("%s: Preview size: %dx%d, picture size: %dx%d, recording size: %dx%d", __func__, preview_width, preview_height, picture_width, picture_height, recording_width, recording_height); - - return 0; -} - -// Capture - -int s5c73m3_interleaved_decode(void *data, int size, - void *yuv_data, int *yuv_size, int yuv_width, int yuv_height, - void *jpeg_data, int *jpeg_size, int *decoded, int *auto_focus_result, - int *exif_flash, int *exif_iso, int *exif_exposure, - int *exif_exposure_bias, int *exif_exposure_time) -{ - int yuv_length; - int jpeg_length; - unsigned char *yuv_p; - unsigned char *jpeg_p; - unsigned char *data_p; - unsigned int *offset_p; - unsigned int pointers_array_offset; - unsigned int pointers_array_size; - unsigned int interleaved_size; - unsigned char s5c73m3_auto_focus_result; - unsigned int yuv_offset_last; - unsigned int yuv_offset; - unsigned int yuv_line_size; - unsigned short *jpeg_start_p; - int gap; - unsigned int i; - - if (data == NULL || size <= 0 || yuv_data == NULL || yuv_size == NULL || yuv_width <= 0 || yuv_height <= 0 || jpeg_data == NULL || jpeg_size == NULL || decoded == NULL || auto_focus_result == NULL || exif_flash == NULL || exif_iso == NULL || exif_exposure == NULL || exif_exposure_bias == NULL || exif_exposure_time == NULL) - return -EINVAL; - - yuv_length = 0; - jpeg_length = 0; - - data_p = (unsigned char *) data; - data_p += size - 0x1000; // End of the first plane (interleaved buffer) - data_p += 4046; // Experimental offset for decoded - - *decoded = (int) *data_p; - - data_p = (unsigned char *) data; - data_p += size - 0x1000; // End of the first plane (interleaved buffer) - data_p += 50; // Experimental offset for auto-focus result - - s5c73m3_auto_focus_result = *data_p; - switch (s5c73m3_auto_focus_result) { - case S5C73M3_AF_STATUS_FOCUSING: - case S5C73M3_CAF_STATUS_FOCUSING: - *auto_focus_result = CAMERA_AF_STATUS_IN_PROGRESS; - break; - case S5C73M3_AF_STATUS_FOCUSED: - case S5C73M3_CAF_STATUS_FOCUSED: - *auto_focus_result = CAMERA_AF_STATUS_SUCCESS; - break; - case S5C73M3_AF_STATUS_INVALID: - case S5C73M3_CAF_STATUS_FIND_SEARCHING_DIR: - case S5C73M3_AF_STATUS_UNFOCUSED: - case S5C73M3_CAF_STATUS_UNFOCUSED: - default: - *auto_focus_result = CAMERA_AF_STATUS_FAIL; - break; - } - - data_p = (unsigned char *) data; - data_p += size - 0x1000; // End of the first plane (interleaved buffer) - data_p += 4; // EXIF flash offset - *exif_flash = (int) *data_p; - - data_p += 4; // EXIF ISO offset - *exif_iso = (int) ((data_p[1] << 8) | (data_p[0] & 0xff)); - - data_p += 4; // EXIF exposure offset - *exif_exposure = (int) *data_p; - - data_p += 4; // EXIF exposure bias offset - *exif_exposure_bias = (int) ((data_p[1] << 8) | (data_p[0] & 0xff)); - - data_p += 8; // EXIF exposure time offset - *exif_exposure_time = (int) ((data_p[1] << 8) | (data_p[0] & 0xff)); - - data_p = (unsigned char *) data; - data_p += size - 0x1000; // End of the first plane (interleaved buffer) - data_p += 4084; // Experimental offset for interleaved size - - // Read the pointers array offset - offset_p = (unsigned int *) data_p; - pointers_array_offset = BIG2LITTLE_ENDIAN(*offset_p); - interleaved_size = pointers_array_offset; - - // Read the pointers array size, it should be 4 * yuv_height - data_p += sizeof(pointers_array_offset); - offset_p = (unsigned int *) data_p; - pointers_array_size = BIG2LITTLE_ENDIAN(*offset_p); - - if (!*decoded) - return 0; - - ALOGD("%s: Interleaved pointers array is at offset 0x%x, 0x%x bytes long\n", __func__, pointers_array_offset, pointers_array_size); - - if ((int) pointers_array_offset > size || (int) pointers_array_size > size || (int) pointers_array_size < yuv_height * (int) sizeof(unsigned int)) { - ALOGE("%s: Invalid informations", __func__); - return -1; - } - - data_p = (unsigned char *) data; - data_p += pointers_array_offset; - yuv_p = (unsigned char *) yuv_data; - jpeg_p = (unsigned char *) jpeg_data; - jpeg_start_p = NULL; - - yuv_line_size = yuv_width * 2; - yuv_offset_last = 0; - yuv_offset = 0; - i = 0; - - while (i < pointers_array_size) { - offset_p = (unsigned int *) data_p; - yuv_offset = BIG2LITTLE_ENDIAN(*offset_p); - - if (yuv_offset > size - yuv_line_size) - return -1; - - gap = yuv_offset - yuv_offset_last - yuv_line_size; - - if (gap > 0) { - data_p = (unsigned char *) data + yuv_offset_last + yuv_line_size; - - if (jpeg_start_p == NULL) { - jpeg_start_p = (unsigned short *) data_p; - if (*jpeg_start_p != 0xd8ff) { - ALOGE("%s: Invalid jpeg start", __func__); - return -1; - } - } - - memcpy(jpeg_p, data_p, gap); - jpeg_p += gap; - jpeg_length += gap; - } - - yuv_offset_last = yuv_offset; - - data_p = (unsigned char *) data + yuv_offset; - memcpy(yuv_p, data_p, yuv_line_size); - yuv_p += yuv_line_size; - yuv_length += yuv_line_size; - - data_p = (unsigned char *) offset_p; - data_p += sizeof(yuv_offset); - i += sizeof(yuv_offset); - } - - gap = interleaved_size - yuv_offset_last - yuv_line_size; - - if (gap > 0) { - data_p = (unsigned char *) data + yuv_offset_last + yuv_line_size; - - memcpy(jpeg_p, data_p, gap); - jpeg_p += gap; - jpeg_length += gap; - } - - *yuv_size = yuv_length; - *jpeg_size = jpeg_length; - - return 0; -} - -int smdk4x12_camera_capture(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_camera_capture_listener *listener; - struct smdk4x12_camera_buffer *buffers = NULL; - struct smdk4x12_camera_buffer *buffer; - struct list_head *list; - int width, height, format; - int yuv_length, jpeg_length; - int jpeg_offset, jpeg_size; - int jpeg_thumbnail_offset, jpeg_thumbnail_size; - int buffers_count; - int buffer_length; - int auto_focus_result; - int decoded; - int busy; - void *pointer; - int address; - int offset; - int index; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - width = smdk4x12_camera->capture_width; - height = smdk4x12_camera->capture_height; - format = smdk4x12_camera->capture_format; - - buffers_count = smdk4x12_camera->capture_buffers_count; - buffer_length = smdk4x12_camera->capture_buffer_length; - - // V4L2 - - index = smdk4x12_v4l2_dqbuf_cap(smdk4x12_camera, 0); - if (index < 0 || index >= buffers_count) { - rc = smdk4x12_v4l2_poll(smdk4x12_camera, 0); - if (rc < 0) { - ALOGE("%s Unable to poll", __func__); - goto error; - } else if (rc == 0) { - // Timeout - rc = 0; - goto complete; - } - - index = smdk4x12_v4l2_dqbuf_cap(smdk4x12_camera, 0); - if (index < 0 || index >= buffers_count) { - ALOGE("%s: Unable to dequeue buffer", __func__); - goto error; - } - } - - smdk4x12_camera->capture_memory_index = index; - - address = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_PADDR_Y, index); - if (address == 0 || address == (int) 0xffffffff) { - ALOGE("%s: Unable to get address", __func__); - goto error; - } - - offset = address - smdk4x12_camera->capture_memory_address; - if (offset != index * buffer_length) - ALOGE("%s: Inconsistent memory offset (0x%x/0x%x)", __func__, offset, index * buffer_length); - - pointer = (void *) ((unsigned char *) smdk4x12_camera->capture_memory->data + offset); - - // Buffers - - switch (format) { - case V4L2_PIX_FMT_INTERLEAVED: - yuv_length = jpeg_length = 0; - auto_focus_result = decoded = 0; - - rc = s5c73m3_interleaved_decode(pointer, buffer_length, smdk4x12_camera->capture_yuv_buffer, &yuv_length, width, height, smdk4x12_camera->capture_jpeg_buffer, &jpeg_length, &decoded, &auto_focus_result, &smdk4x12_camera->capture_exif_flash, &smdk4x12_camera->capture_exif_iso, &smdk4x12_camera->capture_exif_exposure, &smdk4x12_camera->capture_exif_exposure_bias, &smdk4x12_camera->capture_exif_exposure_time); - if (rc < 0) { - ALOGE("%s: Unable to decode S5C73M3 interleaved", __func__); - goto error; - } - - if (auto_focus_result != smdk4x12_camera->auto_focus_result) { - if (!smdk4x12_camera->auto_focus_thread_enabled) { - smdk4x12_camera->auto_focus_result = auto_focus_result; - - rc = smdk4x12_camera_auto_focus(smdk4x12_camera, auto_focus_result); - if (rc < 0) { - ALOGE("%s: Unable to auto focus", __func__); - goto error; - } - } - } - - if (!decoded) { - buffers_count = 1; - buffers = (struct smdk4x12_camera_buffer *) calloc(buffers_count, sizeof(struct smdk4x12_camera_buffer)); - - buffer = buffers; - - buffer->pointer = pointer; - buffer->address = address; - buffer->length = smdk4x12_camera_buffer_length(width, height, V4L2_PIX_FMT_UYVY); - buffer->width = width; - buffer->height = height; - buffer->format = V4L2_PIX_FMT_UYVY; - } else { - buffers_count = 2; - buffers = (struct smdk4x12_camera_buffer *) calloc(buffers_count, sizeof(struct smdk4x12_camera_buffer)); - - buffer = buffers; - - memcpy(pointer, smdk4x12_camera->capture_yuv_buffer, yuv_length); - - buffer->pointer = pointer; - buffer->address = address; - buffer->length = yuv_length; - buffer->width = width; - buffer->height = height; - buffer->format = V4L2_PIX_FMT_UYVY; - - pointer = (void *) ((unsigned char *) pointer + yuv_length); - address += yuv_length; - buffer = (struct smdk4x12_camera_buffer *) ((unsigned char *) buffer + sizeof(struct smdk4x12_camera_buffer)); - - memcpy(pointer, smdk4x12_camera->capture_jpeg_buffer, jpeg_length); - - buffer->pointer = pointer; - buffer->address = address; - buffer->length = jpeg_length; - buffer->width = smdk4x12_camera->picture_width; - buffer->height = smdk4x12_camera->picture_height; - buffer->format = V4L2_PIX_FMT_JPEG; - - smdk4x12_camera->capture_hybrid = 0; - } - break; - case V4L2_PIX_FMT_JPEG: - jpeg_size = jpeg_offset = 0; - jpeg_thumbnail_size = jpeg_thumbnail_offset = 0; - - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAM_JPEG_MAIN_SIZE, &jpeg_size); - if (rc < 0 || jpeg_size <= 0) { - ALOGE("%s: Unable to get jpeg size", __func__); - goto error; - } - - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAM_JPEG_MAIN_OFFSET, &jpeg_offset); - if (rc < 0) { - ALOGE("%s: Unable to get jpeg offset", __func__); - goto error; - } - - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAM_JPEG_THUMB_SIZE, &jpeg_thumbnail_size); - if (rc < 0 || jpeg_thumbnail_size <= 0) { - ALOGE("%s: Unable to get jpeg thumbnail size", __func__); - goto error; - } - - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAM_JPEG_THUMB_OFFSET, &jpeg_thumbnail_offset); - if (rc < 0) { - ALOGE("%s: Unable to get jpeg thumbnail offset", __func__); - goto error; - } - - buffers_count = 2; - buffers = (struct smdk4x12_camera_buffer *) calloc(buffers_count, sizeof(struct smdk4x12_camera_buffer)); - - buffer = buffers; - - buffer->pointer = (void *) ((unsigned char *) pointer + jpeg_offset); - buffer->address = address + jpeg_offset; - buffer->length = jpeg_size; - buffer->width = smdk4x12_camera->picture_width; - buffer->height = smdk4x12_camera->picture_height; - buffer->format = V4L2_PIX_FMT_JPEG; - - buffer = (struct smdk4x12_camera_buffer *) ((unsigned char *) buffer + sizeof(struct smdk4x12_camera_buffer)); - - buffer->pointer = (void *) ((unsigned char *) pointer + jpeg_thumbnail_offset); - buffer->address = address + jpeg_thumbnail_offset; - buffer->length = jpeg_thumbnail_size; - buffer->width = smdk4x12_camera->jpeg_thumbnail_width; - buffer->height = smdk4x12_camera->jpeg_thumbnail_height; - buffer->format = V4L2_PIX_FMT_JPEG; - break; - default: - buffers_count = 1; - buffers = (struct smdk4x12_camera_buffer *) calloc(buffers_count, sizeof(struct smdk4x12_camera_buffer)); - - buffer = buffers; - - buffer->pointer = pointer; - buffer->address = address; - buffer->length = buffer_length; - buffer->width = width; - buffer->height = height; - buffer->format = format; - break; - } - - // Listeners - - list = (struct list_head *) smdk4x12_camera->capture_listeners; - while (list != NULL) { - listener = (struct smdk4x12_camera_capture_listener *) list; - - if (listener->callback == NULL) - goto list_continue_callback; - - /* - * Callback must never call a capture-locked function or it will - * block. Hence, do not unregister the listener in callback. - */ - - listener->callback(smdk4x12_camera, buffers, buffers_count); - -list_continue_callback: - list = list->next; - } - - do { - busy = 0; - - list = (struct list_head *) smdk4x12_camera->capture_listeners; - while (list != NULL) { - listener = (struct smdk4x12_camera_capture_listener *) list; - - if (listener->callback == NULL) - goto list_continue_busy; - - busy |= listener->busy; - -list_continue_busy: - list = list->next; - } - - if (busy) - usleep(1000); - } while (busy); - - rc = smdk4x12_v4l2_qbuf_cap(smdk4x12_camera, 0, index); - if (rc < 0) { - ALOGE("%s: Unable to queue buffer", __func__); - goto error; - } - - rc = 0; - goto complete; - -error: - rc = -1; - -complete: - if (buffers != NULL) - free(buffers); - - return rc; -} - -void *smdk4x12_camera_capture_thread(void *data) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - if (data == NULL) - return NULL; - - smdk4x12_camera = (struct smdk4x12_camera *) data; - - ALOGE("%s: Starting thread", __func__); - smdk4x12_camera->capture_thread_running = 1; - - while (smdk4x12_camera->capture_thread_enabled) { - pthread_mutex_lock(&smdk4x12_camera->capture_lock_mutex); - - while (smdk4x12_camera->capture_enabled) { - pthread_mutex_lock(&smdk4x12_camera->capture_mutex); - - if (!smdk4x12_camera->capture_enabled) { - pthread_mutex_unlock(&smdk4x12_camera->capture_mutex); - break; - } - - rc = smdk4x12_camera_capture(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to capture", __func__); - pthread_mutex_unlock(&smdk4x12_camera->capture_mutex); - break; - } - - pthread_mutex_unlock(&smdk4x12_camera->capture_mutex); - - // Wait a bit to let others lock the mutex if they need to - usleep(10); - } - } - - smdk4x12_camera->capture_thread_running = 0; - ALOGE("%s: Exiting thread", __func__); - - return NULL; -} - -int smdk4x12_camera_capture_thread_start(struct smdk4x12_camera *smdk4x12_camera) -{ - pthread_attr_t thread_attr; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->capture_thread_enabled) { - ALOGE("Capture thread was already started!"); - return -1; - } - - pthread_mutex_init(&smdk4x12_camera->capture_mutex, NULL); - pthread_mutex_init(&smdk4x12_camera->capture_lock_mutex, NULL); - - // Initial lock - pthread_mutex_lock(&smdk4x12_camera->capture_lock_mutex); - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - - smdk4x12_camera->capture_thread_enabled = 1; - - rc = pthread_create(&smdk4x12_camera->capture_thread, &thread_attr, smdk4x12_camera_capture_thread, (void *) smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to create thread", __func__); - goto error; - } - - rc = 0; - goto complete; - -error: - pthread_mutex_destroy(&smdk4x12_camera->capture_mutex); - pthread_mutex_destroy(&smdk4x12_camera->capture_lock_mutex); - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_capture_thread_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - int i; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->capture_thread_enabled) { - ALOGE("Capture thread was already stopped!"); - return; - } - - smdk4x12_camera->capture_enabled = 0; - smdk4x12_camera->capture_thread_enabled = 0; - - pthread_mutex_unlock(&smdk4x12_camera->capture_lock_mutex); - - // Wait for the thread to end - i = 0; - while (smdk4x12_camera->capture_thread_running) { - if (i++ > 10000) { - ALOGE("Capture thread is taking too long to end, something is going wrong"); - break; - } - usleep(100); - } - - if (smdk4x12_camera->capture_enabled) { - pthread_mutex_lock(&smdk4x12_camera->capture_mutex); - smdk4x12_camera_capture_stop(smdk4x12_camera); - pthread_mutex_unlock(&smdk4x12_camera->capture_mutex); - } - - pthread_mutex_destroy(&smdk4x12_camera->capture_mutex); - pthread_mutex_destroy(&smdk4x12_camera->capture_lock_mutex); -} - -int smdk4x12_camera_capture_start(struct smdk4x12_camera *smdk4x12_camera) -{ - struct v4l2_streamparm fps_param; - int width, height, format; - int mbus_width, mbus_height; - int buffers_count, buffer_length; - camera_memory_t *memory = NULL; - int value; - int fd; - int rc; - int i; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->capture_enabled) { - ALOGE("Capture was already started!"); - return -1; - } - - width = smdk4x12_camera->capture_width; - height = smdk4x12_camera->capture_height; - format = smdk4x12_camera->capture_format; - - // V4L2 - - if (format == V4L2_PIX_FMT_INTERLEAVED) { - ALOGD("Enabling hybrid capture"); - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_HYBRID, 1); - if (rc < 0) { - ALOGE("%s: Unable to set hybrid", __func__); - goto error; - } - } - - if (smdk4x12_camera->camera_fimc_is) { - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_IS_S_FORMAT_SCENARIO, smdk4x12_camera->fimc_is_mode); - if (rc < 0) { - ALOGE("%s: Unable to set FIMC-IS scenario", __func__); - goto error; - } - } - - rc = smdk4x12_v4l2_enum_fmt_cap(smdk4x12_camera, 0, format); - if (rc < 0) { - ALOGE("%s: Unable to enumerate formats", __func__); - goto error; - } - - mbus_width = width; - mbus_height = height; - - if (smdk4x12_camera->camera_mbus_resolutions != NULL) { - for (i = 0; i < smdk4x12_camera->camera_mbus_resolutions_count; i++) { - if (smdk4x12_camera->camera_mbus_resolutions[i].width == width && smdk4x12_camera->camera_mbus_resolutions[i].height == height) { - mbus_width = smdk4x12_camera->camera_mbus_resolutions[i].mbus_width; - mbus_height = smdk4x12_camera->camera_mbus_resolutions[i].mbus_height; - break; - } - } - } - - if (smdk4x12_camera->camera_fimc_is) { - // Set MBUS width/height/format - rc = smdk4x12_v4l2_s_fmt_pix(smdk4x12_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, smdk4x12_camera->fimc_is_mode, V4L2_PIX_FMT_MODE_PREVIEW); - if (rc < 0) { - ALOGE("%s: Unable to set MBUS capture pixel format", __func__); - goto error; - } - } - - rc = smdk4x12_v4l2_s_fmt_pix_cap(smdk4x12_camera, 0, width, height, format, V4L2_PIX_FMT_MODE_PREVIEW); - if (rc < 0) { - ALOGE("%s: Unable to set capture pixel format", __func__); - goto error; - } - - if (!smdk4x12_camera->camera_fimc_is) { - // Set MBUS width/height/format - rc = smdk4x12_v4l2_s_fmt_pix(smdk4x12_camera, 0, V4L2_BUF_TYPE_PRIVATE, mbus_width, mbus_height, format, V4L2_FIELD_NONE, V4L2_PIX_FMT_MODE_PREVIEW); - if (rc < 0) { - ALOGE("%s: Unable to set MBUS capture pixel format", __func__); - goto error; - } - } - - if (format == V4L2_PIX_FMT_INTERLEAVED) - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CACHEABLE, 0); - else - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CACHEABLE, 1); - if (rc < 0) { - ALOGE("%s: Unable to set cacheable", __func__); - goto error; - } - - if (smdk4x12_camera->camera_fimc_is) { - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_IS_S_SCENARIO_MODE, smdk4x12_camera->fimc_is_mode); - if (rc < 0) { - ALOGE("%s: Unable to set FIMC-IS scenario mode", __func__); - goto error; - } - } - - if (format == V4L2_PIX_FMT_INTERLEAVED) { - // This must be set to 1 for interleaved data decoding - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_EMBEDDEDDATA_ENABLE, 1); - if (rc < 0) { - ALOGE("%s: Unable to set embdedded data enable", __func__); - goto error; - } - } - - // Let's assume FIMC0 has memory available through mmap - - for (i = SMDK4x12_CAMERA_CAPTURE_BUFFERS_COUNT; i > 0; i--) { - rc = smdk4x12_v4l2_reqbufs_cap(smdk4x12_camera, 0, i); - if (rc >= 0) - break; - } - - if (rc < 0) { - ALOGE("%s: Unable to request buffers", __func__); - goto error; - } - - buffers_count = rc; - ALOGD("Found %d buffers available for capture!", buffers_count); - - memset(&fps_param, 0, sizeof(fps_param)); - fps_param.parm.capture.timeperframe.numerator = 1; - fps_param.parm.capture.timeperframe.denominator = smdk4x12_camera->preview_fps; - - rc = smdk4x12_v4l2_s_parm_cap(smdk4x12_camera, 0, &fps_param); - if (rc < 0) { - ALOGE("%s: Unable to set fps", __func__); - goto error; - } - - for (i = 0; i < buffers_count; i++) { - rc = smdk4x12_v4l2_querybuf_cap(smdk4x12_camera, 0, i); - if (rc < 0) { - ALOGE("%s: Unable to query buffers", __func__); - goto error; - } - } - - buffer_length = rc; - - value = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_PADDR_Y, 0); - if (value == 0 || value == (int) 0xffffffff) { - ALOGE("%s: Unable to get address", __func__); - goto error; - } - - smdk4x12_camera->capture_memory_address = value; - - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - fd = smdk4x12_v4l2_fd(smdk4x12_camera, 0); - if (fd < 0) { - ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, 0); - goto error; - } - - smdk4x12_camera->capture_memory = NULL; - - memory = smdk4x12_camera->callbacks.request_memory(fd, buffer_length, buffers_count, smdk4x12_camera->callbacks.user); - if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { - ALOGE("%s: Unable to request memory", __func__); - goto error; - } - - smdk4x12_camera->capture_memory = memory; - } else { - ALOGE("%s: No memory request function!", __func__); - goto error; - } - - if (format == V4L2_PIX_FMT_INTERLEAVED) { - smdk4x12_camera->capture_yuv_buffer = malloc(buffer_length); - smdk4x12_camera->capture_jpeg_buffer = malloc(buffer_length); - } - - for (i = 0; i < buffers_count; i++) { - rc = smdk4x12_v4l2_qbuf_cap(smdk4x12_camera, 0, i); - if (rc < 0) { - ALOGE("%s: Unable to queue buffer", __func__); - goto error; - } - } - - smdk4x12_camera->capture_buffers_count = buffers_count; - smdk4x12_camera->capture_buffer_length = buffer_length; - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_ROTATION, - smdk4x12_camera->camera_rotation); - if (rc < 0) { - ALOGE("%s: Unable to set rotation", __func__); - goto error; - } - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_HFLIP, - smdk4x12_camera->camera_hflip); - if (rc < 0) { - ALOGE("%s: Unable to set hflip", __func__); - goto error; - } - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_VFLIP, - smdk4x12_camera->camera_vflip); - if (rc < 0) { - ALOGE("%s: Unable to set vflip", __func__); - goto error; - } - - rc = smdk4x12_v4l2_streamon_cap(smdk4x12_camera, 0); - if (rc < 0) { - ALOGE("%s: Unable to start stream", __func__); - goto error; - } - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_SCENE_MODE, smdk4x12_camera->scene_mode); - if (rc < 0) { - ALOGE("%s: Unable to set scene mode", __func__); - goto error; - } - - smdk4x12_camera->capture_enabled = 1; - pthread_mutex_unlock(&smdk4x12_camera->capture_lock_mutex); - - rc = 0; - goto complete; - -error: - if (smdk4x12_camera->capture_memory != NULL && smdk4x12_camera->capture_memory->release != NULL) { - smdk4x12_camera->capture_memory->release(smdk4x12_camera->capture_memory); - smdk4x12_camera->capture_memory = NULL; - } - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_capture_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - int rc; - int i; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->capture_enabled) { - ALOGE("Capture was already stopped!"); - return; - } - - if (smdk4x12_camera->capture_format == V4L2_PIX_FMT_INTERLEAVED) { - ALOGD("Disabling hybrid capture"); - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_HYBRID, 0); - if (rc < 0) - ALOGE("%s: Unable to set hybrid", __func__); - } - - rc = smdk4x12_v4l2_streamoff_cap(smdk4x12_camera, 0); - if (rc < 0) { - ALOGE("%s: Unable to stop stream", __func__); - } - - if (smdk4x12_camera->capture_memory != NULL && smdk4x12_camera->capture_memory->release != NULL) { - smdk4x12_camera->capture_memory->release(smdk4x12_camera->capture_memory); - smdk4x12_camera->capture_memory = NULL; - } - - if (smdk4x12_camera->capture_yuv_buffer != NULL) { - free(smdk4x12_camera->capture_yuv_buffer); - smdk4x12_camera->capture_yuv_buffer = NULL; - } - - if (smdk4x12_camera->capture_jpeg_buffer != NULL) { - free(smdk4x12_camera->capture_jpeg_buffer); - smdk4x12_camera->capture_jpeg_buffer = NULL; - } - - smdk4x12_camera->capture_enabled = 0; -} - -int smdk4x12_camera_capture_setup(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_camera_capture_listener *listener; - struct list_head *list; - int width, height, format; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - // No listener left - if (smdk4x12_camera->capture_listeners == NULL && smdk4x12_camera->capture_enabled) { - smdk4x12_camera_capture_stop(smdk4x12_camera); - return 0; - } - - width = height = format = 0; - - list = (struct list_head *) smdk4x12_camera->capture_listeners; - while (list != NULL) { - listener = (struct smdk4x12_camera_capture_listener *) list; - - // Interleaved format already has the correct width and height for picture set through ioctl - if (smdk4x12_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED) - if (listener->format == V4L2_PIX_FMT_JPEG || listener->format == V4L2_PIX_FMT_INTERLEAVED) - goto list_continue; - - if (listener->width >= width && listener->height >= height) { - width = listener->width; - height = listener->height; - format = listener->format; - } - -list_continue: - list = list->next; - } - - // Override the capture format - if (smdk4x12_camera->camera_capture_format) - format = smdk4x12_camera->camera_capture_format; - - // Only picture is listening, but we need some preview size anyway - if (format == V4L2_PIX_FMT_INTERLEAVED && (width == 0 || height == 0)) { - width = smdk4x12_camera->preview_width; - height = smdk4x12_camera->preview_height; - } - - ALOGD("%s: Selected width: %d, height: %d, format: 0x%x", __func__, width, height, format); - - if (!smdk4x12_camera->capture_enabled) { - smdk4x12_camera->capture_width = width; - smdk4x12_camera->capture_height = height; - smdk4x12_camera->capture_format = format; - - rc = smdk4x12_camera_capture_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start capture", __func__); - return -1; - } - } else if (smdk4x12_camera->capture_width != width || smdk4x12_camera->capture_height != height || smdk4x12_camera->capture_format != format) { - smdk4x12_camera_capture_stop(smdk4x12_camera); - - smdk4x12_camera->capture_width = width; - smdk4x12_camera->capture_height = height; - smdk4x12_camera->capture_format = format; - - rc = smdk4x12_camera_capture_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start capture", __func__); - return -1; - } - } - - return 0; -} - -struct smdk4x12_camera_capture_listener *smdk4x12_camera_capture_listener_register( - struct smdk4x12_camera *smdk4x12_camera, int width, int height, int format, - int (*callback)(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_camera_buffer *buffers, int buffers_count)) -{ - struct smdk4x12_camera_capture_listener *listener = NULL; - struct list_head *list_end; - struct list_head *list; - int rc; - - if (smdk4x12_camera == NULL || callback == NULL) - return NULL; - - pthread_mutex_lock(&smdk4x12_camera->capture_mutex); - - listener = calloc(1, sizeof(struct smdk4x12_camera_capture_listener)); - if (listener == NULL) - goto error; - - listener->width = width; - listener->height = height; - listener->format = format; - listener->callback = callback; - listener->busy = 0; - - list_end = (struct list_head *) smdk4x12_camera->capture_listeners; - while (list_end != NULL && list_end->next != NULL) - list_end = list_end->next; - - list = (struct list_head *) listener; - list_head_insert(list, list_end, NULL); - - if (smdk4x12_camera->capture_listeners == NULL) - smdk4x12_camera->capture_listeners = listener; - - rc = smdk4x12_camera_capture_setup(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to setup capture", __func__); - goto error; - } - - rc = 0; - goto complete; - -error: - listener = NULL; - -complete: - pthread_mutex_unlock(&smdk4x12_camera->capture_mutex); - - return listener; -} - -void smdk4x12_camera_capture_listener_unregister( - struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_capture_listener *listener) -{ - struct list_head *list; - int rc; - - if (smdk4x12_camera == NULL || listener == NULL) - return; - - pthread_mutex_lock(&smdk4x12_camera->capture_mutex); - - list = (struct list_head *) smdk4x12_camera->capture_listeners; - while (list != NULL) { - if ((void *) list == (void *) listener) { - list_head_remove(list); - - if ((void *) list == (void *) smdk4x12_camera->capture_listeners) - smdk4x12_camera->capture_listeners = (struct smdk4x12_camera_capture_listener *) list->next; - - memset(listener, 0, sizeof(struct smdk4x12_camera_capture_listener)); - free(listener); - - break; - } -list_continue: - list = list->next; - } - - rc = smdk4x12_camera_capture_setup(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to setup capture", __func__); - goto complete; - } - -complete: - pthread_mutex_unlock(&smdk4x12_camera->capture_mutex); -} - -// Preview - -int smdk4x12_camera_preview_output_start(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->preview_output_enabled) { - ALOGE("Preview was already started!"); - return -1; - } - - output = &smdk4x12_camera->preview_output; - - memset(output, 0, sizeof(struct smdk4x12_v4l2_output)); - output->v4l2_id = 1; - output->width = smdk4x12_camera->preview_width; - output->height = smdk4x12_camera->preview_height; - output->format = smdk4x12_camera->preview_format; - output->buffer_width = smdk4x12_camera->preview_buffer.width; - output->buffer_height = smdk4x12_camera->preview_buffer.height; - output->buffer_format = smdk4x12_camera->preview_buffer.format; - output->buffers_count = SMDK4x12_CAMERA_PREVIEW_BUFFERS_COUNT; - - rc = smdk4x12_v4l2_output_start(smdk4x12_camera, output); - if (rc < 0) { - ALOGE("%s: Unable to start preview output", __func__); - goto error; - } - - smdk4x12_camera->preview_output_enabled = 1; - - rc = 0; - goto complete; - -error: - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_preview_output_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->preview_output_enabled) { - ALOGE("Preview was already stopped!"); - return; - } - - output = &smdk4x12_camera->preview_output; - - smdk4x12_v4l2_output_stop(smdk4x12_camera, output); - - smdk4x12_camera->preview_output_enabled = 0; -} - -int smdk4x12_camera_preview_callback(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_buffer *buffers, int buffers_count) -{ - struct smdk4x12_camera_buffer *buffer = NULL; - int width, height, format; - int buffer_width, buffer_height, buffer_format; - int rc; - int i; - - if (smdk4x12_camera == NULL || buffers == NULL || buffers_count <= 0) - return -EINVAL; - -// ALOGD("%s()", __func__); - - if (smdk4x12_camera->preview_listener == NULL) - return -1; - - if (smdk4x12_camera->preview_listener->busy) { - ALOGE("%s: Dropping buffer", __func__); - return 0; - } - - if (smdk4x12_camera->preview_listener->width != smdk4x12_camera->preview_width || smdk4x12_camera->preview_listener->height != smdk4x12_camera->preview_height || smdk4x12_camera->preview_listener->format != smdk4x12_camera->preview_format) { - ALOGD("%s: Waiting for preview listener update", __func__); - pthread_mutex_unlock(&smdk4x12_camera->preview_lock_mutex); - return 0; - } - - smdk4x12_camera->preview_listener->busy = 1; - - width = smdk4x12_camera->preview_width; - height = smdk4x12_camera->preview_height; - format = smdk4x12_camera->preview_format; - - for (i = 0; i < buffers_count; i++) { - if (buffers->format == V4L2_PIX_FMT_JPEG) - goto buffers_continue; - - if (buffers->format == V4L2_PIX_FMT_INTERLEAVED) - goto buffers_continue; - - // Optimal buffer - if (buffers->width == width && buffers->height == height) { - buffer = buffers; - break; - } - - // Might-work buffer, but not optimal - buffer = buffers; - -buffers_continue: - buffers = (struct smdk4x12_camera_buffer *) ((unsigned char *) buffers + sizeof(struct smdk4x12_camera_buffer)); - } - - if (buffer == NULL) { - ALOGE("%s: Unable to find an appropriate buffer for preview", __func__); - smdk4x12_camera->preview_listener->busy = 0; - return 0; - } - - buffer_width = buffer->width; - buffer_height = buffer->height; - buffer_format = buffer->format; - - pthread_mutex_lock(&smdk4x12_camera->preview_mutex); - - if (buffer_width != width || buffer_height != height || buffer_format != format) { - if (!smdk4x12_camera->preview_output_enabled) { - memcpy(&smdk4x12_camera->preview_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - - rc = smdk4x12_camera_preview_output_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start preview", __func__); - goto error; - } - } else if (smdk4x12_camera->preview_buffer.width != buffer_width || smdk4x12_camera->preview_buffer.height != buffer_height || smdk4x12_camera->preview_buffer.format != buffer_format) { - smdk4x12_camera_preview_output_stop(smdk4x12_camera); - - memcpy(&smdk4x12_camera->preview_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - - rc = smdk4x12_camera_preview_output_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start preview", __func__); - goto error; - } - } else { - memcpy(&smdk4x12_camera->preview_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - } - } else { - // The buffer format exactly matches our expectations - - if (smdk4x12_camera->preview_output_enabled) - smdk4x12_camera_preview_output_stop(smdk4x12_camera); - - memcpy(&smdk4x12_camera->preview_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - } - - pthread_mutex_unlock(&smdk4x12_camera->preview_lock_mutex); - - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - - rc = 0; - goto complete; - -error: - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - - smdk4x12_camera->preview_listener->busy = 0; - - rc = -1; - -complete: - return rc; -} - -int smdk4x12_camera_preview(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - int width, height, format; - buffer_handle_t *window_buffer; - void *window_data; - int window_stride; - camera_memory_t *memory; - void *memory_pointer; - int memory_index; - int memory_size; - int rc; - - if (smdk4x12_camera == NULL) - goto error; - -// ALOGD("%s()", __func__); - - width = smdk4x12_camera->preview_width; - height = smdk4x12_camera->preview_height; - format = smdk4x12_camera->preview_format; - - output = &smdk4x12_camera->preview_output; - - if (smdk4x12_camera->preview_output_enabled) { - rc = smdk4x12_v4l2_output(smdk4x12_camera, output, smdk4x12_camera->preview_buffer.address); - if (rc < 0) { - ALOGE("%s: Unable to output preview", __func__); - goto error; - } - - memory = output->memory; - memory_index = output->memory_index; - memory_pointer = (void *) ((unsigned char *) memory->data + output->buffer_length * memory_index); - memory_size = output->buffer_length; - } else { - // In that case, we can directly use the capture memory - memory = smdk4x12_camera->capture_memory; - memory_index = smdk4x12_camera->capture_memory_index; - memory_pointer = smdk4x12_camera->preview_buffer.pointer; - memory_size = smdk4x12_camera->preview_buffer.length; - } - - if (smdk4x12_camera->preview_window != NULL && smdk4x12_camera->gralloc != NULL) { - smdk4x12_camera->preview_window->dequeue_buffer(smdk4x12_camera->preview_window, &window_buffer, &window_stride); - smdk4x12_camera->gralloc->lock(smdk4x12_camera->gralloc, *window_buffer, GRALLOC_USAGE_SW_WRITE_OFTEN, 0, 0, width, height, &window_data); - - if (window_data == NULL) { - ALOGE("%s: Unable to lock gralloc", __func__); - goto error; - } - - memcpy(window_data, memory_pointer, memory_size); - - smdk4x12_camera->gralloc->unlock(smdk4x12_camera->gralloc, *window_buffer); - smdk4x12_camera->preview_window->enqueue_buffer(smdk4x12_camera->preview_window, window_buffer); - } - - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_PREVIEW_FRAME) && SMDK4x12_CAMERA_CALLBACK_DEFINED(data) && !smdk4x12_camera->callback_lock) { - smdk4x12_camera->callbacks.data(CAMERA_MSG_PREVIEW_FRAME, memory, memory_index, NULL, smdk4x12_camera->callbacks.user); - } - - if (smdk4x12_camera->preview_output_enabled) { - rc = smdk4x12_v4l2_output_release(smdk4x12_camera, output); - if (rc < 0) { - ALOGE("%s: Unable to release preview output", __func__); - goto error; - } - } - - rc = 0; - goto complete; - -error: - rc = -1; - -complete: - smdk4x12_camera->preview_listener->busy = 0; - - return rc; -} - -void *smdk4x12_camera_preview_thread(void *data) -{ - struct smdk4x12_camera *smdk4x12_camera; - struct smdk4x12_camera_capture_listener *listener; - int gralloc_format; - int rc; - - if (data == NULL) - return NULL; - - smdk4x12_camera = (struct smdk4x12_camera *) data; - - ALOGE("%s: Starting thread", __func__); - smdk4x12_camera->preview_thread_running = 1; - - while (smdk4x12_camera->preview_thread_enabled) { - pthread_mutex_lock(&smdk4x12_camera->preview_lock_mutex); - - pthread_mutex_lock(&smdk4x12_camera->preview_mutex); - - if (smdk4x12_camera->preview_listener == NULL) { - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - break; - } - - if (smdk4x12_camera->preview_listener->busy) { - rc = smdk4x12_camera_preview(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to preview", __func__); - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - break; - } - } - - if (smdk4x12_camera->preview_listener->width != smdk4x12_camera->preview_width || smdk4x12_camera->preview_listener->height != smdk4x12_camera->preview_height || smdk4x12_camera->preview_listener->format != smdk4x12_camera->preview_format) { - if (smdk4x12_camera->preview_output_enabled) - smdk4x12_camera_preview_output_stop(smdk4x12_camera); - - smdk4x12_camera_capture_listener_unregister(smdk4x12_camera, smdk4x12_camera->preview_listener); - - smdk4x12_camera->preview_listener = NULL; - - listener = smdk4x12_camera_capture_listener_register(smdk4x12_camera, smdk4x12_camera->preview_width, smdk4x12_camera->preview_height, smdk4x12_camera->preview_format, smdk4x12_camera_preview_callback); - if (listener == NULL) { - ALOGE("%s: Unable to register preview capture listener", __func__); - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - break; - } - - smdk4x12_camera->preview_listener = listener; - - gralloc_format = smdk4x12_gralloc_format(smdk4x12_camera->preview_format); - - rc = smdk4x12_camera->preview_window->set_buffers_geometry(smdk4x12_camera->preview_window, smdk4x12_camera->preview_width, smdk4x12_camera->preview_height, gralloc_format); - if (rc) { - ALOGE("%s: Unable to set buffers geometry", __func__); - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - break; - } - } - - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - } - - smdk4x12_camera->preview_thread_running = 0; - ALOGE("%s: Exiting thread", __func__); - - return NULL; -} - -int smdk4x12_camera_preview_thread_start(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_camera_capture_listener *listener; - pthread_attr_t thread_attr; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->preview_thread_enabled) { - ALOGE("Preview thread was already started!"); - return -1; - } - - pthread_mutex_init(&smdk4x12_camera->preview_mutex, NULL); - pthread_mutex_init(&smdk4x12_camera->preview_lock_mutex, NULL); - - // Initial lock - pthread_mutex_lock(&smdk4x12_camera->preview_lock_mutex); - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - - smdk4x12_camera->preview_thread_enabled = 1; - - rc = pthread_create(&smdk4x12_camera->preview_thread, &thread_attr, smdk4x12_camera_preview_thread, (void *) smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to create thread", __func__); - goto error; - } - - listener = smdk4x12_camera_capture_listener_register(smdk4x12_camera, smdk4x12_camera->preview_width, smdk4x12_camera->preview_height, smdk4x12_camera->preview_format, smdk4x12_camera_preview_callback); - if (listener == NULL) { - ALOGE("%s: Unable to register preview capture listener", __func__); - goto error; - } - - smdk4x12_camera->preview_listener = listener; - - rc = 0; - goto complete; - -error: - pthread_mutex_destroy(&smdk4x12_camera->preview_mutex); - pthread_mutex_destroy(&smdk4x12_camera->preview_lock_mutex); - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_preview_thread_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - int i; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->preview_thread_enabled) { - ALOGE("Preview thread was already stopped!"); - return; - } - - if (smdk4x12_camera->preview_listener != NULL) { - smdk4x12_camera_capture_listener_unregister(smdk4x12_camera, smdk4x12_camera->preview_listener); - smdk4x12_camera->preview_listener = NULL; - } - - smdk4x12_camera->preview_thread_enabled = 0; - - pthread_mutex_unlock(&smdk4x12_camera->preview_lock_mutex); - - // Wait for the thread to end - i = 0; - while (smdk4x12_camera->preview_thread_running) { - if (i++ > 10000) { - ALOGE("Preview thread is taking too long to end, something is going wrong"); - break; - } - usleep(100); - } - - if (smdk4x12_camera->preview_output_enabled) { - pthread_mutex_lock(&smdk4x12_camera->preview_mutex); - smdk4x12_camera_preview_output_stop(smdk4x12_camera); - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - } - - pthread_mutex_destroy(&smdk4x12_camera->preview_mutex); - pthread_mutex_destroy(&smdk4x12_camera->preview_lock_mutex); - - // Invalidate the preview window - smdk4x12_camera->preview_window = NULL; -} - -// Picture - -int smdk4x12_camera_picture_callback(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_buffer *buffers, int buffers_count) -{ - struct smdk4x12_camera_buffer *jpeg_buffer = NULL; - struct smdk4x12_camera_buffer *jpeg_thumbnail_buffer = NULL; - struct smdk4x12_camera_buffer *yuv_buffer = NULL; - struct smdk4x12_camera_buffer *yuv_thumbnail_buffer = NULL; - int width, height; - int thumbnail_width, thumbnail_height; - time_t timestamp; - int rc; - int i; - - if (smdk4x12_camera == NULL || buffers == NULL || buffers_count <= 0) - return -EINVAL; - - ALOGD("%s()", __func__); - - width = smdk4x12_camera->picture_width; - height = smdk4x12_camera->picture_height; - thumbnail_width = smdk4x12_camera->jpeg_thumbnail_width; - thumbnail_height = smdk4x12_camera->jpeg_thumbnail_height; - - if (smdk4x12_camera->picture_completed) - return -1; - - if (smdk4x12_camera->picture_listener == NULL) - return -1; - - if (smdk4x12_camera->picture_listener->busy) { - ALOGE("%s: Dropping buffer", __func__); - return 0; - } - - ALOGE("%s: locking picture_mutex", __func__); - pthread_mutex_lock(&smdk4x12_camera->picture_mutex); - ALOGE("%s: locked picture_mutex", __func__); - - if (!smdk4x12_camera->picture_enabled && !smdk4x12_camera->camera_fimc_is) { - if (smdk4x12_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED && smdk4x12_camera->zoom == 0 && smdk4x12_camera->focus_mode == FOCUS_MODE_CONTINOUS_PICTURE) { - if (smdk4x12_camera->auto_focus_result == CAMERA_AF_STATUS_FAIL) { - // We don't want to take a picture out of focus, so wait a bit - timestamp = time(NULL); - - if (smdk4x12_camera->picture_focus_timestamp > 0) { - if ((timestamp - smdk4x12_camera->picture_focus_timestamp) > 2) { - ALOGE("%s: Picture will be taken out of focus", __func__); - } else { - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - return 0; - } - } else { - smdk4x12_camera->picture_focus_timestamp = timestamp; - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - return 0; - } - } else if (smdk4x12_camera->auto_focus_result == CAMERA_AF_STATUS_IN_PROGRESS) { - ALOGD("%s: Not asking for picture until auto focus is done", __func__); - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - return 0; - } - } - - smdk4x12_camera->picture_focus_timestamp = 0; - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_CAPTURE, 0); - if (rc < 0) { - ALOGE("%s: Unable to set capture", __func__); - goto error; - } - - if (smdk4x12_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED && !smdk4x12_camera->capture_hybrid) { - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_HYBRID_CAPTURE, 1); - if (rc < 0) { - ALOGE("%s: Unable to set hybrid capture", __func__); - goto error; - } - - smdk4x12_camera->capture_hybrid = 1; - } - - smdk4x12_camera->picture_enabled = 1; - - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - return 0; - } - - ALOGE("%s: unlocking picture_mutex", __func__); - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - ALOGE("%s: unlocked picture_mutex", __func__); - - smdk4x12_camera->picture_listener->busy = 1; - - // Let's assume the picture format is JPEG - - for (i = 0; i < buffers_count; i++) { - if (buffers->format == V4L2_PIX_FMT_JPEG) { - if (buffers->width == width && buffers->height == height) - jpeg_buffer = buffers; - else if (buffers->width == thumbnail_width && buffers->height == thumbnail_height) - jpeg_thumbnail_buffer = buffers; - } else { - if (buffers->width >= width && buffers->height >= height) - yuv_buffer = buffers; - if (buffers->width >= thumbnail_width && buffers->height >= thumbnail_height) - yuv_thumbnail_buffer = buffers; - } - -buffers_continue: - buffers = (struct smdk4x12_camera_buffer *) ((unsigned char *) buffers + sizeof(struct smdk4x12_camera_buffer)); - } - - if (jpeg_buffer == NULL && yuv_buffer == NULL) { - ALOGE("%s: Unable to find an appropriate buffer for picture", __func__); - smdk4x12_camera->picture_listener->busy = 0; - return 0; - } - - // Interleaved must not use a preview frame as picture - if (smdk4x12_camera->camera_capture_format == V4L2_PIX_FMT_INTERLEAVED && jpeg_buffer == NULL) { - smdk4x12_camera->picture_listener->busy = 0; - return 0; - } - - pthread_mutex_lock(&smdk4x12_camera->picture_mutex); - - if (jpeg_buffer == NULL) - memset(&smdk4x12_camera->picture_jpeg_buffer, 0, sizeof(smdk4x12_camera->picture_jpeg_buffer)); - else - memcpy(&smdk4x12_camera->picture_jpeg_buffer, jpeg_buffer, sizeof(struct smdk4x12_camera_buffer)); - - if (jpeg_thumbnail_buffer == NULL) - memset(&smdk4x12_camera->picture_jpeg_thumbnail_buffer, 0, sizeof(smdk4x12_camera->picture_jpeg_thumbnail_buffer)); - else - memcpy(&smdk4x12_camera->picture_jpeg_thumbnail_buffer, jpeg_thumbnail_buffer, sizeof(struct smdk4x12_camera_buffer)); - - if (yuv_buffer == NULL) - memset(&smdk4x12_camera->picture_yuv_buffer, 0, sizeof(smdk4x12_camera->picture_yuv_buffer)); - else - memcpy(&smdk4x12_camera->picture_yuv_buffer, yuv_buffer, sizeof(struct smdk4x12_camera_buffer)); - - if (yuv_thumbnail_buffer == NULL) - memset(&smdk4x12_camera->picture_yuv_thumbnail_buffer, 0, sizeof(smdk4x12_camera->picture_yuv_thumbnail_buffer)); - else - memcpy(&smdk4x12_camera->picture_yuv_thumbnail_buffer, yuv_thumbnail_buffer, sizeof(struct smdk4x12_camera_buffer)); - - pthread_mutex_unlock(&smdk4x12_camera->picture_lock_mutex); - - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - - rc = 0; - goto complete; - -error: - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - - smdk4x12_camera->picture_listener->busy = 0; - - rc = -1; - -complete: - return rc; -} - -int smdk4x12_camera_picture(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_camera_buffer *jpeg_buffer; - struct smdk4x12_camera_buffer *jpeg_thumbnail_buffer; - struct smdk4x12_camera_buffer *yuv_buffer; - struct smdk4x12_camera_buffer *yuv_thumbnail_buffer; - struct smdk4x12_v4l2_output output; - struct smdk4x12_jpeg jpeg; - struct smdk4x12_exif exif; - int output_enabled = 0; - int width, height, format; - int buffer_width, buffer_height, buffer_format, buffer_address; - camera_memory_t *memory = NULL; - int memory_size; - unsigned char *p; - camera_memory_t *jpeg_memory = NULL; - void *jpeg_data = NULL; - int jpeg_size = 0; - camera_memory_t *jpeg_thumbnail_memory = NULL; - void *jpeg_thumbnail_data = NULL; - int jpeg_thumbnail_size = 0; - void *yuv_data = NULL; - int yuv_address; - int yuv_size = 0; - void *yuv_thumbnail_data = NULL; - int yuv_thumbnail_address; - int yuv_thumbnail_size = 0; - int rc; - - if (smdk4x12_camera == NULL) - goto error; - -// ALOGD("%s()", __func__); - - jpeg_buffer = &smdk4x12_camera->picture_jpeg_buffer; - jpeg_thumbnail_buffer = &smdk4x12_camera->picture_jpeg_thumbnail_buffer; - yuv_buffer = &smdk4x12_camera->picture_yuv_buffer; - yuv_thumbnail_buffer = &smdk4x12_camera->picture_yuv_thumbnail_buffer; - - if (jpeg_buffer->pointer != NULL && jpeg_buffer->length > 0) { - jpeg_data = jpeg_buffer->pointer; - jpeg_size = jpeg_buffer->length; - } - - if (jpeg_thumbnail_buffer->pointer != NULL && jpeg_thumbnail_buffer->length > 0) { - jpeg_thumbnail_data = jpeg_thumbnail_buffer->pointer; - jpeg_thumbnail_size = jpeg_thumbnail_buffer->length; - } - - if (yuv_buffer->pointer != NULL && yuv_buffer->length > 0) { - yuv_data = yuv_buffer->pointer; - yuv_address = yuv_buffer->address; - yuv_size = yuv_buffer->length; - } - - if (yuv_thumbnail_buffer->pointer != NULL && yuv_thumbnail_buffer->length > 0) { - yuv_thumbnail_data = yuv_thumbnail_buffer->pointer; - yuv_thumbnail_address = yuv_thumbnail_buffer->address; - yuv_thumbnail_size = yuv_thumbnail_buffer->length; - } - - // JPEG - - if (jpeg_data == NULL) { - if (yuv_data == NULL || yuv_size <= 0) { - ALOGE("%s: Unable to create jpeg without an YUV buffer", __func__); - goto error; - } - - width = smdk4x12_camera->picture_width; - height = smdk4x12_camera->picture_height; - format = yuv_buffer->format; - - buffer_width = yuv_buffer->width; - buffer_height = yuv_buffer->height; - buffer_format = yuv_buffer->format; - buffer_address = yuv_buffer->address; - - if (width != buffer_width && height != buffer_height) { - format = SMDK4x12_CAMERA_PICTURE_OUTPUT_FORMAT; - - memset(&output, 0, sizeof(output)); - output.v4l2_id = 2; - output.width = width; - output.height = height; - output.format = format; - output.buffer_width = buffer_width; - output.buffer_height = buffer_height; - output.buffer_format = buffer_format; - output.buffers_count = 1; - - rc = smdk4x12_v4l2_output_start(smdk4x12_camera, &output); - if (rc < 0) { - ALOGE("%s: Unable to start picture output", __func__); - goto error; - } - - rc = smdk4x12_v4l2_output(smdk4x12_camera, &output, buffer_address); - if (rc < 0) { - ALOGE("%s: Unable to output picture", __func__); - goto error; - } - - output_enabled = 1; - - yuv_data = output.memory->data; - yuv_address = output.memory_address; - yuv_size = output.buffer_length; - } - - memset(&jpeg, 0, sizeof(jpeg)); - jpeg.width = width; - jpeg.height = height; - jpeg.format = format; - jpeg.quality = smdk4x12_camera->jpeg_quality; - - rc = smdk4x12_jpeg_start(smdk4x12_camera, &jpeg); - if (rc < 0) { - ALOGE("%s: Unable to start jpeg", __func__); - goto error; - } - - if (jpeg.memory_in_pointer == NULL) { - ALOGE("%s: Invalid memory input pointer", __func__); - goto error; - } - - memcpy(jpeg.memory_in_pointer, yuv_data, yuv_size); - - rc = smdk4x12_jpeg(smdk4x12_camera, &jpeg); - if (rc < 0) { - ALOGE("%s: Unable to jpeg", __func__); - goto error; - } - - jpeg_size = jpeg.memory_out_size; - if (jpeg_size <= 0) { - ALOGE("%s: Invalid jpeg size", __func__); - goto error; - } - - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - jpeg_memory = smdk4x12_camera->callbacks.request_memory(-1, jpeg_size, 1, smdk4x12_camera->callbacks.user); - if (jpeg_memory == NULL || jpeg_memory->data == NULL || jpeg_memory->data == MAP_FAILED) { - ALOGE("%s: Unable to request memory", __func__); - goto error; - } - } else { - ALOGE("%s: No memory request function!", __func__); - goto error; - } - - jpeg_data = jpeg_memory->data; - - memcpy(jpeg_data, jpeg.memory_out_pointer, jpeg_size); - - smdk4x12_jpeg_stop(smdk4x12_camera, &jpeg); - - if (output_enabled) { - smdk4x12_v4l2_output_stop(smdk4x12_camera, &output); - output_enabled = 0; - } - } - - ALOGE("%s: finished jpeg", __func__); - - // Thumbnail - - if (jpeg_thumbnail_data == NULL) { - if (yuv_thumbnail_data == NULL || yuv_thumbnail_size <= 0) { - ALOGE("%s: Unable to create jpeg thumbnail without an YUV buffer", __func__); - goto error; - } - - width = smdk4x12_camera->jpeg_thumbnail_width; - height = smdk4x12_camera->jpeg_thumbnail_height; - format = yuv_thumbnail_buffer->format; - - buffer_width = yuv_thumbnail_buffer->width; - buffer_height = yuv_thumbnail_buffer->height; - buffer_format = yuv_thumbnail_buffer->format; - buffer_address = yuv_thumbnail_buffer->address; - - if (width != buffer_width && height != buffer_height) { - format = SMDK4x12_CAMERA_PICTURE_OUTPUT_FORMAT; - - memset(&output, 0, sizeof(output)); - output.v4l2_id = 2; - output.width = width; - output.height = height; - output.format = format; - output.buffer_width = buffer_width; - output.buffer_height = buffer_height; - output.buffer_format = buffer_format; - output.buffers_count = 1; - - rc = smdk4x12_v4l2_output_start(smdk4x12_camera, &output); - if (rc < 0) { - ALOGE("%s: Unable to start thumbnail picture output", __func__); - goto error; - } - - output_enabled = 1; - - rc = smdk4x12_v4l2_output(smdk4x12_camera, &output, buffer_address); - if (rc < 0) { - ALOGE("%s: Unable to output thumbnail picture", __func__); - goto error; - } - - yuv_thumbnail_data = output.memory->data; - yuv_thumbnail_address = output.memory_address; - yuv_thumbnail_size = output.buffer_length; - } - - memset(&jpeg, 0, sizeof(jpeg)); - jpeg.width = width; - jpeg.height = height; - jpeg.format = format; - jpeg.quality = smdk4x12_camera->jpeg_thumbnail_quality; - - rc = smdk4x12_jpeg_start(smdk4x12_camera, &jpeg); - if (rc < 0) { - ALOGE("%s: Unable to start jpeg", __func__); - goto error; - } - - if (jpeg.memory_in_pointer == NULL) { - ALOGE("%s: Invalid memory input pointer", __func__); - goto error; - } - - memcpy(jpeg.memory_in_pointer, yuv_thumbnail_data, yuv_thumbnail_size); - - rc = smdk4x12_jpeg(smdk4x12_camera, &jpeg); - if (rc < 0) { - ALOGE("%s: Unable to jpeg", __func__); - goto error; - } - - jpeg_thumbnail_size = jpeg.memory_out_size; - if (jpeg_thumbnail_size <= 0) { - ALOGE("%s: Invalid jpeg size", __func__); - goto error; - } - - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - jpeg_thumbnail_memory = smdk4x12_camera->callbacks.request_memory(-1, jpeg_thumbnail_size, 1, smdk4x12_camera->callbacks.user); - if (jpeg_thumbnail_memory == NULL || jpeg_thumbnail_memory->data == NULL || jpeg_thumbnail_memory->data == MAP_FAILED) { - ALOGE("%s: Unable to request memory", __func__); - goto error; - } - } else { - ALOGE("%s: No memory request function!", __func__); - goto error; - } - - jpeg_thumbnail_data = jpeg_thumbnail_memory->data; - - memcpy(jpeg_thumbnail_data, jpeg.memory_out_pointer, jpeg_thumbnail_size); - - smdk4x12_jpeg_stop(smdk4x12_camera, &jpeg); - - if (output_enabled) { - smdk4x12_v4l2_output_stop(smdk4x12_camera, &output); - output_enabled = 0; - } - } - - ALOGE("%s: Thumbnail finished", __func__); - - // EXIF - - memset(&exif, 0, sizeof(exif)); - exif.jpeg_thumbnail_data = jpeg_thumbnail_data; - exif.jpeg_thumbnail_size = jpeg_thumbnail_size; - - rc = smdk4x12_exif_start(smdk4x12_camera, &exif); - if (rc < 0) { - ALOGE("%s: Unable to start exif", __func__); - goto error; - } - - rc = smdk4x12_exif(smdk4x12_camera, &exif); - if (rc < 0) { - ALOGE("%s: Unable to exif", __func__); - goto error; - } - - memory_size = exif.memory_size + jpeg_size; - - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - memory = smdk4x12_camera->callbacks.request_memory(-1, memory_size, 1, smdk4x12_camera->callbacks.user); - if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { - ALOGE("%s: Unable to request memory", __func__); - goto error; - } - } else { - ALOGE("%s: No memory request function!", __func__); - goto error; - } - - ALOGE("%s: exif finished", __func__); - - p = (unsigned char *) memory->data; - - // Copy the first two bytes of the JPEG picture - memcpy(p, jpeg_data, 2); - p += 2; - - // Copy the EXIF data - memcpy(p, exif.memory->data, exif.memory_size); - p += exif.memory_size; - - // Copy the JPEG picture - memcpy(p, (void *) ((unsigned char *) jpeg_data + 2), jpeg_size - 2); - - smdk4x12_exif_stop(smdk4x12_camera, &exif); - - smdk4x12_camera->picture_memory = memory; - - rc = 0; - goto complete; - -error: - if (output_enabled) - smdk4x12_v4l2_output_stop(smdk4x12_camera, &output); - - if (memory != NULL && memory->release != NULL) { - memory->release(memory); - smdk4x12_camera->picture_memory = NULL; - } - - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_ERROR) && SMDK4x12_CAMERA_CALLBACK_DEFINED(notify) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.notify(CAMERA_MSG_ERROR, -1, 0, smdk4x12_camera->callbacks.user); - - rc = -1; - -complete: - if (jpeg_memory != NULL && jpeg_memory->release != NULL) - jpeg_memory->release(jpeg_memory); - - if (jpeg_thumbnail_memory != NULL && jpeg_thumbnail_memory->release != NULL) - jpeg_thumbnail_memory->release(jpeg_thumbnail_memory); - - smdk4x12_camera->picture_completed = 1; - smdk4x12_camera->picture_listener->busy = 0; - - return rc; -} - -void *smdk4x12_camera_picture_thread(void *data) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - if (data == NULL) - return NULL; - - smdk4x12_camera = (struct smdk4x12_camera *) data; - - ALOGE("%s: Starting thread", __func__); - smdk4x12_camera->picture_thread_running = 1; - - while (smdk4x12_camera->picture_thread_enabled) { - ALOGE("%s: in while loop", __func__); - pthread_mutex_lock(&smdk4x12_camera->picture_lock_mutex); - ALOGE("%s: lock_mutex locked", __func__); - pthread_mutex_lock(&smdk4x12_camera->picture_mutex); - ALOGE("%s: picture_mutex locked", __func__); - - if (smdk4x12_camera->picture_listener == NULL) { - ALOGE("%s: no listener", __func__); - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - break; - } - - if (smdk4x12_camera->picture_listener->busy) { - ALOGE("%s: listener busy", __func__); - rc = smdk4x12_camera_picture(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to take picture", __func__); - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - break; - } - } - - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - ALOGE("%s: picture_mutex unlocked", __func__); - - if (smdk4x12_camera->picture_completed) { - ALOGE("%s: picture completed", __func__); - smdk4x12_camera->picture_thread_running = 0; - smdk4x12_camera_picture_thread_stop(smdk4x12_camera); - break; - } - ALOGE("%s: still while loop", __func__); - } - - smdk4x12_camera->picture_thread_running = 0; - ALOGE("%s: Exiting thread", __func__); - - return NULL; -} - -int smdk4x12_camera_picture_thread_start(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_camera_capture_listener *listener; - pthread_attr_t thread_attr; - int format; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->picture_thread_enabled) { - ALOGE("Picture thread was already started!"); - return -1; - } - - if (smdk4x12_camera->camera_picture_format) - format = smdk4x12_camera->camera_picture_format; - else - format = smdk4x12_camera->picture_format; - - pthread_mutex_init(&smdk4x12_camera->picture_mutex, NULL); - pthread_mutex_init(&smdk4x12_camera->picture_lock_mutex, NULL); - - // Initial lock - pthread_mutex_lock(&smdk4x12_camera->picture_lock_mutex); - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - - smdk4x12_camera->picture_thread_enabled = 1; - - rc = pthread_create(&smdk4x12_camera->picture_thread, &thread_attr, smdk4x12_camera_picture_thread, (void *) smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to create thread", __func__); - goto error; - } - - smdk4x12_camera->picture_completed = 0; - - listener = smdk4x12_camera_capture_listener_register(smdk4x12_camera, smdk4x12_camera->picture_width, smdk4x12_camera->picture_height, format, smdk4x12_camera_picture_callback); - if (listener == NULL) { - ALOGE("%s: Unable to register picture capture listener", __func__); - goto error; - } - - smdk4x12_camera->picture_listener = listener; - - rc = 0; - goto complete; - -error: - pthread_mutex_destroy(&smdk4x12_camera->picture_mutex); - pthread_mutex_destroy(&smdk4x12_camera->picture_lock_mutex); - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_picture_thread_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - camera_memory_t *memory; - int i; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->picture_thread_enabled) { - ALOGE("Picture thread was already stopped!"); - return; - } - - memory = smdk4x12_camera->picture_memory; - - if (smdk4x12_camera->picture_listener != NULL) { - smdk4x12_camera_capture_listener_unregister(smdk4x12_camera, smdk4x12_camera->picture_listener); - smdk4x12_camera->picture_listener = NULL; - } - - smdk4x12_camera->picture_thread_enabled = 0; - - pthread_mutex_unlock(&smdk4x12_camera->picture_lock_mutex); - - // Wait for the thread to end - i = 0; - while (smdk4x12_camera->picture_thread_running) { - if (i++ > 10000) { - ALOGE("Picture thread is taking too long to end, something is going wrong"); - break; - } - usleep(100); - } - - if (smdk4x12_camera->picture_enabled) { - pthread_mutex_lock(&smdk4x12_camera->picture_mutex); - smdk4x12_camera->picture_enabled = 0; - pthread_mutex_unlock(&smdk4x12_camera->picture_mutex); - } - - pthread_mutex_destroy(&smdk4x12_camera->picture_mutex); - pthread_mutex_destroy(&smdk4x12_camera->picture_lock_mutex); - - if (smdk4x12_camera->picture_completed && memory != NULL) { - // It is important to return at this point (and not before) for burst - - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_SHUTTER) && SMDK4x12_CAMERA_CALLBACK_DEFINED(notify) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.notify(CAMERA_MSG_SHUTTER, 0, 0, smdk4x12_camera->callbacks.user); - - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_COMPRESSED_IMAGE) && SMDK4x12_CAMERA_CALLBACK_DEFINED(data) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.data(CAMERA_MSG_COMPRESSED_IMAGE, memory, 0, NULL, smdk4x12_camera->callbacks.user); - - if (memory->release != NULL) { - memory->release(memory); - smdk4x12_camera->picture_memory = NULL; - } - } -} - -// Recording - -int smdk4x12_camera_recording_output_start(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->recording_output_enabled) { - ALOGE("Recording was already started!"); - return -1; - } - - output = &smdk4x12_camera->recording_output; - - memset(output, 0, sizeof(struct smdk4x12_v4l2_output)); - output->v4l2_id = 3; - output->width = smdk4x12_camera->recording_width; - output->height = smdk4x12_camera->recording_height; - output->format = smdk4x12_camera->recording_format; - output->buffer_width = smdk4x12_camera->recording_buffer.width; - output->buffer_height = smdk4x12_camera->recording_buffer.height; - output->buffer_format = smdk4x12_camera->recording_buffer.format; - output->buffers_count = SMDK4x12_CAMERA_RECORDING_BUFFERS_COUNT; - - rc = smdk4x12_v4l2_output_start(smdk4x12_camera, output); - if (rc < 0) { - ALOGE("%s: Unable to start recording output", __func__); - goto error; - } - - smdk4x12_camera->recording_output_enabled = 1; - - rc = 0; - goto complete; - -error: - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_recording_output_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->recording_output_enabled) { - ALOGE("Recording was already stopped!"); - return; - } - - output = &smdk4x12_camera->recording_output; - - smdk4x12_v4l2_output_stop(smdk4x12_camera, output); - - smdk4x12_camera->recording_output_enabled = 0; -} - -int smdk4x12_camera_recording_callback(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_buffer *buffers, int buffers_count) -{ - struct smdk4x12_camera_buffer *buffer = NULL; - int width, height, format; - int buffer_width, buffer_height, buffer_format; - int rc; - int i; - - if (smdk4x12_camera == NULL || buffers == NULL || buffers_count <= 0) - return -EINVAL; - -// ALOGD("%s()", __func__); - - if (smdk4x12_camera->recording_listener == NULL) - return -1; - - if (smdk4x12_camera->recording_listener->busy) { - ALOGE("%s: Dropping buffer", __func__); - return 0; - } - - smdk4x12_camera->recording_listener->busy = 1; - - width = smdk4x12_camera->recording_width; - height = smdk4x12_camera->recording_height; - format = smdk4x12_camera->recording_format; - - for (i = 0; i < buffers_count; i++) { - if (buffers->format == V4L2_PIX_FMT_JPEG) - goto buffers_continue; - - if (buffers->format == V4L2_PIX_FMT_INTERLEAVED) - goto buffers_continue; - - // Optimal buffer - if (buffers->width == width && buffers->height == height) { - buffer = buffers; - break; - } - - // Might-work buffer, but not optimal - buffer = buffers; - -buffers_continue: - buffers = (struct smdk4x12_camera_buffer *) ((unsigned char *) buffers + sizeof(struct smdk4x12_camera_buffer)); - } - - if (buffer == NULL) { - ALOGE("%s: Unable to find an appropriate buffer for recording", __func__); - smdk4x12_camera->recording_listener->busy = 0; - return 0; - } - - buffer_width = buffer->width; - buffer_height = buffer->height; - buffer_format = buffer->format; - - pthread_mutex_lock(&smdk4x12_camera->recording_mutex); - - if (!smdk4x12_camera->recording_output_enabled) { - memcpy(&smdk4x12_camera->recording_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - - rc = smdk4x12_camera_recording_output_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start recording", __func__); - goto error; - } - } else if (smdk4x12_camera->recording_buffer.width != buffer_width || smdk4x12_camera->recording_buffer.height != buffer_height || smdk4x12_camera->recording_buffer.format != buffer_format) { - smdk4x12_camera_recording_output_stop(smdk4x12_camera); - - memcpy(&smdk4x12_camera->recording_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - - rc = smdk4x12_camera_recording_output_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start recording", __func__); - goto error; - } - } else { - memcpy(&smdk4x12_camera->recording_buffer, buffer, sizeof(struct smdk4x12_camera_buffer)); - } - - pthread_mutex_unlock(&smdk4x12_camera->recording_lock_mutex); - - pthread_mutex_unlock(&smdk4x12_camera->recording_mutex); - - rc = 0; - goto complete; - -error: - pthread_mutex_unlock(&smdk4x12_camera->recording_mutex); - - smdk4x12_camera->recording_listener->busy = 0; - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_recording_frame_release(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - int rc; - - if (smdk4x12_camera == NULL) - return; - -// ALOGD("%s()", __func__); - - output = &smdk4x12_camera->recording_output; - - if (!smdk4x12_camera->recording_output_enabled) { - ALOGE("%s: Recording output should always be enabled", __func__); - return; - } - - rc = smdk4x12_v4l2_output_release(smdk4x12_camera, output); - if (rc < 0) { - ALOGE("%s: Unable to release recording output", __func__); - return; - } -} - -int smdk4x12_camera_recording(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_v4l2_output *output; - struct smdk4x12_camera_addrs *addrs; - int width, height, format; - camera_memory_t *memory; - int memory_address; - int memory_index; - int buffer_length; - int buffers_count; - nsecs_t timestamp; - int rc; - - if (smdk4x12_camera == NULL) - goto error; - -// ALOGD("%s()", __func__); - - width = smdk4x12_camera->recording_width; - height = smdk4x12_camera->recording_height; - format = smdk4x12_camera->recording_format; - - output = &smdk4x12_camera->recording_output; - - buffer_length = smdk4x12_camera->recording_buffer_length; - buffers_count = smdk4x12_camera->recording_buffers_count; - - timestamp = systemTime(1); - - if (!smdk4x12_camera->recording_output_enabled) { - ALOGE("%s: Recording output should always be enabled", __func__); - goto error; - } - - rc = smdk4x12_v4l2_output(smdk4x12_camera, output, smdk4x12_camera->recording_buffer.address); - if (rc < 0) { - ALOGE("%s: Unable to output recording", __func__); - goto error; - } - - if (smdk4x12_camera->recording_metadata) { - memory = smdk4x12_camera->recording_memory; - memory_index = smdk4x12_camera->recording_memory_index; - memory_address = output->memory_address + output->buffer_length * output->memory_index; - - addrs = (struct smdk4x12_camera_addrs *) ((unsigned char *) memory->data + buffer_length * memory_index); - memset(addrs, 0, sizeof(struct smdk4x12_camera_addrs)); - addrs->type = 0; // kMetadataBufferTypeCameraSource - addrs->index = memory_index; - - smdk4x12_camera_yuv_planes(width, height, format, memory_address, (int *) &addrs->y, (int *) &addrs->cbcr, NULL); - } else { - memory = output->memory; - memory_index = output->memory_index; - } - - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_VIDEO_FRAME) && SMDK4x12_CAMERA_CALLBACK_DEFINED(data_timestamp) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.data_timestamp(timestamp, CAMERA_MSG_VIDEO_FRAME, memory, memory_index, smdk4x12_camera->callbacks.user); - else - smdk4x12_camera_recording_frame_release(smdk4x12_camera); - - if (smdk4x12_camera->recording_metadata) { - memory_index++; - smdk4x12_camera->recording_memory_index = memory_index % buffers_count; - } - - rc = 0; - goto complete; - -error: - rc = -1; - -complete: - smdk4x12_camera->recording_listener->busy = 0; - - return rc; -} - -void *smdk4x12_camera_recording_thread(void *data) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - if (data == NULL) - return NULL; - - smdk4x12_camera = (struct smdk4x12_camera *) data; - - ALOGE("%s: Starting thread", __func__); - smdk4x12_camera->recording_thread_running = 1; - - while (smdk4x12_camera->recording_thread_enabled) { - pthread_mutex_lock(&smdk4x12_camera->recording_lock_mutex); - - pthread_mutex_lock(&smdk4x12_camera->recording_mutex); - - if (smdk4x12_camera->recording_listener == NULL) { - pthread_mutex_unlock(&smdk4x12_camera->recording_mutex); - break; - } - - if (smdk4x12_camera->recording_listener->busy) { - rc = smdk4x12_camera_recording(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to record", __func__); - pthread_mutex_unlock(&smdk4x12_camera->recording_mutex); - break; - } - } - - pthread_mutex_unlock(&smdk4x12_camera->recording_mutex); - } - - smdk4x12_camera->recording_thread_running = 0; - ALOGE("%s: Exiting thread", __func__); - - return NULL; -} - -int smdk4x12_camera_recording_thread_start(struct smdk4x12_camera *smdk4x12_camera) -{ - struct smdk4x12_camera_capture_listener *listener; - pthread_attr_t thread_attr; - camera_memory_t *memory = NULL; - int buffer_length; - int buffers_count; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->recording_thread_enabled) { - ALOGE("Recording thread was already started!"); - return -1; - } - - pthread_mutex_init(&smdk4x12_camera->recording_mutex, NULL); - pthread_mutex_init(&smdk4x12_camera->recording_lock_mutex, NULL); - - // Initial lock - pthread_mutex_lock(&smdk4x12_camera->recording_lock_mutex); - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - - smdk4x12_camera->recording_thread_enabled = 1; - - rc = pthread_create(&smdk4x12_camera->recording_thread, &thread_attr, smdk4x12_camera_recording_thread, (void *) smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to create thread", __func__); - goto error; - } - - if (smdk4x12_camera->recording_metadata) { - buffer_length = sizeof(struct smdk4x12_camera_addrs); - buffers_count = SMDK4x12_CAMERA_RECORDING_BUFFERS_COUNT; - - if (SMDK4x12_CAMERA_CALLBACK_DEFINED(request_memory)) { - memory = smdk4x12_camera->callbacks.request_memory(-1, buffer_length, buffers_count, smdk4x12_camera->callbacks.user); - if (memory == NULL || memory->data == NULL || memory->data == MAP_FAILED) { - ALOGE("%s: Unable to request memory", __func__); - goto error; - } - } else { - ALOGE("%s: No memory request function!", __func__); - goto error; - } - - smdk4x12_camera->recording_memory = memory; - smdk4x12_camera->recording_buffer_length = buffer_length; - smdk4x12_camera->recording_buffers_count = buffers_count; - } - - listener = smdk4x12_camera_capture_listener_register(smdk4x12_camera, smdk4x12_camera->recording_width, smdk4x12_camera->recording_height, smdk4x12_camera->recording_format, smdk4x12_camera_recording_callback); - if (listener == NULL) { - ALOGE("%s: Unable to register recording capture listener", __func__); - goto error; - } - - smdk4x12_camera->recording_listener = listener; - - rc = 0; - goto complete; - -error: - if (memory != NULL && memory->release != NULL) { - memory->release(memory); - smdk4x12_camera->recording_memory = NULL; - } - - pthread_mutex_destroy(&smdk4x12_camera->recording_mutex); - pthread_mutex_destroy(&smdk4x12_camera->recording_lock_mutex); - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_recording_thread_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - camera_memory_t *memory; - int i; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->recording_thread_enabled) { - ALOGE("Recording thread was already stopped!"); - return; - } - - memory = smdk4x12_camera->recording_memory; - - if (smdk4x12_camera->recording_listener != NULL) { - smdk4x12_camera_capture_listener_unregister(smdk4x12_camera, smdk4x12_camera->recording_listener); - smdk4x12_camera->recording_listener = NULL; - } - - smdk4x12_camera->recording_thread_enabled = 0; - - pthread_mutex_unlock(&smdk4x12_camera->recording_lock_mutex); - - // Wait for the thread to end - i = 0; - while (smdk4x12_camera->recording_thread_running) { - if (i++ > 10000) { - ALOGE("Recording thread is taking too long to end, something is going wrong"); - break; - } - usleep(100); - } - - if (smdk4x12_camera->recording_output_enabled) { - pthread_mutex_lock(&smdk4x12_camera->recording_mutex); - smdk4x12_camera_recording_output_stop(smdk4x12_camera); - pthread_mutex_unlock(&smdk4x12_camera->recording_mutex); - } - - pthread_mutex_destroy(&smdk4x12_camera->recording_mutex); - pthread_mutex_destroy(&smdk4x12_camera->recording_lock_mutex); - - if (memory != NULL && memory->release != NULL) { - memory->release(memory); - smdk4x12_camera->recording_memory = NULL; - } -} - -// Auto-focus - -int smdk4x12_camera_auto_focus(struct smdk4x12_camera *smdk4x12_camera, int auto_focus_status) -{ - if (smdk4x12_camera == NULL) - return -EINVAL; - -// ALOGD("%s()", __func__); - - switch (auto_focus_status) { - case CAMERA_AF_STATUS_IN_PROGRESS: - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS_MOVE) && SMDK4x12_CAMERA_CALLBACK_DEFINED(notify) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.notify(CAMERA_MSG_FOCUS_MOVE, 1, 0, smdk4x12_camera->callbacks.user); - break; - case CAMERA_AF_STATUS_SUCCESS: - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && SMDK4x12_CAMERA_CALLBACK_DEFINED(notify) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.notify(CAMERA_MSG_FOCUS, 1, 0, smdk4x12_camera->callbacks.user); - break; - case CAMERA_AF_STATUS_FAIL: - default: - if (SMDK4x12_CAMERA_MSG_ENABLED(CAMERA_MSG_FOCUS) && SMDK4x12_CAMERA_CALLBACK_DEFINED(notify) && !smdk4x12_camera->callback_lock) - smdk4x12_camera->callbacks.notify(CAMERA_MSG_FOCUS, 0, 0, smdk4x12_camera->callbacks.user); - break; - } - - return 0; -} - -void *smdk4x12_camera_auto_focus_thread(void *data) -{ - struct smdk4x12_camera *smdk4x12_camera; - int auto_focus_result = CAMERA_AF_STATUS_FAIL; - int auto_focus_completed = 0; - int rc; - - if (data == NULL) - return NULL; - - smdk4x12_camera = (struct smdk4x12_camera *) data; - - ALOGE("%s: Starting thread", __func__); - smdk4x12_camera->auto_focus_thread_running = 1; - - if (smdk4x12_camera->focus_mode == FOCUS_MODE_CONTINOUS_PICTURE) { - rc = smdk4x12_camera_auto_focus(smdk4x12_camera, smdk4x12_camera->auto_focus_result); - if (rc < 0) - ALOGE("%s: Unable to auto-focus", __func__); - - smdk4x12_camera->auto_focus_thread_enabled = 0; - } - - while (smdk4x12_camera->auto_focus_thread_enabled) { - pthread_mutex_lock(&smdk4x12_camera->auto_focus_mutex); - - rc = smdk4x12_v4l2_g_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_AUTO_FOCUS_RESULT, &auto_focus_result); - if (rc < 0) { - ALOGE("%s: Unable to get auto-focus result", __func__); - auto_focus_result = CAMERA_AF_STATUS_FAIL; - } - - smdk4x12_camera->auto_focus_result = auto_focus_result; - - rc = smdk4x12_camera_auto_focus(smdk4x12_camera, auto_focus_result); - if (rc < 0) { - ALOGE("%s: Unable to auto-focus", __func__); - auto_focus_result = CAMERA_AF_STATUS_FAIL; - } - - if (auto_focus_result == CAMERA_AF_STATUS_IN_PROGRESS) - usleep(10000); - else - auto_focus_completed = 1; - - pthread_mutex_unlock(&smdk4x12_camera->auto_focus_mutex); - - if (auto_focus_completed) { - smdk4x12_camera->auto_focus_thread_running = 0; - smdk4x12_camera_auto_focus_thread_stop(smdk4x12_camera); - } - } - - smdk4x12_camera->auto_focus_thread_running = 0; - ALOGE("%s: Exiting thread", __func__); - - return NULL; -} - -int smdk4x12_camera_auto_focus_thread_start(struct smdk4x12_camera *smdk4x12_camera) -{ - pthread_attr_t thread_attr; - int auto_focus; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - ALOGD("%s()", __func__); - - if (smdk4x12_camera->auto_focus_thread_enabled) { - ALOGE("Auto-focus thread was already started!"); - return -1; - } - - pthread_mutex_init(&smdk4x12_camera->auto_focus_mutex, NULL); - - if (smdk4x12_camera->focus_mode != FOCUS_MODE_CONTINOUS_PICTURE) { - auto_focus = AUTO_FOCUS_ON | (smdk4x12_camera->preview_width & 0xfff) << 20 | (smdk4x12_camera->preview_height & 0xfff) << 8; - - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, auto_focus); - if (rc < 0) { - ALOGE("%s: Unable to set auto-focus on", __func__); - goto error; - } - } - - pthread_attr_init(&thread_attr); - pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); - - smdk4x12_camera->auto_focus_thread_enabled = 1; - - rc = pthread_create(&smdk4x12_camera->auto_focus_thread, &thread_attr, smdk4x12_camera_auto_focus_thread, (void *) smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to create thread", __func__); - goto error; - } - - rc = 0; - goto complete; - -error: - pthread_mutex_destroy(&smdk4x12_camera->auto_focus_mutex); - - rc = -1; - -complete: - return rc; -} - -void smdk4x12_camera_auto_focus_thread_stop(struct smdk4x12_camera *smdk4x12_camera) -{ - int rc; - int i; - - if (smdk4x12_camera == NULL) - return; - - ALOGD("%s()", __func__); - - if (!smdk4x12_camera->auto_focus_thread_enabled) { - ALOGE("Auto-focus thread was already stopped!"); - return; - } - - smdk4x12_camera->auto_focus_thread_enabled = 0; - - // Wait for the thread to end - i = 0; - while (smdk4x12_camera->auto_focus_thread_running) { - if (i++ > 10000) { - ALOGE("Auto-focus thread is taking too long to end, something is going wrong"); - break; - } - usleep(100); - } - if (smdk4x12_camera->focus_mode != FOCUS_MODE_CONTINOUS_PICTURE) { - rc = smdk4x12_v4l2_s_ctrl(smdk4x12_camera, 0, V4L2_CID_CAMERA_SET_AUTO_FOCUS, AUTO_FOCUS_OFF); - if (rc < 0) - ALOGE("%s: Unable to set auto-focus off", __func__); - } - - pthread_mutex_destroy(&smdk4x12_camera->auto_focus_mutex); -} - -/* - * SMDK4x12 Camera OPS - */ - -int smdk4x12_camera_set_preview_window(struct camera_device *device, - struct preview_stream_ops *w) -{ - struct smdk4x12_camera *smdk4x12_camera; - - int width, height, format, gralloc_format; - - buffer_handle_t *buffer; - int stride; - void *addr = NULL; - - int rc; - - ALOGD("%s(%p, %p)", __func__, device, w); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - if (smdk4x12_camera->preview_thread_enabled) - pthread_mutex_lock(&smdk4x12_camera->preview_mutex); - - if (w == NULL) { - smdk4x12_camera->preview_window = NULL; - return 0; - } - - if (w->set_buffer_count == NULL || w->set_usage == NULL || w->set_buffers_geometry == NULL) - goto error; - - rc = w->set_buffer_count(w, SMDK4x12_CAMERA_GRALLOC_BUFFERS_COUNT); - if (rc) { - ALOGE("%s: Unable to set buffer count: %d", __func__, SMDK4x12_CAMERA_GRALLOC_BUFFERS_COUNT); - goto error; - } - - rc = w->set_usage(w, GRALLOC_USAGE_SW_WRITE_OFTEN); - if (rc) { - ALOGE("%s: Unable to set usage", __func__); - goto error; - } - - width = smdk4x12_camera->preview_width; - height = smdk4x12_camera->preview_height; - format = smdk4x12_camera->preview_format; - - gralloc_format = smdk4x12_gralloc_format(format); - - rc = w->set_buffers_geometry(w, width, height, gralloc_format); - if (rc) { - ALOGE("%s: Unable to set buffers geometry", __func__); - goto error; - } - - smdk4x12_camera->preview_window = w; - - rc = 0; - goto complete; - -error: - smdk4x12_camera->preview_window = NULL; - rc = -1; - -complete: - if (smdk4x12_camera->preview_thread_enabled) - pthread_mutex_unlock(&smdk4x12_camera->preview_mutex); - - return rc; -} - -void smdk4x12_camera_set_callbacks(struct camera_device *device, - camera_notify_callback notify_cb, - camera_data_callback data_cb, - camera_data_timestamp_callback data_cb_timestamp, - camera_request_memory get_memory, - void *user) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p, %p)", __func__, device, user); - - if (device == NULL || device->priv == NULL) - return; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callbacks.notify = notify_cb; - smdk4x12_camera->callbacks.data = data_cb; - smdk4x12_camera->callbacks.data_timestamp = data_cb_timestamp; - smdk4x12_camera->callbacks.request_memory = get_memory; - smdk4x12_camera->callbacks.user = user; -} - -void smdk4x12_camera_enable_msg_type(struct camera_device *device, - int32_t msg_type) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p, %d)", __func__, device, msg_type); - - if (device == NULL || device->priv == NULL) - return; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->messages_enabled |= msg_type; -} - -void smdk4x12_camera_disable_msg_type(struct camera_device *device, - int32_t msg_type) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p, %d)", __func__, device, msg_type); - - if (device == NULL || device->priv == NULL) - return; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->messages_enabled &= ~msg_type; -} - -int smdk4x12_camera_msg_type_enabled(struct camera_device *device, - int32_t msg_type) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p, %d)", __func__, device, msg_type); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - return smdk4x12_camera->messages_enabled & msg_type; -} - -int smdk4x12_camera_start_preview(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callback_lock = 1; - rc = smdk4x12_camera_preview_thread_start(smdk4x12_camera); - smdk4x12_camera->callback_lock = 0; - - return rc; -} - -void smdk4x12_camera_stop_preview(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callback_lock = 1; - smdk4x12_camera_preview_thread_stop(smdk4x12_camera); - smdk4x12_camera->callback_lock = 0; -} - -int smdk4x12_camera_preview_enabled(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - return smdk4x12_camera->preview_thread_enabled; -} - -int smdk4x12_camera_store_meta_data_in_buffers(struct camera_device *device, - int enable) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p, %d)", __func__, device, enable); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - if (!smdk4x12_camera->recording_thread_enabled) - smdk4x12_camera->recording_metadata = enable; - else - ALOGE("%s: Recording is running!", __func__); - - return 0; -} - -int smdk4x12_camera_start_recording(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - ALOGD("%s(%p)", __func__, device); - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callback_lock = 1; - rc = smdk4x12_camera_recording_thread_start(smdk4x12_camera); - smdk4x12_camera->callback_lock = 0; - - return rc; -} - -void smdk4x12_camera_stop_recording(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callback_lock = 1; - smdk4x12_camera_recording_thread_stop(smdk4x12_camera); - smdk4x12_camera->callback_lock = 0; -} - -int smdk4x12_camera_recording_enabled(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - return smdk4x12_camera->recording_thread_enabled; -} - -void smdk4x12_camera_release_recording_frame(struct camera_device *device, - const void *opaque) -{ - struct smdk4x12_camera *smdk4x12_camera; - -// ALOGD("%s(%p, %p)", __func__, device, opaque); - - if (device == NULL || device->priv == NULL) - return; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera_recording_frame_release(smdk4x12_camera); -} - -int smdk4x12_camera_start_auto_focus(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - return smdk4x12_camera_auto_focus_thread_start(smdk4x12_camera); -} - -int smdk4x12_camera_cancel_auto_focus(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera_auto_focus_thread_stop(smdk4x12_camera); - - return 0; -} - -int smdk4x12_camera_take_picture(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callback_lock = 1; - rc = smdk4x12_camera_picture_thread_start(smdk4x12_camera); - smdk4x12_camera->callback_lock = 0; - - return rc; -} - -int smdk4x12_camera_cancel_picture(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera->callback_lock = 1; - smdk4x12_camera_picture_thread_stop(smdk4x12_camera); - smdk4x12_camera->callback_lock = 0; - - return 0; -} - -int smdk4x12_camera_set_parameters(struct camera_device *device, - const char *params) -{ - struct smdk4x12_camera *smdk4x12_camera; - int rc; - - ALOGD("%s(%p, %s)", __func__, device, params); - - if (device == NULL || device->priv == NULL || params == NULL) - return -EINVAL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - rc = smdk4x12_params_string_set(smdk4x12_camera, (char *) params); - if (rc < 0) { - ALOGE("%s: Unable to set params string", __func__); - return -1; - } - - rc = smdk4x12_camera_params_apply(smdk4x12_camera, 0); - if (rc < 0) { - ALOGE("%s: Unable to apply params", __func__); - return -1; - } - - return 0; -} - -char *smdk4x12_camera_get_parameters(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - char *params; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return NULL; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - params = smdk4x12_params_string_get(smdk4x12_camera); - if (params == NULL) { - ALOGE("%s: Couldn't find any param", __func__); - return strdup(""); - } - - return params; -} - -void smdk4x12_camera_put_parameters(struct camera_device *device, char *params) -{ - ALOGD("%s(%p)", __func__, device); - - if (params != NULL) - free(params); -} - -int smdk4x12_camera_send_command(struct camera_device *device, - int32_t cmd, int32_t arg1, int32_t arg2) -{ - ALOGD("%s(%p, %d, %d, %d)", __func__, device, cmd, arg1, arg2); - - return 0; -} - -void smdk4x12_camera_release(struct camera_device *device) -{ - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL || device->priv == NULL) - return; - - smdk4x12_camera = (struct smdk4x12_camera *) device->priv; - - smdk4x12_camera_capture_thread_stop(smdk4x12_camera); - - smdk4x12_camera_stop(smdk4x12_camera); -} - -int smdk4x12_camera_dump(struct camera_device *device, int fd) -{ - ALOGD("%s(%p, %d)", __func__, device, fd); - - return 0; -} - -/* - * Interface - */ - -struct camera_device_ops smdk4x12_camera_ops = { - .set_preview_window = smdk4x12_camera_set_preview_window, - .set_callbacks = smdk4x12_camera_set_callbacks, - .enable_msg_type = smdk4x12_camera_enable_msg_type, - .disable_msg_type = smdk4x12_camera_disable_msg_type, - .msg_type_enabled = smdk4x12_camera_msg_type_enabled, - .start_preview = smdk4x12_camera_start_preview, - .stop_preview = smdk4x12_camera_stop_preview, - .preview_enabled = smdk4x12_camera_preview_enabled, - .store_meta_data_in_buffers = smdk4x12_camera_store_meta_data_in_buffers, - .start_recording = smdk4x12_camera_start_recording, - .stop_recording = smdk4x12_camera_stop_recording, - .recording_enabled = smdk4x12_camera_recording_enabled, - .release_recording_frame = smdk4x12_camera_release_recording_frame, - .auto_focus = smdk4x12_camera_start_auto_focus, - .cancel_auto_focus = smdk4x12_camera_cancel_auto_focus, - .take_picture = smdk4x12_camera_take_picture, - .cancel_picture = smdk4x12_camera_cancel_picture, - .set_parameters = smdk4x12_camera_set_parameters, - .get_parameters = smdk4x12_camera_get_parameters, - .put_parameters = smdk4x12_camera_put_parameters, - .send_command = smdk4x12_camera_send_command, - .release = smdk4x12_camera_release, - .dump = smdk4x12_camera_dump, -}; - -int smdk4x12_camera_close(hw_device_t *device) -{ - struct camera_device *camera_device; - struct smdk4x12_camera *smdk4x12_camera; - - ALOGD("%s(%p)", __func__, device); - - if (device == NULL) - return -EINVAL; - - camera_device = (struct camera_device *) device; - - if (camera_device->priv != NULL) { - free(camera_device->priv); - } - - free(camera_device); - - return 0; -} - -int smdk4x12_camera_open(const struct hw_module_t* module, const char *camera_id, - struct hw_device_t** device) -{ - struct camera_device *camera_device = NULL; - struct smdk4x12_camera *smdk4x12_camera = NULL; - int id; - int rc; - - ALOGD("%s(%p, %s, %p)", __func__, module, camera_id, device); - - if (module == NULL || camera_id == NULL || device == NULL) - return -EINVAL; - - id = atoi(camera_id); - if (id < 0) - return -EINVAL; - - smdk4x12_camera = calloc(1, sizeof(struct smdk4x12_camera)); - smdk4x12_camera->config = smdk4x12_camera_config; - - if (smdk4x12_camera->config->v4l2_nodes_count > SMDK4x12_CAMERA_MAX_V4L2_NODES_COUNT) - goto error_preset; - - if (id >= smdk4x12_camera->config->presets_count) - goto error_preset; - - rc = smdk4x12_camera_start(smdk4x12_camera, id); - if (rc < 0) { - ALOGE("%s: Unable to start camera", __func__); - goto error; - } - - rc = smdk4x12_camera_capture_thread_start(smdk4x12_camera); - if (rc < 0) { - ALOGE("%s: Unable to start capture thread", __func__); - goto error; - } - - camera_device = calloc(1, sizeof(struct camera_device)); - camera_device->common.tag = HARDWARE_DEVICE_TAG; - camera_device->common.version = 0; - camera_device->common.module = (struct hw_module_t *) module; - camera_device->common.close = smdk4x12_camera_close; - - camera_device->ops = &smdk4x12_camera_ops; - camera_device->priv = smdk4x12_camera; - - *device = (struct hw_device_t *) &(camera_device->common); - - return 0; - -error: - smdk4x12_camera_stop(smdk4x12_camera); - -error_device: - if (camera_device != NULL) - free(camera_device); - -error_preset: - if (smdk4x12_camera != NULL) - free(smdk4x12_camera); - - return -1; -} - -int smdk4x12_camera_get_number_of_cameras(void) -{ - ALOGD("%s()", __func__); - - if (smdk4x12_camera_config == NULL || smdk4x12_camera_config->presets == NULL) { - ALOGE("%s: Unable to find proper camera config", __func__); - return -1; - } - - return smdk4x12_camera_config->presets_count; -} - -int smdk4x12_camera_get_camera_info(int id, struct camera_info *info) -{ - ALOGD("%s(%d, %p)", __func__, id, info); - - if (id < 0 || info == NULL) - return -EINVAL; - - if (smdk4x12_camera_config == NULL || smdk4x12_camera_config->presets == NULL) { - ALOGE("%s: Unable to find proper camera config", __func__); - return -1; - } - - if (id >= smdk4x12_camera_config->presets_count) - return -EINVAL; - - ALOGD("Selected camera: %s", smdk4x12_camera_config->presets[id].name); - - info->facing = smdk4x12_camera_config->presets[id].facing; - info->orientation = smdk4x12_camera_config->presets[id].orientation; - - return 0; -} - -struct hw_module_methods_t smdk4x12_camera_module_methods = { - .open = smdk4x12_camera_open, -}; - -struct camera_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = CAMERA_HARDWARE_MODULE_ID, - .name = "SMDK4x12 Camera", - .author = "Paul Kocialkowski", - .methods = &smdk4x12_camera_module_methods, - }, - .get_number_of_cameras = smdk4x12_camera_get_number_of_cameras, - .get_camera_info = smdk4x12_camera_get_camera_info, -}; diff --git a/camera/smdk4x12_camera.h b/camera/smdk4x12_camera.h deleted file mode 100644 index d1a3924..0000000 --- a/camera/smdk4x12_camera.h +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr> - * - * 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 3 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/>. - */ - -#include <stdlib.h> -#include <stdint.h> -#include <stdbool.h> -#include <pthread.h> - -#include <videodev2.h> -#include <videodev2_exynos_camera.h> -#include <videodev2_exynos_media.h> -#include <fimc.h> - -#include <s5c73m3.h> - -#include <jpeg_hal.h> -#include <Exif.h> - -#include <hardware/hardware.h> -#include <hardware/camera.h> - -#ifndef _SMDK4x12_CAMERA_H_ -#define _SMDK4x12_CAMERA_H_ - -#define SMDK4x12_CAMERA_MAX_V4L2_NODES_COUNT 4 - -#define SMDK4x12_CAMERA_CAPTURE_BUFFERS_COUNT 6 -#define SMDK4x12_CAMERA_PREVIEW_BUFFERS_COUNT 6 -#define SMDK4x12_CAMERA_RECORDING_BUFFERS_COUNT 6 -#define SMDK4x12_CAMERA_GRALLOC_BUFFERS_COUNT 3 - -#define SMDK4x12_CAMERA_PICTURE_OUTPUT_FORMAT V4L2_PIX_FMT_YUYV - -#define SMDK4x12_CAMERA_MSG_ENABLED(msg) (smdk4x12_camera->messages_enabled & msg) -#define SMDK4x12_CAMERA_CALLBACK_DEFINED(cb) (smdk4x12_camera->callbacks.cb != NULL) - -#define SMDK4x12_CAMERA_ALIGN(value) ((value + (0x10000 - 1)) & ~(0x10000 - 1)) - -/* - * Structures - */ - -struct smdk4x12_camera; - -struct list_head { - struct list_head *next; - struct list_head *prev; -}; - -enum smdk4x12_param_type { - EXYNOS_PARAM_INT, - EXYNOS_PARAM_FLOAT, - EXYNOS_PARAM_STRING, -}; - -union smdk4x12_param_data { - int integer; - float floating; - char *string; -}; - -struct smdk4x12_param { - struct list_head list; - - char *key; - union smdk4x12_param_data data; - enum smdk4x12_param_type type; -}; - -struct smdk4x12_camera_buffer { - void *pointer; - int address; - int length; - - int width; - int height; - int format; -}; - -struct smdk4x12_camera_capture_listener { - struct list_head list; - - int width; - int height; - int format; - - int (*callback)(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_camera_buffer *buffers, int buffers_count); - int busy; -}; - -struct smdk4x12_camera_mbus_resolution { - int width; - int height; - int mbus_width; - int mbus_height; -}; - -struct smdk4x12_camera_params { - char *preview_size_values; - char *preview_size; - char *preview_format_values; - char *preview_format; - char *preview_frame_rate_values; - int preview_frame_rate; - char *preview_fps_range_values; - char *preview_fps_range; - - char *picture_size_values; - char *picture_size; - char *picture_format_values; - char *picture_format; - char *jpeg_thumbnail_size_values; - int jpeg_thumbnail_width; - int jpeg_thumbnail_height; - int jpeg_thumbnail_quality; - int jpeg_quality; - - int video_snapshot_supported; - int full_video_snap_supported; - - char *recording_size; - char *recording_size_values; - char *recording_format; - - char *focus_mode; - char *focus_mode_values; - char *focus_distances; - char *focus_areas; - int max_num_focus_areas; - - int zoom_supported; - int smooth_zoom_supported; - char *zoom_ratios; - int zoom; - int max_zoom; - - int auto_exposure_lock_supported; - int auto_exposure_lock; - - int auto_white_balance_lock_supported; - int auto_white_balance_lock; - - char *flash_mode; - char *flash_mode_values; - - int exposure_compensation; - float exposure_compensation_step; - int min_exposure_compensation; - int max_exposure_compensation; - - char *whitebalance; - char *whitebalance_values; - - char *antibanding; - char *antibanding_values; - - char *scene_mode; - char *scene_mode_values; - - char *effect; - char *effect_values; - - char *iso; - char *iso_values; - - char *image_stabilization; - char *image_stabilization_values; -}; - -struct smdk4x12_camera_preset { - char *name; - int facing; - int orientation; - - int rotation; - int hflip; - int vflip; - - int capture_format; - int picture_format; - int fimc_is; - - float focal_length; - float horizontal_view_angle; - float vertical_view_angle; - - int metering; - - struct smdk4x12_camera_params params; - struct smdk4x12_camera_mbus_resolution *mbus_resolutions; - int mbus_resolutions_count; -}; - -struct smdk4x12_v4l2_node { - int id; - char *node; -}; - -struct smdk4x12_v4l2_output { - int enabled; - - int v4l2_id; - - int width; - int height; - int format; - - int buffer_width; - int buffer_height; - int buffer_format; - - camera_memory_t *memory; - int memory_address; -#ifdef EXYNOS_ION - int memory_ion_fd; -#endif - int memory_index; - int buffers_count; - int buffer_length; -}; - -struct smdk4x12_exif { - int enabled; - - exif_attribute_t attributes; - void *jpeg_thumbnail_data; - int jpeg_thumbnail_size; - - camera_memory_t *memory; - int memory_size; -}; - -struct smdk4x12_jpeg { - int enabled; - - int fd; - struct jpeg_buf buffer_in; - struct jpeg_buf buffer_out; - camera_memory_t *memory_in; - void *memory_in_pointer; -#ifdef EXYNOS_ION - int memory_in_ion_fd; -#endif - camera_memory_t *memory_out; - void *memory_out_pointer; - int memory_out_size; -#ifdef EXYNOS_ION - int memory_out_ion_fd; -#endif - - int width; - int height; - int format; - - int quality; -}; - -struct exynox_camera_config { - struct smdk4x12_camera_preset *presets; - int presets_count; - - struct smdk4x12_v4l2_node *v4l2_nodes; - int v4l2_nodes_count; -}; - -struct smdk4x12_camera_callbacks { - camera_notify_callback notify; - camera_data_callback data; - camera_data_timestamp_callback data_timestamp; - camera_request_memory request_memory; - void *user; -}; - -struct smdk4x12_camera { - int v4l2_fds[SMDK4x12_CAMERA_MAX_V4L2_NODES_COUNT]; - int ion_fd; - - struct exynox_camera_config *config; - struct smdk4x12_param *params; - - struct smdk4x12_camera_callbacks callbacks; - int callback_lock; - int messages_enabled; - - gralloc_module_t *gralloc; - - // Capture - - pthread_t capture_thread; - pthread_mutex_t capture_mutex; - pthread_mutex_t capture_lock_mutex; - int capture_thread_running; - int capture_thread_enabled; - - int capture_enabled; - struct smdk4x12_camera_capture_listener *capture_listeners; - camera_memory_t *capture_memory; - int capture_memory_address; - int capture_memory_index; - void *capture_yuv_buffer; - void *capture_jpeg_buffer; - int capture_exif_flash; - int capture_exif_iso; - int capture_exif_exposure; - int capture_exif_exposure_bias; - int capture_exif_exposure_time; - int capture_hybrid; - int capture_width; - int capture_height; - int capture_format; - int capture_buffers_count; - int capture_buffer_length; - - // Preview - - pthread_t preview_thread; - pthread_mutex_t preview_mutex; - pthread_mutex_t preview_lock_mutex; - int preview_thread_running; - int preview_thread_enabled; - - int preview_output_enabled; - struct smdk4x12_camera_capture_listener *preview_listener; - struct preview_stream_ops *preview_window; - struct smdk4x12_camera_buffer preview_buffer; - struct smdk4x12_v4l2_output preview_output; - - // Picture - - pthread_t picture_thread; - pthread_mutex_t picture_mutex; - pthread_mutex_t picture_lock_mutex; - int picture_thread_running; - int picture_thread_enabled; - - int picture_enabled; - int picture_completed; - struct smdk4x12_camera_capture_listener *picture_listener; - camera_memory_t *picture_memory; - struct smdk4x12_camera_buffer picture_jpeg_buffer; - struct smdk4x12_camera_buffer picture_jpeg_thumbnail_buffer; - struct smdk4x12_camera_buffer picture_yuv_buffer; - struct smdk4x12_camera_buffer picture_yuv_thumbnail_buffer; - time_t picture_focus_timestamp; - - // Recording - - pthread_t recording_thread; - pthread_mutex_t recording_mutex; - pthread_mutex_t recording_lock_mutex; - int recording_thread_running; - int recording_thread_enabled; - - int recording_output_enabled; - struct smdk4x12_camera_capture_listener *recording_listener; - camera_memory_t *recording_memory; - int recording_memory_index; - struct smdk4x12_camera_buffer recording_buffer; - struct smdk4x12_v4l2_output recording_output; - int recording_buffers_count; - int recording_buffer_length; - int recording_metadata; - - // Auto-focus - - pthread_t auto_focus_thread; - pthread_mutex_t auto_focus_mutex; - int auto_focus_thread_enabled; - int auto_focus_thread_running; - - int auto_focus_result; - - // Camera params - - int camera_rotation; - int camera_hflip; - int camera_vflip; - int camera_capture_format; - int camera_picture_format; - int camera_fimc_is; - int camera_focal_length; - int camera_metering; - - struct smdk4x12_camera_mbus_resolution *camera_mbus_resolutions; - int camera_mbus_resolutions_count; - - int camera_sensor_mode; - int fimc_is_mode; - - // Params - - int preview_width; - int preview_height; - int preview_format; - int preview_fps; - int picture_width; - int picture_height; - int picture_format; - int jpeg_thumbnail_width; - int jpeg_thumbnail_height; - int jpeg_thumbnail_quality; - int jpeg_quality; - int recording_width; - int recording_height; - int recording_format; - int focus_mode; - int focus_x; - int focus_y; - int zoom; - int ae_lock; - int awb_lock; - int flash_mode; - int exposure_compensation; - int whitebalance; - int antibanding; - int scene_mode; - int effect; - int iso; - int metering; - int image_stabilization; -}; - -struct smdk4x12_camera_addrs { - unsigned int type; - unsigned int y; - unsigned int cbcr; - unsigned int index; - unsigned int reserved; -}; - -// This is because the linux header uses anonymous union -struct smdk4x12_v4l2_ext_control { - __u32 id; - __u32 size; - __u32 reserved2[1]; - union { - __s32 value; - __s64 value64; - char *string; - } data; -} __attribute__ ((packed)); - -/* - * Camera - */ - -// Camera -int smdk4x12_camera_start(struct smdk4x12_camera *smdk4x12_camera, int id); -void smdk4x12_camera_stop(struct smdk4x12_camera *smdk4x12_camera); - -// Params -int smdk4x12_camera_params_init(struct smdk4x12_camera *smdk4x12_camera, int id); -int smdk4x12_camera_params_apply(struct smdk4x12_camera *smdk4x12_camera, int force); - -// Capture -int smdk4x12_camera_capture(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_capture_thread_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_capture_thread_stop(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_capture_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_capture_stop(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_capture_setup(struct smdk4x12_camera *smdk4x12_camera); -struct smdk4x12_camera_capture_listener *smdk4x12_camera_capture_listener_register( - struct smdk4x12_camera *smdk4x12_camera, int width, int height, int format, - int (*callback)(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_camera_buffer *buffers, int buffers_count)); -void smdk4x12_camera_capture_listener_unregister( - struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_capture_listener *listener); - -// Preview -int smdk4x12_camera_preview_output_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_preview_output_stop(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_preview_callback(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_buffer *buffers, int buffers_count); -int smdk4x12_camera_preview(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_preview_thread_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_preview_thread_stop(struct smdk4x12_camera *smdk4x12_camera); - -// Picture -int smdk4x12_camera_picture_callback(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_buffer *buffers, int buffers_count); -int smdk4x12_camera_picture(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_picture_thread_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_picture_thread_stop(struct smdk4x12_camera *smdk4x12_camera); - -// Recording -int smdk4x12_camera_recording_output_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_recording_output_stop(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_recording_callback(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_camera_buffer *buffers, int buffers_count); -void smdk4x12_camera_recording_frame_release(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_recording(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_camera_recording_thread_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_recording_thread_stop(struct smdk4x12_camera *smdk4x12_camera); - -// Auto-focus -int smdk4x12_camera_auto_focus(struct smdk4x12_camera *smdk4x12_camera, int auto_focus_status); -int smdk4x12_camera_auto_focus_thread_start(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_camera_auto_focus_thread_stop(struct smdk4x12_camera *smdk4x12_camera); - -/* - * EXIF - */ - -int smdk4x12_exif_start(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif *exif); -void smdk4x12_exif_stop(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_exif *exif); -int smdk4x12_exif(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_exif *exif); - -/* - * ION - */ - -#ifdef EXYNOS_ION -int smdk4x12_ion_init(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_ion_open(struct smdk4x12_camera *smdk4x12_camera); -void smdk4x12_ion_close(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_ion_alloc(struct smdk4x12_camera *smdk4x12_camera, int size); -int smdk4x12_ion_free(struct smdk4x12_camera *smdk4x12_camera, int fd); -int smdk4x12_ion_phys(struct smdk4x12_camera *smdk4x12_camera, int fd); -int smdk4x12_ion_msync(struct smdk4x12_camera *smdk4x12_camera, int fd, - int offset, int size); -#endif - -/* - * Jpeg - */ - -int smdk4x12_jpeg_start(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_jpeg *jpeg); -void smdk4x12_jpeg_stop(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_jpeg *jpeg); -int smdk4x12_jpeg(struct smdk4x12_camera *smdk4x12_camera, struct smdk4x12_jpeg *jpeg); - -/* - * Param - */ - -int smdk4x12_param_int_get(struct smdk4x12_camera *smdk4x12_camera, - char *key); -float smdk4x12_param_float_get(struct smdk4x12_camera *smdk4x12_camera, - char *key); -char *smdk4x12_param_string_get(struct smdk4x12_camera *smdk4x12_camera, - char *key); -int smdk4x12_param_int_set(struct smdk4x12_camera *smdk4x12_camera, - char *key, int integer); -int smdk4x12_param_float_set(struct smdk4x12_camera *smdk4x12_camera, - char *key, float floating); -int smdk4x12_param_string_set(struct smdk4x12_camera *smdk4x12_camera, - char *key, char *string); -char *smdk4x12_params_string_get(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_params_string_set(struct smdk4x12_camera *smdk4x12_camera, char *string); - -/* - * Utils - */ - -int list_head_insert(struct list_head *list, struct list_head *prev, - struct list_head *next); -void list_head_remove(struct list_head *list); - -int smdk4x12_camera_buffer_length(int width, int height, int format); -void smdk4x12_camera_yuv_planes(int width, int height, int format, int address, int *address_y, int *address_cb, int *address_cr); -int smdk4x12_gralloc_format(int format); - -/* - * V4L2 - */ - -int smdk4x12_v4l2_init(struct smdk4x12_camera *smdk4x12_camera); -int smdk4x12_v4l2_index(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id); -int smdk4x12_v4l2_fd(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id); - -int smdk4x12_v4l2_open(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id); -void smdk4x12_v4l2_close(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id); -int smdk4x12_v4l2_ioctl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int request, void *data); -int smdk4x12_v4l2_poll(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id); -int smdk4x12_v4l2_qbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int memory, int index, unsigned long userptr); -int smdk4x12_v4l2_qbuf_cap(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int index); -int smdk4x12_v4l2_qbuf_out(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int index, unsigned long userptr); -int smdk4x12_v4l2_dqbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int memory); -int smdk4x12_v4l2_dqbuf_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_dqbuf_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_reqbufs(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int memory, int count); -int smdk4x12_v4l2_reqbufs_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int count); -int smdk4x12_v4l2_reqbufs_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int count); -int smdk4x12_v4l2_querybuf(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int memory, int index); -int smdk4x12_v4l2_querybuf_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int index); -int smdk4x12_v4l2_querybuf_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int index); -int smdk4x12_v4l2_querycap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int flags); -int smdk4x12_v4l2_querycap_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_querycap_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_streamon(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type); -int smdk4x12_v4l2_streamon_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_streamon_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_streamoff(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type); -int smdk4x12_v4l2_streamoff_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_streamoff_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id); -int smdk4x12_v4l2_g_fmt(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int *width, int *height, int *fmt); -int smdk4x12_v4l2_g_fmt_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int *width, int *height, int *fmt); -int smdk4x12_v4l2_g_fmt_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int *width, int *height, int *fmt); -int smdk4x12_v4l2_s_fmt_pix(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int width, int height, int fmt, int field, - int priv); -int smdk4x12_v4l2_s_fmt_pix_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int width, int height, int fmt, int priv); -int smdk4x12_v4l2_s_fmt_pix_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int width, int height, int fmt, int priv); -int smdk4x12_v4l2_s_fmt_win(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int left, int top, int width, int height); -int smdk4x12_v4l2_enum_fmt(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int fmt); -int smdk4x12_v4l2_enum_fmt_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int fmt); -int smdk4x12_v4l2_enum_fmt_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int fmt); -int smdk4x12_v4l2_enum_input(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int id); -int smdk4x12_v4l2_s_input(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int id); -int smdk4x12_v4l2_g_ext_ctrls(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, struct v4l2_ext_control *control, int count); -int smdk4x12_v4l2_g_ctrl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int id, int *value); -int smdk4x12_v4l2_s_ctrl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int id, int value); -int smdk4x12_v4l2_s_parm(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, struct v4l2_streamparm *streamparm); -int smdk4x12_v4l2_s_parm_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, struct v4l2_streamparm *streamparm); -int smdk4x12_v4l2_s_parm_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, struct v4l2_streamparm *streamparm); -int smdk4x12_v4l2_s_crop(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int left, int top, int width, int height); -int smdk4x12_v4l2_s_crop_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int left, int top, int width, int height); -int smdk4x12_v4l2_s_crop_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int left, int top, int width, int height); -int smdk4x12_v4l2_g_fbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - void **base, int *width, int *height, int *fmt); -int smdk4x12_v4l2_s_fbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - void *base, int width, int height, int fmt); - -/* - * V4L2 Output - */ - -int smdk4x12_v4l2_output_start(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output); -void smdk4x12_v4l2_output_stop(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output); -int smdk4x12_v4l2_output(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output, int buffer_address); -int smdk4x12_v4l2_output_release(struct smdk4x12_camera *smdk4x12_camera, - struct smdk4x12_v4l2_output *output); - -#endif diff --git a/camera/smdk4x12_v4l2.c b/camera/smdk4x12_v4l2.c deleted file mode 100644 index e8b130e..0000000 --- a/camera/smdk4x12_v4l2.c +++ /dev/null @@ -1,739 +0,0 @@ -/* - * Copyright (C) 2013 Paul Kocialkowski <contact@paulk.fr> - * - * Based on crespo libcamera and exynos4 hal libcamera: - * Copyright 2008, The Android Open Source Project - * Copyright 2010, Samsung Electronics Co. LTD - * - * 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 3 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/>. - */ - -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <malloc.h> -#include <poll.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/time.h> -#include <sys/mman.h> -#include <sys/ioctl.h> - -#include <asm/types.h> - -#define LOG_TAG "smdk4x12_v4l2" -#include <utils/Log.h> - -#include "smdk4x12_camera.h" - -int smdk4x12_v4l2_init(struct smdk4x12_camera *smdk4x12_camera) -{ - int i; - - for (i = 0; i < SMDK4x12_CAMERA_MAX_V4L2_NODES_COUNT; i++) - smdk4x12_camera->v4l2_fds[i] = -1; - - return 0; -} - -int smdk4x12_v4l2_index(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) -{ - int index; - int i; - - if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL || - smdk4x12_camera->config->v4l2_nodes == NULL) - return -EINVAL; - - if (smdk4x12_v4l2_id > smdk4x12_camera->config->v4l2_nodes_count) - return -1; - - index = -1; - for (i = 0; i < smdk4x12_camera->config->v4l2_nodes_count; i++) { - if (smdk4x12_camera->config->v4l2_nodes[i].id == smdk4x12_v4l2_id && - smdk4x12_camera->config->v4l2_nodes[i].node != NULL) { - index = i; - } - } - - return index; -} - -int smdk4x12_v4l2_fd(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) -{ - int index; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - index = smdk4x12_v4l2_index(smdk4x12_camera, smdk4x12_v4l2_id); - if (index < 0) { - ALOGE("%s: Unable to get v4l2 index for id %d", __func__, smdk4x12_v4l2_id); - return -1; - } - - return smdk4x12_camera->v4l2_fds[index]; -} - -int smdk4x12_v4l2_open(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) -{ - char *node; - int index; - int fd; - - if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL || - smdk4x12_camera->config->v4l2_nodes == NULL) - return -EINVAL; - - index = smdk4x12_v4l2_index(smdk4x12_camera, smdk4x12_v4l2_id); - if (index < 0) { - ALOGE("%s: Unable to get v4l2 node for id %d", __func__, smdk4x12_v4l2_id); - return -1; - } - - node = smdk4x12_camera->config->v4l2_nodes[index].node; - fd = open(node, O_RDWR); - if (fd < 0) { - ALOGE("%s: Unable to open v4l2 node for id %d", __func__, smdk4x12_v4l2_id); - return -1; - } - - smdk4x12_camera->v4l2_fds[index] = fd; - - return 0; -} - -void smdk4x12_v4l2_close(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) -{ - int index; - - if (smdk4x12_camera == NULL || smdk4x12_camera->config == NULL || - smdk4x12_camera->config->v4l2_nodes == NULL) - return; - - index = smdk4x12_v4l2_index(smdk4x12_camera, smdk4x12_v4l2_id); - if (index < 0) { - ALOGE("%s: Unable to get v4l2 node for id %d", __func__, smdk4x12_v4l2_id); - return; - } - - if (smdk4x12_camera->v4l2_fds[index] >= 0) - close(smdk4x12_camera->v4l2_fds[index]); - - smdk4x12_camera->v4l2_fds[index] = -1; -} - -int smdk4x12_v4l2_ioctl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int request, void *data) -{ - int fd; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - fd = smdk4x12_v4l2_fd(smdk4x12_camera, smdk4x12_v4l2_id); - if (fd < 0) { - ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, smdk4x12_v4l2_id); - return -1; - } - - return ioctl(fd, request, data); -} - -int smdk4x12_v4l2_poll(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id) -{ - struct pollfd events; - int fd; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - fd = smdk4x12_v4l2_fd(smdk4x12_camera, smdk4x12_v4l2_id); - if (fd < 0) { - ALOGE("%s: Unable to get v4l2 fd for id %d", __func__, smdk4x12_v4l2_id); - return -1; - } - - memset(&events, 0, sizeof(events)); - events.fd = fd; - events.events = POLLIN | POLLERR; - - rc = poll(&events, 1, 1000); - if (rc < 0 || events.revents & POLLERR) - return -1; - - return rc; -} - -int smdk4x12_v4l2_qbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int memory, int index, unsigned long userptr) -{ - struct v4l2_buffer buffer; - int rc; - - if (smdk4x12_camera == NULL || index < 0) - return -EINVAL; - - memset(&buffer, 0, sizeof(buffer)); - buffer.type = type; - buffer.memory = memory; - buffer.index = index; - - if (userptr) - buffer.m.userptr = userptr; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_QBUF, &buffer); - return rc; -} - -int smdk4x12_v4l2_qbuf_cap(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int index) -{ - return smdk4x12_v4l2_qbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_MEMORY_MMAP, index, 0); -} - -int smdk4x12_v4l2_qbuf_out(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int index, unsigned long userptr) -{ - return smdk4x12_v4l2_qbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - V4L2_MEMORY_USERPTR, index, userptr); -} - -int smdk4x12_v4l2_dqbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int memory) -{ - struct v4l2_buffer buffer; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - memset(&buffer, 0, sizeof(buffer)); - buffer.type = type; - buffer.memory = memory; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_DQBUF, &buffer); - if (rc < 0) - return rc; - - return buffer.index; -} - -int smdk4x12_v4l2_dqbuf_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_dqbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_MEMORY_MMAP); -} - -int smdk4x12_v4l2_dqbuf_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_dqbuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - V4L2_MEMORY_USERPTR); -} - -int smdk4x12_v4l2_reqbufs(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int memory, int count) -{ - struct v4l2_requestbuffers requestbuffers; - int rc; - - if (smdk4x12_camera == NULL || count < 0) - return -EINVAL; - - requestbuffers.type = type; - requestbuffers.count = count; - requestbuffers.memory = memory; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_REQBUFS, &requestbuffers); - if (rc < 0) - return rc; - - return requestbuffers.count; -} - -int smdk4x12_v4l2_reqbufs_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int count) -{ - return smdk4x12_v4l2_reqbufs(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_MEMORY_MMAP, count); -} - -int smdk4x12_v4l2_reqbufs_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int count) -{ - return smdk4x12_v4l2_reqbufs(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - V4L2_MEMORY_USERPTR, count); -} - -int smdk4x12_v4l2_querybuf(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int memory, int index) -{ - struct v4l2_buffer buffer; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - memset(&buffer, 0, sizeof(buffer)); - buffer.type = type; - buffer.memory = memory; - buffer.index = index; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_QUERYBUF, &buffer); - if (rc < 0) - return rc; - - return buffer.length; -} - -int smdk4x12_v4l2_querybuf_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int index) -{ - return smdk4x12_v4l2_querybuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_MEMORY_MMAP, index); -} - -int smdk4x12_v4l2_querybuf_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int index) -{ - return smdk4x12_v4l2_querybuf(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - V4L2_MEMORY_USERPTR, index); -} - -int smdk4x12_v4l2_querycap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int flags) -{ - struct v4l2_capability cap; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_QUERYCAP, &cap); - if (rc < 0) - return rc; - - if (!(cap.capabilities & flags)) - return -1; - - return 0; -} - -int smdk4x12_v4l2_querycap_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_querycap(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_CAP_VIDEO_CAPTURE); -} - -int smdk4x12_v4l2_querycap_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_querycap(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_CAP_VIDEO_OUTPUT); -} - -int smdk4x12_v4l2_streamon(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type) -{ - enum v4l2_buf_type buf_type; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - buf_type = type; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_STREAMON, &buf_type); - return rc; -} - -int smdk4x12_v4l2_streamon_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_streamon(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); -} - -int smdk4x12_v4l2_streamon_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_streamon(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); -} - -int smdk4x12_v4l2_streamoff(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type) -{ - enum v4l2_buf_type buf_type; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - buf_type = type; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_STREAMOFF, &buf_type); - return rc; -} - -int smdk4x12_v4l2_streamoff_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_streamoff(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE); -} - -int smdk4x12_v4l2_streamoff_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id) -{ - return smdk4x12_v4l2_streamoff(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT); -} - -int smdk4x12_v4l2_g_fmt(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int *width, int *height, int *fmt) -{ - struct v4l2_format format; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - format.type = type; - format.fmt.pix.field = V4L2_FIELD_NONE; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_FMT, &format); - if (rc < 0) - return rc; - - if (width != NULL) - *width = format.fmt.pix.width; - if (height != NULL) - *height = format.fmt.pix.height; - if (fmt != NULL) - *fmt = format.fmt.pix.pixelformat; - - return 0; -} - -int smdk4x12_v4l2_g_fmt_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int *width, int *height, int *fmt) -{ - return smdk4x12_v4l2_g_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - width, height, fmt); -} - -int smdk4x12_v4l2_g_fmt_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int *width, int *height, int *fmt) -{ - return smdk4x12_v4l2_g_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - width, height, fmt); -} - -int smdk4x12_v4l2_s_fmt_pix(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int width, int height, int fmt, int field, - int priv) -{ - struct v4l2_format format; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - memset(&format, 0, sizeof(format)); - format.type = type; - format.fmt.pix.width = width; - format.fmt.pix.height = height; - format.fmt.pix.pixelformat = fmt; - format.fmt.pix.field = field; - format.fmt.pix.priv = priv; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_FMT, &format); - return rc; - - return 0; -} - -int smdk4x12_v4l2_s_fmt_pix_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int width, int height, int fmt, int priv) -{ - return smdk4x12_v4l2_s_fmt_pix(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - width, height, fmt, V4L2_FIELD_NONE, priv); -} - -int smdk4x12_v4l2_s_fmt_pix_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int width, int height, int fmt, int priv) -{ - return smdk4x12_v4l2_s_fmt_pix(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - width, height, fmt, V4L2_FIELD_NONE, priv); -} - -int smdk4x12_v4l2_s_fmt_win(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int left, int top, int width, int height) -{ - struct v4l2_format format; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - memset(&format, 0, sizeof(format)); - format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY; - format.fmt.win.w.left = left; - format.fmt.win.w.top = top; - format.fmt.win.w.width = width; - format.fmt.win.w.height = height; - - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_FMT, &format); - return rc; -} - -int smdk4x12_v4l2_enum_fmt(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int type, int fmt) -{ - struct v4l2_fmtdesc fmtdesc; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - fmtdesc.type = type; - fmtdesc.index = 0; - - do { - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_ENUM_FMT, &fmtdesc); - if (rc < 0) - return rc; - - if (fmtdesc.pixelformat == (unsigned int) fmt) - return 0; - - fmtdesc.index++; - } while (rc >= 0); - - return -1; -} - -int smdk4x12_v4l2_enum_fmt_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int fmt) -{ - return smdk4x12_v4l2_enum_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - fmt); -} - -int smdk4x12_v4l2_enum_fmt_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int fmt) -{ - return smdk4x12_v4l2_enum_fmt(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - fmt); -} - -int smdk4x12_v4l2_enum_input(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int id) -{ - struct v4l2_input input; - int rc; - - if (smdk4x12_camera == NULL || id < 0) - return -EINVAL; - - input.index = id; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_ENUMINPUT, &input); - if (rc < 0) - return rc; - - if (input.name[0] == '\0') - return -1; - - return 0; -} - -int smdk4x12_v4l2_s_input(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int id) -{ - struct v4l2_input input; - int rc; - - if (smdk4x12_camera == NULL || id < 0) - return -EINVAL; - - input.index = id; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_INPUT, &input); - return rc; -} - -int smdk4x12_v4l2_g_ext_ctrls(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, struct v4l2_ext_control *control, int count) -{ - struct v4l2_ext_controls controls; - int rc; - - if (smdk4x12_camera == NULL || control == NULL) - return -EINVAL; - - memset(&controls, 0, sizeof(controls)); - controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA; - controls.count = count; - controls.controls = control; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_EXT_CTRLS, &controls); - return rc; -} - -int smdk4x12_v4l2_g_ctrl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int id, int *value) -{ - struct v4l2_control control; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - control.id = id; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_CTRL, &control); - if (rc < 0) - return rc; - - if (value != NULL) - *value = control.value; - - return 0; -} - -int smdk4x12_v4l2_s_ctrl(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int id, int value) -{ - struct v4l2_control control; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - control.id = id; - control.value = value; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_CTRL, &control); - if (rc < 0) - return rc; - - return control.value; -} - -int smdk4x12_v4l2_s_parm(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, struct v4l2_streamparm *streamparm) -{ - int rc; - - if (smdk4x12_camera == NULL || streamparm == NULL) - return -EINVAL; - - streamparm->type = type; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_PARM, streamparm); - return rc; -} - -int smdk4x12_v4l2_s_parm_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, struct v4l2_streamparm *streamparm) -{ - return smdk4x12_v4l2_s_parm(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - streamparm); -} - -int smdk4x12_v4l2_s_parm_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, struct v4l2_streamparm *streamparm) -{ - return smdk4x12_v4l2_s_parm(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - streamparm); -} - -int smdk4x12_v4l2_s_crop(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - int type, int left, int top, int width, int height) -{ - struct v4l2_crop crop; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - crop.type = type; - crop.c.left = left; - crop.c.top = top; - crop.c.width = width; - crop.c.height = height; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_CROP, &crop); - return rc; -} - -int smdk4x12_v4l2_s_crop_cap(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int left, int top, int width, int height) -{ - return smdk4x12_v4l2_s_crop(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE, - left, top, width, height); -} - -int smdk4x12_v4l2_s_crop_out(struct smdk4x12_camera *smdk4x12_camera, - int smdk4x12_v4l2_id, int left, int top, int width, int height) -{ - return smdk4x12_v4l2_s_crop(smdk4x12_camera, smdk4x12_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT, - left, top, width, height); -} - -int smdk4x12_v4l2_g_fbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - void **base, int *width, int *height, int *fmt) -{ - struct v4l2_framebuffer framebuffer; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_G_FBUF, &framebuffer); - if (rc < 0) - return rc; - - if (base != NULL) - *base = framebuffer.base; - if (width != NULL) - *width = framebuffer.fmt.width; - if (height != NULL) - *height = framebuffer.fmt.height; - if (fmt != NULL) - *fmt = framebuffer.fmt.pixelformat; - - return 0; -} - -int smdk4x12_v4l2_s_fbuf(struct smdk4x12_camera *smdk4x12_camera, int smdk4x12_v4l2_id, - void *base, int width, int height, int fmt) -{ - struct v4l2_framebuffer framebuffer; - int rc; - - if (smdk4x12_camera == NULL) - return -EINVAL; - - memset(&framebuffer, 0, sizeof(framebuffer)); - framebuffer.base = base; - framebuffer.fmt.width = width; - framebuffer.fmt.height = height; - framebuffer.fmt.pixelformat = fmt; - - rc = smdk4x12_v4l2_ioctl(smdk4x12_camera, smdk4x12_v4l2_id, VIDIOC_S_FBUF, &framebuffer); - return rc; -} |