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 __EXYNOS_HWJPEG_H__
19 #define __EXYNOS_HWJPEG_H__
20 
21 #include <cstddef> // size_t
22 /*
23  * exynos-hwjpeg.h does not include videodev2.h because Exynos HAL code may
24  * define its version of videodev2.h that may differ from <linux/videodev2.h>
25  * of the current Linux version.
26  * To prevent conflict different versions of videodev2.h, this header file does
27  * not include videodev2.h even though it depends on the data types defined in
28  * videodev2.h.
29  * Therefore, the source files that include this header file, they should
30  * include their proper version of videodev2.h.
31  */
32 #ifndef VIDEO_MAX_PLANES
33 #error 'linux/videodev2.h' should be included before 'exynos-hwjpeg.h'
34 #endif
35 
36 #if VIDEO_MAX_PLANES < 6
37 #error VIDEO_MAX_PLANES should not be smaller than 6
38 #endif
39 
40 // Exynos JPEG specific device capabilities
41 // Defined in the driver. Not in videodev2.h
42 #define V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION       0x0100
43 #define V4L2_CAP_EXYNOS_JPEG_B2B_COMPRESSION     0x0200
44 #define V4L2_CAP_EXYNOS_JPEG_HWFC                0x0400
45 #define V4L2_CAP_EXYNOS_JPEG_HWFC_EMBEDDED       0x0800
46 #define V4L2_CAP_EXYNOS_JPEG_MAX_STREAMSIZE      0x1000
47 #define V4L2_CAP_EXYNOS_JPEG_NO_STREAMBASE_ALIGN 0x2000
48 #define V4L2_CAP_EXYNOS_JPEG_NO_IMAGEBASE_ALIGN  0x4000
49 #define V4L2_CAP_EXYNOS_JPEG_NO_BUFFER_OVERRUN   0x8000
50 #define V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_FROM_SOS 0x10000
51 #define V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_CROP  0x20000
52 #define V4L2_CAP_EXYNOS_JPEG_DOWNSCALING         0x40000
53 #define V4L2_CAP_EXYNOS_JPEG_DMABUF_OFFSET       0x80000
54 // EXYNOS HWJPEG specific auxiliary option flags
55 // The flags are common to all derived classes of CHWJpegCompressor
56 // but if a derived class does not support for a specified flag,
57 // it is discarded and ignored silently.
58 #define EXYNOS_HWJPEG_AUXOPT_ENABLE_HWFC        (1 << 4)
59 #define EXYNOS_HWJPEG_AUXOPT_SRC_NOCACHECLEAN   (1 << 8)
60 #define EXYNOS_HWJPEG_AUXOPT_DST_NOCACHECLEAN   (1 << 9)
61 
62 /*
63  * CHWJpegBase - The base class of JPEG compression and decompression
64  *
65  * This class contains the following information:
66  * - The open file descriptor of the device node
67  * - The flags to describe the state of the operations
68  * - The falgs to indicate the capability of HWJPEG
69  * This class also defines the getters and the setters of flags.
70  */
71 class CHWJpegBase {
72     int m_iFD;
73     unsigned int m_uiDeviceCaps;
74     /*
75      * Auxiliary option flags are implementation specific to derived classes
76      * of CHWJpegCompressor. Even though the flags are common to all derived
77      * classes, they should identify their supporting flags and ignore the
78      * other flags.
79      * NOTE that the flag is volatile. That means the flags stored in
80      * m_uiAuxFlags is cleared when it is read by GetAuxFlags().
81      *
82      */
83     unsigned int m_uiAuxFlags;
84 protected:
85     CHWJpegBase(const char *path);
86     virtual ~CHWJpegBase();
GetDeviceFD()87     int GetDeviceFD() { return m_iFD; }
SetDeviceCapabilities(unsigned int cap)88     void SetDeviceCapabilities(unsigned int cap) { m_uiDeviceCaps = cap; }
GetAuxFlags()89     unsigned int GetAuxFlags() { return m_uiAuxFlags; }
90 public:
GetDeviceCapabilities()91     unsigned int GetDeviceCapabilities() { return m_uiDeviceCaps; }
IsDeviceCapability(unsigned int cap_flags)92     bool IsDeviceCapability(unsigned int cap_flags) { return (m_uiDeviceCaps & cap_flags) == cap_flags; }
93 
94     /*
95      * Okay - Test if the object is correctly initialized
96      * @return: true if this object is correctly initialized and ready to use.
97      *          false, otherwise.
98      *
99      * A user that creates this object *must* test if the object is successfully
100      * created because some initialization in the constructor may fail.
101      */
Okay()102     bool Okay() { return m_iFD >= 0; }
103     operator bool() { return Okay(); }
104 
105     /*
106      * SetAuxFlags - Configure HWJPEG auxiliary options
107      * @auxflags: a set of bit flags. The flags are prefixed by EXYNOS_HWJPEG_AUXOPT
108      *            and defined separately in this file.
109      *
110      * SetAuxFlags() is *not* thread-safe. Racing calls to SetAuxFlags() between
111      * multiple threads may cause the flags inconsistent. Moreover, Racing between
112      * SetAuxFlags() call by the users and reading the flags by the libhwjpeg
113      * causes incomplete hwjpeg configuration.
114      */
115     void SetAuxFlags(unsigned int auxflags);
116 
117     /*
118      * ClearAuxFlags - Removes HWJPEG auxiliary options
119      * @auxflags: a set of bit flags to clear. The flags are prefixed by EXYNOS_HWJPEG_AUXOPT
120      *            and defined separately in this file.
121      *
122      * ClearAuxFlags() is *not* thread-safe. Racing calls to ClearAuxFlags() between
123      * multiple threads may cause the flags inconsistent. Moreover, Racing between
124      * ClearAuxFlags() call by the users and reading the flags by the libhwjpeg
125      * causes incomplete hwjpeg configuration.
126      */
127     void ClearAuxFlags(unsigned int auxflags);
128 };
129 
130 /*
131  * CHWJpegCompressor - The abstract class of HW JPEG compression accelerator
132  *
133  * This class is *not* thread-safe. If an instance of this class is handled by
134  * multiple threads, the users of the instance should care about the thread
135  * synchronization.
136  *
137  * CHWJpegCompressor is able to check if the number of configured image buffers
138  * are sufficient. It depends on the configured image format. Therefore, it is
139  * better to configure the image format and the size prior to configure image
140  * buffers. If back-to-back compression is required, it is *important* to know
141  * how many buffers are required for an image. Thus it is *strongly* recommented
142  * to configure image format and sizes before configuring image buffers.
143  */
144 class CHWJpegCompressor : public CHWJpegBase {
145     size_t m_nLastStreamSize;
146     size_t m_nLastThumbStreamSize;
147 protected:
148     void SetStreamSize(size_t main_size, size_t secondary_size = 0) {
149         m_nLastStreamSize = main_size;
150         m_nLastThumbStreamSize = secondary_size;
151     }
152 
GetStreamSize(size_t * secondary_size)153     ssize_t GetStreamSize(size_t *secondary_size) {
154         if (secondary_size)
155             *secondary_size = m_nLastThumbStreamSize;
156         return static_cast<ssize_t>(m_nLastStreamSize);
157     }
158 public:
CHWJpegCompressor(const char * path)159     CHWJpegCompressor(const char *path): CHWJpegBase(path), m_nLastStreamSize(0), m_nLastThumbStreamSize(0) { }
160 
161     /*
162      * SetImageFormat - Configure uncompressed image format, width and height
163      * @v4l2_fmt[in] : Image pixel format defined in <linux/videodev2.h>
164      * @width[in]      : Width of the primary uncompressed image in the number of pixels
165      * @height[in]     : Height of the primary uncompressed image in the number of pixels
166      * @sec_width[in]  : Width of the secondary uncompressed image in the number of pixels (optional)
167      * @sec_height[in] : Height of the secondary uncompressed image in the number of pixels (optional)
168      * @return : true if configuration of image pixel format and size is successful.
169      *           false, otherwise.
170      *
171      * The primary and the secondary image format should be same. There is no way
172      * to configure different image formats for them.
173      */
174     virtual bool SetImageFormat(unsigned int v4l2_fmt, unsigned int width, unsigned int height,
175                               unsigned int sec_width = 0, unsigned int sec_height = 0) = 0;
176 
177     /*
178      * GetImageBufferSizes - Ask the required buffer sizes for the given image format
179      * @buf_sizes[out] : array of buffer sizes.
180      * @num_buffers[in/out]: number of elements in @buf_sizes intially.
181      *                       number assigned buffer sizes to @buf_sizes on return.
182      * @return: true if the @buf_sizes and @num_buffers are initialized successfully.
183      *          false, otherwise
184      *
185      * It should be called after SetImageFormat() SetImageSize() are called. Otherwise,
186      * the returned buffer sizes are not correct.
187      */
188     virtual bool GetImageBufferSizes(size_t buf_sizes[], unsigned int *num_bufffers) = 0;
189     /*
190      * SetChromaSampFactor - Configure the chroma subsampling factor for JPEG stream
191      * @horizontal[in] : horizontal chroma subsampling factor
192      * @vertical[in]   : vertical chroma subsampling factor
193      * @return: true if chroma subsamping factors are configured successfully,
194      *          false if the factors are invalid.
195      */
196     virtual bool SetChromaSampFactor(unsigned int horizontal, unsigned int vertical) = 0;
197     /*
198      * SetQuality - Configure quality factor for JPEG compression
199      * @quality_factor[in]  : JPEG compression quality factor between 1 and 100 for the primary image
200      * @quality_factor2[in] : JPEG compression quality factor for the secondary image (optional)
201      * @return: true if quality factors are configured successfully.
202      *          false, otherwise.
203      */
204     virtual bool SetQuality(unsigned int quality_factor, unsigned int quality_factor2 = 0) = 0;
205     /*
206      * SetQuality - Configure quantization tables for JPEG compression
207      * @qtable[in]  : The 128 element array of quantization tables that contributes to JPEG
208      *                compression. The first 64 elements are the quantization tables of the luma
209      *                component. The other 64 elements are the quantization table of the chroma
210      *                components. All the quantizers in the tables should be specified in the
211      *                zig-zag scan order.
212      * @return: true if the given quantization tables are configured successfully.
213      *          false, otherwise.
214      */
SetQuality(const unsigned char __unused qtable[])215     virtual bool SetQuality(const unsigned char __unused qtable[]) { return false; };
216     /*
217      * SetImageBuffer - Configure the uncompressed primary image buffers (userptr)
218      * @buffers[in]     : addresses of the buffers
219      * @len_buffers[in] : sizes of the buffers
220      * @num_buffers[in] : the number of elements of @buffers and @len_buffers
221      * @return          : true if buffer configuration is successful.
222      *                    false, otherwise.
223      */
224     virtual bool SetImageBuffer(char *buffers[], size_t len_buffers[], unsigned int num_buffers) = 0;
225     /*
226      * SetImageBuffer - Configure the uncompressed primary image buffers (dmabuf)
227      * @buffers[in]     : file descriptors of the buffers exported by dma-buf
228      * @len_buffers[in] : sizes of the buffers
229      * @num_buffers[in] : the number of elements of @buffers and @len_buffers
230      * @return          : true if buffer configuration is successful.
231      *                    false, otherwise.
232      */
233     virtual bool SetImageBuffer(int buffers[], size_t len_buffers[], unsigned int num_buffers) = 0;
234     /*
235      * SetImageBuffer2 - Configure the uncompressed secondary image buffers (userptr)
236      * @buffers[in]     : addresses of the buffers
237      * @len_buffers[in] : sizes of the buffers
238      * @num_buffers[in] : the number of elements of @buffers and @len_buffers
239      * @return          : true if buffer configuration is successful.
240      *                    false, otherwise.
241      */
SetImageBuffer2(char __unused * buffers[],size_t __unused len_buffers[],unsigned int __unused num_buffers)242     virtual bool SetImageBuffer2(char __unused *buffers[], size_t __unused len_buffers[], unsigned int __unused num_buffers) { return false; }
243     /*
244      * SetImageBuffer2 - Configure the uncompressed secondary image buffers (dmabuf)
245      * @buffers[in]     : file descriptors of the buffers exported by dma-buf
246      * @len_buffers[in] : sizes of the buffers
247      * @num_buffers[in] : the number of elements of @buffers and @len_buffers
248      * @return          : true if buffer configuration is successful.
249      *                    false, otherwise.
250      */
SetImageBuffer2(int __unused buffers[],size_t __unused len_buffers[],unsigned int __unused num_buffers)251     virtual bool SetImageBuffer2(int __unused buffers[], size_t __unused len_buffers[], unsigned int __unused num_buffers) { return false; }
252     /*
253      * SetJpegBuffer - Configure the buffer of JPEG stream of the primary image (userptr)
254      * @buffer [in]     : The address of the buffer
255      * @len_buffer [in] : The size of @buffer
256      * @return          : true if buffer configuration is successful.
257      *                    false, otherwise.
258      */
259     virtual bool SetJpegBuffer(char *buffer, size_t len_buffer) = 0;
260     /*
261      * SetJpegBuffer - Configure the buffer of JPEG stream of the primary image (dmabuf)
262      * @buffer [in]     : The file descriptor of the buffer exported by dma-buf
263      * @offset          : The buffer offset that main JPEG image is updated
264      * @len_buffer [in] : The size of @buffer
265      * @return          : true if buffer configuration is successful.
266      *                    false, otherwise.
267      */
268     virtual bool SetJpegBuffer(int buffer, size_t len_buffer, int offset = 0) = 0;
269     /*
270      * SetJpegBuffer2 - Configure the buffer of JPEG stream of the secondary image (userptr)
271      * @buffer [in]     : The address of the buffer
272      * @len_buffer [in] : The size of @buffer
273      * @return          : true if buffer configuration is successful.
274      *                    false, otherwise.
275      * The secondary image configuration is ignored if the secondary image size
276      * is not configured with SetImageSize().
277      */
SetJpegBuffer2(char __unused * buffer,size_t __unused len_buffer)278     virtual bool SetJpegBuffer2(char __unused *buffer, size_t __unused len_buffer) { return false; }
279     /*
280      * SetJpegBuffer2 - Configure the buffer of JPEG stream of the secondary image (dmabuf)
281      * @buffer [in]     : The file descriptor of the buffer exported by dma-buf
282      * @len_buffer [in] : The size of @buffer
283      * @return          : true if buffer configuration is successful.
284      *                    false, otherwise.
285      * The secondary image configuration is ignored if the secondary image size
286      * is not configured with SetImageSize().
287      */
SetJpegBuffer2(int __unused buffer,size_t __unused len_buffer)288     virtual bool SetJpegBuffer2(int __unused buffer, size_t __unused len_buffer) { return false; }
289     /*
290      * Compress - Compress the given image
291      * secondary_stream_size[out] : The size of secondary JPEG stream
292      * block_mode[in]             : If @block_mode is true this function does not return
293      *                              until the compression finishes or error occurrs.
294      *                              If a derived function does not support for non-block mode,
295      *                              errur is returned.
296      * @return : The size of the compressed JPEG stream
297      *           (the offset of EOI from SOI plus sizeof(EOI))
298      *           Zero If @block_mode is false and no error is occurred.
299      *           Negative value on error.
300      */
301     virtual ssize_t Compress(size_t *secondary_stream_size = NULL, bool block_mode = true) = 0;
302     /*
303      * WaitForCompression - Wait for the compression finishes
304      * secondary_stream_size[out] : The size of secondary JPEG stream
305      * @return : The size of the compressed JPEG stream
306      *           (the offset of EOI from SOI plus sizeof(EOI))
307      *           Negative value on error.
308      *
309      * This function waits until the HWJPEG finishes JPEG compression if the second parameter
310      * to Compress() is false. If the parameter is true, WaitForCompression() immeidately
311      * returns and the returned size will be the stream sizes obtained by the last call to
312      * Compress().
313      */
314     virtual ssize_t WaitForCompression(size_t __unused *secondary_stream_size = NULL) { return GetStreamSize(secondary_stream_size); }
315     /*
316      * GetImageBuffers - Retrieve the configured uncompressed image buffer information (dmabuf)
317      * @buffers[out]: The file descriptors of the buffers exported by dma-buf
318      * @len_buffers[out]: The size of each buffers in @buffers
319      * @num_buffers[in]: The number of elements in @buffers and @len_buffers array
320      * return: true if retrieving the buffer information is successful.
321      *         false if no buffer is configured or the configured buffer is userptr type.
322      * DEPREDCATED. DO NOT USE THIS FUNCTION.
323      * This function is just provided to support the legacy ExynosJpegEncoder API.
324      */
GetImageBuffers(int __unused buffers[],size_t __unused len_buffers[],unsigned int __unused num_buffers)325     virtual bool GetImageBuffers(int __unused buffers[], size_t __unused len_buffers[], unsigned int __unused num_buffers) { return false; }
326     /*
327      * GetImageBuffers - Retrieve the configured uncompressed image buffer information (userptr)
328      * @buffers[out]: The addresses of the buffers
329      * @len_buffers[out]: The size of each buffers in @buffers
330      * @num_buffers[in]: The number of elements in @buffers and @len_buffers array
331      * return: true if retrieving the buffer information is successful.
332      *         false if no buffer is configured or the configured buffer is dmabuf type.
333      * DEPREDCATED. DO NOT USE THIS FUNCTION.
334      * This function is just provided to support the legacy ExynosJpegEncoder API.
335      */
GetImageBuffers(char __unused * buffers[],size_t __unused len_buffers[],unsigned int __unused num_buffers)336     virtual bool GetImageBuffers(char __unused *buffers[], size_t __unused len_buffers[], unsigned int __unused num_buffers) { return false; }
337     /*
338      * GetJpegBuffers - Retrieve the configured JPEG stream image buffer information (dmabuf)
339      * @buffers[out]: The file descriptor of the buffer exported by dma-buf
340      * @len_buffers[out]: The size of @buffer
341      * return: true if retrieving the buffer information is successful.
342      *         false if no buffer is configured or the configured buffer is userptr type.
343      * DEPREDCATED. DO NOT USE THIS FUNCTION.
344      * This function is just provided to support the legacy ExynosJpegEncoder API.
345      */
GetJpegBuffer(int __unused * buffers,size_t __unused * len_buffer)346     virtual bool GetJpegBuffer(int __unused *buffers, size_t __unused *len_buffer) { return false; }
347     /*
348      * GetJpegBuffers - Retrieve the configured JPEG stream buffer information (userptr)
349      * @buffers[out]: The address of the buffer
350      * @len_buffers[out]: The size of @buffers
351      * return: true if retrieving the buffer information is successful.
352      *         false if no buffer is configured or the configured buffer is dmabuf type.
353      * DEPREDCATED. DO NOT USE THIS FUNCTION.
354      * This function is just provided to support the legacy ExynosJpegEncoder API.
355      */
GetJpegBuffer(char __unused ** buffers,size_t __unused * len_buffer)356     virtual bool GetJpegBuffer(char __unused **buffers, size_t __unused *len_buffer) { return false; }
357     /*
358      * Release - release the buffers acquired by CHWJpegCompressor
359      */
Release()360     virtual void Release() { }
361 };
362 
363 /*
364  * CHWJpegDecompressor - The abstract class of HW JPEG accelerator for decompression
365  *
366  * This class is *not* thread-safe. If an instance of this class is handled by
367  * multiple threads, the users of the instance should care about the thread
368  * synchronization.
369  *
370  * CHWJpegDecompressor supports for downscaling during decompression by 1/2, 1/4 and
371  * 1/8 if HWJPEG supports. The users should test if the HWJPEG supports for downscaling
372  * before configuring smaller output image size.
373  * The users also test if the HWJPEG (driver) requires the address SOI or SOS. If it
374  * needs SOI, there is no need to feed the driver DHT and DQT. If it needs SOS, DHT
375  * DQT should be informed to the driver because it is unable to find DHT and DQT
376  * from SOS.
377  *
378  * V4L2_CAP_EXYNOS_JPEG_DOWNSCALING is set if HWJPEG supports for downscaling.
379  * V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_FROM_SOS is set if HWJPEG driver needs the
380  * address of SOS and the users to specify DHT and DQT to the driver.
381  */
382 class CHWJpegDecompressor : public CHWJpegBase {
383 public:
CHWJpegDecompressor(const char * path)384     CHWJpegDecompressor(const char *path) : CHWJpegBase(path) { }
~CHWJpegDecompressor()385     virtual ~CHWJpegDecompressor() { }
386     /*
387      * SetImageFormat - Configure decompressed image pixel format
388      * @v4l2_fmt[in] : Image pixel format defined in <linux/videodev2.h>
389      * @width[in]      : Width of the decompressed image in the number of pixels
390      * @height[in]     : Height of the decompressed image in the number of pixels
391      * @return : true if configuration of image pixel format is successful.
392      *           false, otherwise.
393      *
394      * @width and @height can be smaller than the compressed image size specified
395      * by SetStreamPixelSize() if downscaling during decompression is supported.
396      * The subclasses should test if V4L2_CAP_EXYNOS_JPEG_DOWNSCALING is set
397      * in the device capabilities. Even though downscaling is supported by HWJPEG,
398      * it has strict limitation that the downscaling factor should be one of
399      * 1, 2, 4 and 8. If the specified decompressed image size is not one of
400      * the compressed image size divided by 1, 2, 4 or 8, decompression should fail.
401      */
402     virtual bool SetImageFormat(unsigned int v4l2_fmt, unsigned int width, unsigned int height) = 0;
403 
404     /*
405      * SetImageBuffer - Configure the decompressed image buffer (userptr)
406      * @buffer[in]     : address of the buffer
407      * @len_buffer[in] : size of the buffer
408      * @return          : true if buffer configuration is successful.
409      *                    false, otherwise.
410      */
411     virtual bool SetImageBuffer(char *buffer, size_t len_buffer) = 0;
412 
413     /*
414      * SetImageBuffer - Configure the decompressed image buffer (dmabuf)
415      * @buffer[in]     : file descriptor of the buffer exported by dma-buf
416      * @len_buffer[in] : size of the buffer
417      * @return          : true if buffer configuration is successful.
418      *                    false, otherwise.
419      */
420     virtual bool SetImageBuffer(int buffer, size_t len_buffer) = 0;
421 
422     /*
423      * SetStreamPixelSize - Configure the width and the height of the compressed stream
424      * @width[in] : The number of horizontal pixels of the compressed image
425      * @height[in] : The number of vertical pixels of the compressed image
426      */
SetStreamPixelSize(unsigned int __unused width,unsigned int __unused height)427     virtual bool SetStreamPixelSize(unsigned int __unused width, unsigned int __unused height) { return true; }
428 
429     /*
430      * SetChromaSampFactor - Configure the chroma subsampling factor for JPEG stream
431      * @horizontal[in] : horizontal chroma subsampling factor
432      * @vertical[in]   : vertical chroma subsampling factor
433      * @return: true if chroma subsamping factors are configured successfully,
434      *          false if the factors are invalid.
435      *
436      * If V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_FROM_SOS is specified in the device
437      * capabilities, it is needed to configure chroma subsampling fractors because
438      * Neither of HWJPEG nor its driver is able to find the chroma subsampling factors
439      * of the compressed stream because it is specified in SOF and SOF is written
440      * ahead of SOS in the JPEG stream.
441      * If it is required to specify chroma subsampling factors separately, you should
442      * override SetChromaSampFactor().
443      */
SetChromaSampFactor(unsigned int __unused horizontal,unsigned int __unused vertical)444     virtual bool SetChromaSampFactor(unsigned int __unused horizontal, unsigned int __unused vertical) { return true; }
445 
446     /*
447      * SetDQT - Configure the address of DQT
448      * @dqt[in] : The address of DQT in the JPEG stream
449      * @return: true if the specified DQT has no problem. false if DQT does not exist
450      *          in @dqt or the tables in @dqt are incomplete.
451      *
452      * If V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_FROM_SOS is specified in the device
453      * capabilities, the HWJPEG needs DQT separately. Therefore every subcalss
454      * will need to override SetDQT().
455      */
SetDQT(const char __unused * dqt)456     virtual bool SetDQT(const char __unused *dqt) { return true; }
457 
458     /*
459      * SetDHT - Configure the address of DHT
460      * @dht[in] : The address of DHT in the JPEG stream
461      * @return: true if the specified DHT has no problem. false if DHT does not exist
462      *          in @dht or the tables in @dqt are incomplete.
463      *
464      * If V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_FROM_SOS is specified in the device
465      * capabilities, the HWJPEG needs DHT separately. Therefore every subcalss
466      * will need to override SetDHT().
467      */
SetDHT(const char __unused * dht)468     virtual bool SetDHT(const char __unused *dht) { return true; }
469 
470     /*
471      * Decompress - Decompress the given JPEG stream
472      * @buffer[in] : The buffer of JPEG stream.
473      * @len[in] : The length of the JPEG stream. It includes EOI marker.
474      * @return : true if the decompression succeeded. false, otherwise.
475      *
476      * If V4L2_CAP_EXYNOS_JPEG_DECOMPRESSION_FROM_SOS is set in the device capability
477      * SOS marker should be at the start of @buffer. Otherwise, SOI marker should be
478      * at the start. If @buffer is start with SOS marker, DHT, DQT and chroma
479      * subsampling factors should be separately configured with SetDHT(), SetDQT() and
480      * SetChromaSampFactor(), respectively.
481      */
482     virtual bool Decompress(const char *buffer, size_t len) = 0;
483 };
484 
485 class CHWJpegFlagManager {
486     unsigned int m_uiHWConfigFlags;
487 public:
CHWJpegFlagManager()488     CHWJpegFlagManager() : m_uiHWConfigFlags(0) { }
SetFlag(unsigned int flag)489     void SetFlag(unsigned int flag) { m_uiHWConfigFlags |= flag; }
ClearFlag(unsigned int flag)490     void ClearFlag(unsigned int flag) { m_uiHWConfigFlags &= ~flag; }
TestFlag(unsigned int flag)491     bool TestFlag(unsigned int flag) { return (m_uiHWConfigFlags & flag) == flag; }
TestFlagEither(unsigned int flag)492     bool TestFlagEither(unsigned int flag) { return !!(m_uiHWConfigFlags & flag); }
GetFlags()493     unsigned int GetFlags() { return m_uiHWConfigFlags; }
494 };
495 /*
496 class CHWJpegM2M1SHOTCompressor: public CHWJpegCompressor {
497 };
498 */
499 
500 #define TO_SEC_IMG_SIZE(val)    (((val) >> 16) & 0xFFFF)
501 
502 class CHWJpegV4L2Compressor : public CHWJpegCompressor, private CHWJpegFlagManager {
503     enum {
504         HWJPEG_CTRL_CHROMFACTOR = 0,
505         HWJPEG_CTRL_QFACTOR,
506         HWJPEG_CTRL_QFACTOR2,
507         HWJPEG_CTRL_HWFC,
508         HWJPEG_CTRL_NUM,
509     };
510 
511     enum  {
512         HWJPEG_FLAG_PIX_FMT     = 0x1, // Set if unapplied image format exists
513 
514         HWJPEG_FLAG_QBUF_OUT    = 0x100, // Set if the image buffer is queued
515         HWJPEG_FLAG_QBUF_CAP    = 0x200, // Set if the JPEG stream buffer is queued
516         HWJPEG_FLAG_REQBUFS     = 0x400,
517         HWJPEG_FLAG_STREAMING   = 0x800,
518 
519         HWJPEG_FLAG_SRC_BUFFER  = 0x10000, // Set if SetImageBuffer() is invoked successfully
520         HWJPEG_FLAG_SRC_BUFFER2 = 0x20000, // Set if SetImageBuffer2() is invoked successfully
521         HWJPEG_FLAG_DST_BUFFER  = 0x40000, // Set if SetJpegBuffer() is invoked successfully
522         HWJPEG_FLAG_DST_BUFFER2 = 0x80000, // Set if SetJpegBuffer2() is invoked successfully
523     };
524 
525     struct hwjpeg_v4l2_controls {
526         __u32 id;
527         __s32 value;
528     } m_v4l2Controls[HWJPEG_CTRL_NUM];
529 
530     unsigned int m_uiControlsToSet;
531     // H/W delay of the last compressoin in usec.
532     // Only valid after Compression() successes.
533     unsigned int m_uiHWDelay;
534 
535     v4l2_format m_v4l2Format; // v4l2 format for the source image
536     v4l2_buffer m_v4l2SrcBuffer; // v4l2 source buffer
537     v4l2_plane m_v4l2SrcPlanes[6];
538     v4l2_buffer m_v4l2DstBuffer;
539     v4l2_plane m_v4l2DstPlanes[2];
540 
541     bool m_bEnableHWFC;
542 
IsB2BCompression()543     bool IsB2BCompression() {
544         return (TO_SEC_IMG_SIZE(m_v4l2Format.fmt.pix_mp.width) +
545                     TO_SEC_IMG_SIZE(m_v4l2Format.fmt.pix_mp.height)) != 0;
546     }
547 
548     // V4L2 Helpers
549     bool TryFormat();
550     bool SetFormat();
551     bool UpdateControls();
552     bool ReqBufs(unsigned int count = 1);
553     bool StreamOn();
554     bool StreamOff();
555     bool QBuf();
556     ssize_t DQBuf(size_t *secondary_stream_size);
557     bool StopStreaming();
558 public:
559     CHWJpegV4L2Compressor();
560     virtual ~CHWJpegV4L2Compressor();
561 
GetHWDelay()562     unsigned int GetHWDelay() { return m_uiHWDelay; }
563 
564     // SetChromaSampFactor can be called during streaming
565     virtual bool SetChromaSampFactor(unsigned int horizontal,
566                                      unsigned int vertical);
567     virtual bool SetQuality(unsigned int quality_factor,
568                             unsigned int quality_factor2 = 0);
569     virtual bool SetQuality(const unsigned char qtable[]);
570 
571     virtual bool SetImageFormat(unsigned int v4l2_fmt, unsigned int width, unsigned int height,
572                               unsigned int sec_width = 0, unsigned sec_height = 0);
573     virtual bool GetImageBufferSizes(size_t buf_sizes[], unsigned int *num_bufffers);
574     virtual bool SetImageBuffer(char *buffers[], size_t len_buffers[], unsigned int num_buffers);
575     virtual bool SetImageBuffer(int buffers[], size_t len_buffers[], unsigned int num_buffers);
576     virtual bool SetImageBuffer2(char *buffers[], size_t len_buffers[], unsigned int num_buffers);
577     virtual bool SetImageBuffer2(int buffers[], size_t len_buffers[], unsigned int num_buffers);
578     virtual bool SetJpegBuffer(char *buffer, size_t len_buffer);
579     virtual bool SetJpegBuffer(int buffer, size_t len_buffer, int offset = 0);
580     virtual bool SetJpegBuffer2(char *buffer, size_t len_buffer);
581     virtual bool SetJpegBuffer2(int buffer, size_t len_buffer);
582     virtual ssize_t Compress(size_t *secondary_stream_size = NULL, bool bock_mode = true);
583     virtual bool GetImageBuffers(int buffers[], size_t len_buffers[], unsigned int num_buffers);
584     virtual bool GetImageBuffers(char *buffers[], size_t len_buffers[], unsigned int num_buffers);
585     virtual bool GetJpegBuffer(char **buffer, size_t *len_buffer);
586     virtual bool GetJpegBuffer(int *buffer, size_t *len_buffer);
587     virtual ssize_t WaitForCompression(size_t *secondary_stream_size = NULL);
588     virtual void Release();
589 };
590 
591 class CHWJpegV4L2Decompressor : public CHWJpegDecompressor, private CHWJpegFlagManager {
592     enum  {
593         HWJPEG_FLAG_OUTPUT_READY  = 0x10, /* the output stream is ready */
594         HWJPEG_FLAG_CAPTURE_READY = 0x20, /* the capture stream is ready */
595     };
596 
597     unsigned int m_uiHWDelay;
598 
599     v4l2_format m_v4l2Format;
600     v4l2_buffer m_v4l2DstBuffer; /* multi-planar foramt is not supported */
601 
602     bool PrepareCapture();
603     void CancelCapture();
604 
605     bool PrepareStream();
606     void CancelStream();
607     bool QBufAndWait(const char *buffer, size_t len);
608 public:
609     CHWJpegV4L2Decompressor();
610     virtual ~CHWJpegV4L2Decompressor();
611     virtual bool SetImageFormat(unsigned int v4l2_fmt, unsigned int width, unsigned int height);
612     virtual bool SetImageBuffer(char *buffer, size_t len_buffer);
613     virtual bool SetImageBuffer(int buffer, size_t len_buffer);
614     virtual bool Decompress(const char *buffer, size_t len);
615 
GetHWDelay()616     unsigned int GetHWDelay() { return m_uiHWDelay; }
617 };
618 #endif /* __EXYNOS_HWJPEG_H__ */
619