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 <functional>
20 
21 #include <linux/videodev2.h>
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, size_t dstLen);
39     bool RunStream(char *srcBuf[SCALER_MAX_PLANES], int srcLen[SCALER_MAX_PLANES], int dstBuf, size_t dstLen);
40 
available()41     bool available() { return mDevice.mFd >= 0; }
42 private:
43     struct Device {
44         int mFd;
45 
46         Device();
47         ~Device();
48         bool requestBuffers(unsigned int buftype, unsigned int memtype, unsigned int count);
49         bool setFormat(unsigned int buftype, unsigned int format, unsigned int width, unsigned int height, unsigned int planelen[SCALER_MAX_PLANES]);
50         bool streamOn(unsigned int buftype);
51         bool streamOff(unsigned int buftype);
52         bool queueBuffer(unsigned int buftype, std::function<void(v4l2_buffer &)> bufferFiller);
53         bool queueBuffer(unsigned int buftype, int buf[SCALER_MAX_PLANES], unsigned int len[SCALER_MAX_PLANES]);
54         bool queueBuffer(unsigned int buftype, char *buf[SCALER_MAX_PLANES], unsigned int len[SCALER_MAX_PLANES]);
55         bool queueBuffer(unsigned int buftype, int buf, unsigned int len[SCALER_MAX_PLANES]);
56         bool dequeueBuffer(unsigned int buftype, unsigned int memtype);
57     };
58 
59     struct Image {
60         Device &mDevice;
61         unsigned int width;
62         unsigned int height;
63         unsigned int format;
64         unsigned int memoryType = 0;
65         const unsigned int bufferType;
66         unsigned int planeLen[SCALER_MAX_PLANES];
67 
ImageImage68         Image(Device &dev, unsigned int w, unsigned int h, unsigned int f, unsigned int buftype)
69             : mDevice(dev), width(w), height(h), format(f), bufferType(buftype)
70         { }
71 
72         bool set(unsigned int width, unsigned int height, unsigned int format);
73         bool begin(unsigned int memtype);
74         bool cancelBuffer();
75 
76         template <class tBuf>
queueBufferImage77         bool queueBuffer(tBuf buf) { return mDevice.queueBuffer(bufferType, buf, planeLen); }
dequeueBufferImage78         bool dequeueBuffer() { return mDevice.dequeueBuffer(bufferType, memoryType); }
79 
sameImage80         bool same(unsigned int w, unsigned int h, unsigned int f) { return width == w && height == h && format == f; }
81     };
82 
83     template<class T>
queue(T srcBuf[SCALER_MAX_PLANES],int dstBuf)84     bool queue(T srcBuf[SCALER_MAX_PLANES], int dstBuf) {
85         if (!mSrcImage.queueBuffer(srcBuf))
86             return false;
87 
88         if (!mDstImage.queueBuffer(dstBuf)) {
89             mSrcImage.cancelBuffer();
90             return false;
91         }
92 
93         if (!mSrcImage.dequeueBuffer() || !mDstImage.dequeueBuffer()) {
94             mSrcImage.cancelBuffer();
95             mDstImage.cancelBuffer();
96             return false;
97         }
98 
99         return true;
100     }
101 
102     Device mDevice;
103     Image mSrcImage{mDevice, 0, 0, V4L2_PIX_FMT_YUYV, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE};
104     Image mDstImage{mDevice, 0, 0, V4L2_PIX_FMT_YUYV, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE};
105 };
106 
107 #endif //__HARDWARE_EXYNOS_LIBSCALERFORJPEG_H__
108