1 /*
2  * Copyright (C) 2019 Samsung Electronics Co.,LTD.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #ifndef __HARDWARE_EXYNOS_LIBSCALERFORJPEG_H__
17 #define __HARDWARE_EXYNOS_LIBSCALERFORJPEG_H__
18 
19 #include <linux/videodev2.h>
20 
21 #include <functional>
22 
23 #include "ThumbnailScaler.h"
24 
25 class LibScalerForJpeg : public ThumbnailScaler {
26 public:
LibScalerForJpeg()27     LibScalerForJpeg() {}
~LibScalerForJpeg()28     ~LibScalerForJpeg() {}
29 
SetSrcImage(unsigned int width,unsigned int height,unsigned int v4l2_format)30     bool SetSrcImage(unsigned int width, unsigned int height, unsigned int v4l2_format) {
31         return mSrcImage.set(width, height, v4l2_format);
32     }
33 
SetDstImage(unsigned int width,unsigned int height,unsigned int v4l2_format)34     bool SetDstImage(unsigned int width, unsigned int height, unsigned int v4l2_format) {
35         return mDstImage.set(width, height, v4l2_format);
36     }
37 
38     bool RunStream(int srcBuf[SCALER_MAX_PLANES], int srcLen[SCALER_MAX_PLANES], int dstBuf,
39                    size_t dstLen);
40     bool RunStream(char *srcBuf[SCALER_MAX_PLANES], int srcLen[SCALER_MAX_PLANES], int dstBuf,
41                    size_t dstLen);
42 
available()43     bool available() { return mDevice.mFd >= 0; }
44 
45 private:
46     struct Device {
47         int mFd;
48 
49         Device();
50         ~Device();
51         bool requestBuffers(unsigned int buftype, unsigned int memtype, unsigned int count);
52         bool setFormat(unsigned int buftype, unsigned int format, unsigned int width,
53                        unsigned int height, unsigned int planelen[SCALER_MAX_PLANES]);
54         bool streamOn(unsigned int buftype);
55         bool streamOff(unsigned int buftype);
56         bool queueBuffer(unsigned int buftype, std::function<void(v4l2_buffer &)> bufferFiller);
57         bool queueBuffer(unsigned int buftype, int buf[SCALER_MAX_PLANES],
58                          unsigned int len[SCALER_MAX_PLANES]);
59         bool queueBuffer(unsigned int buftype, char *buf[SCALER_MAX_PLANES],
60                          unsigned int len[SCALER_MAX_PLANES]);
61         bool queueBuffer(unsigned int buftype, int buf, unsigned int len[SCALER_MAX_PLANES]);
62         bool dequeueBuffer(unsigned int buftype, unsigned int memtype);
63     };
64 
65     struct Image {
66         Device &mDevice;
67         unsigned int width;
68         unsigned int height;
69         unsigned int format;
70         unsigned int memoryType = 0;
71         const unsigned int bufferType;
72         unsigned int planeLen[SCALER_MAX_PLANES];
73 
ImageImage74         Image(Device &dev, unsigned int w, unsigned int h, unsigned int f, unsigned int buftype)
75               : mDevice(dev), width(w), height(h), format(f), bufferType(buftype) {}
76 
77         bool set(unsigned int width, unsigned int height, unsigned int format);
78         bool begin(unsigned int memtype);
79         bool cancelBuffer();
80 
81         template <class tBuf>
queueBufferImage82         bool queueBuffer(tBuf buf) {
83             return mDevice.queueBuffer(bufferType, buf, planeLen);
84         }
dequeueBufferImage85         bool dequeueBuffer() { return mDevice.dequeueBuffer(bufferType, memoryType); }
86 
sameImage87         bool same(unsigned int w, unsigned int h, unsigned int f) {
88             return width == w && height == h && format == f;
89         }
90     };
91 
92     template <class T>
queue(T srcBuf[SCALER_MAX_PLANES],int dstBuf)93     bool queue(T srcBuf[SCALER_MAX_PLANES], int dstBuf) {
94         if (!mSrcImage.queueBuffer(srcBuf)) return false;
95 
96         if (!mDstImage.queueBuffer(dstBuf)) {
97             mSrcImage.cancelBuffer();
98             return false;
99         }
100 
101         if (!mSrcImage.dequeueBuffer() || !mDstImage.dequeueBuffer()) {
102             mSrcImage.cancelBuffer();
103             mDstImage.cancelBuffer();
104             return false;
105         }
106 
107         return true;
108     }
109 
110     Device mDevice;
111     Image mSrcImage{mDevice, 0, 0, V4L2_PIX_FMT_YUYV, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE};
112     Image mDstImage{mDevice, 0, 0, V4L2_PIX_FMT_YUYV, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE};
113 };
114 
115 #endif //__HARDWARE_EXYNOS_LIBSCALERFORJPEG_H__
116