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 <ExynosExif.h>
22 #include <hardware/exynos/ExynosExif.h>
23 #include <pthread.h>
24 
25 #include <memory>
26 
27 #include "ExynosJpegApi.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,
83                                  int src_buftype);
84     size_t RemoveTrailingDummies(char* base, size_t len);
85     ssize_t FinishCompression(size_t mainlen, size_t thumblen);
86     bool ProcessExif(char* base, size_t limit, exif_attribute_t* exifInfo, extra_appinfo_t* extra);
87     static void* tCompressThumbnail(void* p);
88     bool PrepareCompression(bool thumbnail);
89 
90     // IsThumbGenerationNeeded - true if thumbnail image needed to be generated from the main image
91     //                           It also implies that a worker thread is generated to generate
92     //                           thumbnail concurrently.
IsThumbGenerationNeeded()93     inline bool IsThumbGenerationNeeded() { return !TestState(STATE_NO_CREATE_THUMBIMAGE); }
NoThumbGenerationNeeded()94     inline void NoThumbGenerationNeeded() { SetState(STATE_NO_CREATE_THUMBIMAGE); }
ThumbGenerationNeeded()95     inline void ThumbGenerationNeeded() { ClearState(STATE_NO_CREATE_THUMBIMAGE); }
96 
IsBTBCompressionSupported()97     inline bool IsBTBCompressionSupported() {
98         return !!(GetDeviceCapabilities() & V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION) &&
99                 !TestState(STATE_NO_BTBCOMP);
100     }
101 
102 protected:
103     virtual bool EnsureFormatIsApplied();
104 
105 public:
106     ExynosJpegEncoderForCamera(bool bBTBComp = true);
107     virtual ~ExynosJpegEncoderForCamera();
108 
109     int encode(int* size, exif_attribute_t* exifInfo, char** pcJpegBuffer,
110                debug_attribute_t* debugInfo = 0);
111     int encode(int* size, exif_attribute_t* exifInfo, int fdJpegBuffer, char** pcJpegBuffer,
112                debug_attribute_t* debugInfo = 0);
113     int encode(int* size, exif_attribute_t* exifInfo, int fdJpegBuffer, char** pcJpegBuffer,
114                extra_appinfo_t* appInfo = 0);
115     int setInBuf2(int* piBuf, int* iSize);
116     int setInBuf2(char** pcBuf, int* iSize);
117     int setThumbnailSize(int w, int h);
118     int setThumbnailQuality(int quality);
119     int setThumbnailPadding(const unsigned char* padding, unsigned int num_planes);
120 
setExtScalerNum(int csc_hwscaler_id)121     void setExtScalerNum(int csc_hwscaler_id) { m_iHWScalerID = csc_hwscaler_id; }
122 
EnableHWFC()123     void EnableHWFC() {
124         SetState(STATE_HWFC_ENABLED);
125         GetCompressor().SetAuxFlags(EXYNOS_HWJPEG_AUXOPT_ENABLE_HWFC);
126     }
DisableHWFC()127     void DisableHWFC() {
128         GetCompressor().ClearAuxFlags(EXYNOS_HWJPEG_AUXOPT_ENABLE_HWFC);
129         ClearState(STATE_HWFC_ENABLED);
130     }
131 
132     ssize_t WaitForCompression();
133 
134     size_t GetThumbnailImage(char* buffer, size_t buflen);
135 };
136 
137 #endif //__HARDWARE_EXYNOS_JPEG_ENCODER_FOR_CAMERA_H__
138