1 /*
2  * Copyright Samsung Electronics Co.,LTD.
3  * Copyright (C) 2015 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef __HARDWARE_EXYNOS_JPEG_ENCODER_FOR_CAMERA_H__
19 #define __HARDWARE_EXYNOS_JPEG_ENCODER_FOR_CAMERA_H__
20 
21 #include <memory>
22 
23 #include <pthread.h>
24 
25 #include <ExynosExif.h>
26 #include "ExynosJpegApi.h"
27 #include <hardware/exynos/ExynosExif.h>
28 
29 class CAppMarkerWriter; // defined in libhwjpeg/AppMarkerWriter.h
30 class ThumbnailScaler; // defined in libhwjpeg/thumbnail_scaler.h
31 
32 class ExynosJpegEncoderForCamera: public ExynosJpegEncoder {
33     enum {
34         STATE_THUMBSIZE_CHANGED = STATE_BASE_MAX << 0,
35         STATE_HWFC_ENABLED = STATE_BASE_MAX << 1,
36         STATE_NO_CREATE_THUMBIMAGE = STATE_BASE_MAX << 2,
37         STATE_NO_BTBCOMP = STATE_BASE_MAX << 3,
38     };
39 
40     CHWJpegCompressor *m_phwjpeg4thumb;
41     std::unique_ptr<ThumbnailScaler> mThumbnailScaler;
42     int m_fdIONClient;
43     int m_fdIONThumbImgBuffer;
44     char *m_pIONThumbImgBuffer;
45     size_t m_szIONThumbImgBuffer;
46     char *m_pIONThumbJpegBuffer;
47     int m_fdIONThumbJpegBuffer;
48     size_t m_szIONThumbJpegBuffer;
49 
50     int m_nThumbWidth;
51     int m_nThumbHeight;
52     int m_nThumbQuality;
53 
54     int m_iHWScalerID;
55 
56     /*
57      * The following four placeholders and size vairables are used
58      * by asynchronous(non-blocking) compression
59      */
60     char *m_pStreamBase;
61     size_t m_nStreamSize;
62 
63     char m_fThumbBufferType;
64 
65     union {
66         char *m_pThumbnailImageBuffer[3]; // checkInBufType() == JPEG_BUF_TYPE_USER_PTR
67         int m_fdThumbnailImageBuffer[3]; // checkInBufType() == JPEG_BUF_TYPE_DMA_BUF
68     };
69     size_t m_szThumbnailImageLen[3];
70 
71     CAppMarkerWriter *m_pAppWriter;
72 
73     pthread_t m_threadWorker;
74 
75     extra_appinfo_t m_extraInfo;
76     app_info_t m_appInfo[15];
77 
78     bool AllocThumbBuffer(int v4l2Format); /* For single compression */
79     bool AllocThumbJpegBuffer(); /* For BTB compression */
80     bool GenerateThumbnailImage();
81     size_t CompressThumbnail();
82     size_t CompressThumbnailOnly(size_t limit, int quality, unsigned int v4l2Format, int src_buftype);
83     size_t RemoveTrailingDummies(char *base, size_t len);
84     ssize_t FinishCompression(size_t mainlen, size_t thumblen);
85     bool ProcessExif(char *base, size_t limit, exif_attribute_t *exifInfo, extra_appinfo_t *extra);
86     static void *tCompressThumbnail(void *p);
87     bool PrepareCompression(bool thumbnail);
88 
89     // IsThumbGenerationNeeded - true if thumbnail image needed to be generated from the main image
90     //                           It also implies that a worker thread is generated to generate thumbnail concurrently.
IsThumbGenerationNeeded()91     inline bool IsThumbGenerationNeeded() { return !TestState(STATE_NO_CREATE_THUMBIMAGE); }
NoThumbGenerationNeeded()92     inline void NoThumbGenerationNeeded() { SetState(STATE_NO_CREATE_THUMBIMAGE); }
ThumbGenerationNeeded()93     inline void ThumbGenerationNeeded() { ClearState(STATE_NO_CREATE_THUMBIMAGE); }
94 
IsBTBCompressionSupported()95     inline bool IsBTBCompressionSupported() {
96         return !!(GetDeviceCapabilities() & V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION) &&
97                     !TestState(STATE_NO_BTBCOMP);
98     }
99 protected:
100     virtual bool EnsureFormatIsApplied();
101 public:
102     ExynosJpegEncoderForCamera(bool bBTBComp = true);
103     virtual ~ExynosJpegEncoderForCamera();
104 
105     int encode(int *size, exif_attribute_t *exifInfo, char** pcJpegBuffer, debug_attribute_t *debugInfo = 0);
106     int encode(int *size, exif_attribute_t *exifInfo, int fdJpegBuffer, char** pcJpegBuffer, debug_attribute_t *debugInfo = 0);
107     int encode(int *size, exif_attribute_t *exifInfo, int fdJpegBuffer, char** pcJpegBuffer, extra_appinfo_t *appInfo = 0);
108     int setInBuf2(int *piBuf, int *iSize);
109     int setInBuf2(char **pcBuf, int *iSize);
110     int setThumbnailSize(int w, int h);
111     int setThumbnailQuality(int quality);
112 
setExtScalerNum(int csc_hwscaler_id)113     void setExtScalerNum(int csc_hwscaler_id) { m_iHWScalerID = csc_hwscaler_id; }
114 
EnableHWFC()115     void EnableHWFC() {
116         SetState(STATE_HWFC_ENABLED);
117         GetCompressor().SetAuxFlags(EXYNOS_HWJPEG_AUXOPT_ENABLE_HWFC);
118     }
DisableHWFC()119     void DisableHWFC() {
120         GetCompressor().ClearAuxFlags(EXYNOS_HWJPEG_AUXOPT_ENABLE_HWFC);
121         ClearState(STATE_HWFC_ENABLED);
122     }
123 
124     ssize_t WaitForCompression();
125 
126     size_t GetThumbnailImage(char *buffer, size_t buflen);
127 
128     virtual int destroy(void);
129 };
130 
131 #endif //__HARDWARE_EXYNOS_JPEG_ENCODER_FOR_CAMERA_H__
132