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