1 /*
2 * Copyright (c) 2019 Rockchip Corporation
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 */
17
18
19 #include "NrStatsStream.h"
20 #include "rkispp-config.h"
21 #include "CamHwIsp20.h"
22 namespace RkCam {
23
Nr_imag_buf_process(void * pUserContext,XCamVideoBuffer * pVideoBuffer)24 static void Nr_imag_buf_process
25 (
26 void* pUserContext,
27 XCamVideoBuffer* pVideoBuffer
28 )
29 {
30 NrStatsStream* nrStreamProc = (NrStatsStream*)pUserContext;
31 nrStreamProc->queue_NRImg_fd(pVideoBuffer->get_fd(pVideoBuffer), pVideoBuffer->frame_id);
32 }
33
NrStatsStream(SmartPtr<V4l2Device> dev,int type)34 NrStatsStream::NrStatsStream (SmartPtr<V4l2Device> dev, int type)
35 : RKStream(dev, type)
36 , _fd_init_flag(true)
37 , _NrImage(nullptr)
38 {
39 setPollCallback (this);
40 }
41
~NrStatsStream()42 NrStatsStream::~NrStatsStream()
43 {
44 }
45
46 void
start()47 NrStatsStream::start()
48 {
49 RKStream::start();
50 }
51
52 void
stop()53 NrStatsStream::stop()
54 {
55 RKStream::stopThreadOnly();
56 deinit_nrbuf_fd();
57 _list_mutex.lock();
58 _NrImg_ready_map.clear();
59 _list_mutex.unlock();
60 RKStream::stopDeviceOnly();
61 }
62
set_device(CamHwIsp20 * camHw,SmartPtr<V4l2SubDevice> dev)63 void NrStatsStream::set_device(CamHwIsp20* camHw, SmartPtr<V4l2SubDevice> dev)
64 {
65 _camHw = camHw;
66 _ispp_dev = dev;
67 }
68
69 SmartPtr<VideoBuffer>
new_video_buffer(SmartPtr<V4l2Buffer> buf,SmartPtr<V4l2Device> dev)70 NrStatsStream::new_video_buffer(SmartPtr<V4l2Buffer> buf,
71 SmartPtr<V4l2Device> dev)
72 {
73 if (_fd_init_flag) {
74 init_nrbuf_fd();
75 _fd_init_flag = false;
76
77 struct v4l2_subdev_format fmt;
78 memset(&fmt, 0, sizeof(fmt));
79 fmt.pad = 0;
80 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
81 XCamReturn ret = _ispp_dev->getFormat(fmt);
82 if (ret) {
83 LOGE("get ispp_dev fmt failed !\n");
84 }
85 _ispp_fmt = fmt;
86 LOGD("ispp fmt info: fmt 0x%x, %dx%d !",
87 fmt.format.code, fmt.format.width, fmt.format.height);
88
89 //struct v4l2_format format;
90 //memset(&format, 0, sizeof(format));
91 //ret = _dev->get_format(format);
92 //if (ret) {
93 // LOGE("get ispp_dev get_format failed !\n");
94 //} else {
95 // LOGE("nr fmt info: fmt 0x%x, %dx%d !",
96 // format.fmt.pix.pixelformat, format.fmt.pix.width, format.fmt.pix.height);
97 //}
98 }
99 SmartPtr<V4l2BufferProxy> nrstats = new V4l2BufferProxy (buf, dev);
100 nrstats->_buf_type = _dev_type;
101
102 return nrstats;
103 }
104
105 XCamReturn
poll_buffer_ready(SmartPtr<VideoBuffer> & buf)106 NrStatsStream::poll_buffer_ready (SmartPtr<VideoBuffer> &buf)
107 {
108 if (_camHw->mHwResLintener) {
109 _camHw->mHwResLintener->hwResCb(buf);
110 //NR image
111 SmartPtr<V4l2BufferProxy> nrstats = buf.dynamic_cast_ptr<V4l2BufferProxy>();
112 struct rkispp_stats_nrbuf *stats;
113 stats = (struct rkispp_stats_nrbuf *)(nrstats->get_v4l2_userptr());
114 struct VideoBufferInfo vbufInfo;
115 vbufInfo.init(V4L2_PIX_FMT_NV12, _ispp_fmt.format.width, _ispp_fmt.format.height,
116 _ispp_fmt.format.width, _ispp_fmt.format.height, stats->image.size);
117 SmartPtr<VideoBuffer> nrImage = new SubVideoBuffer(
118 _buf_num, stats->image.index, get_NRimg_fd_by_index(stats->image.index), vbufInfo);
119 nrImage->set_sequence(stats->frame_id);
120 nrImage->_buf_type = ISP_NR_IMG;
121 _camHw->mHwResLintener->hwResCb(nrImage);
122 }
123
124 return XCAM_RETURN_NO_ERROR;
125 }
126
init_nrbuf_fd()127 bool NrStatsStream::init_nrbuf_fd()
128 {
129 struct rkispp_buf_idxfd isppbuf_fd;
130 int res = -1;
131
132 memset(&isppbuf_fd, 0, sizeof(isppbuf_fd));
133 res = _ispp_dev->io_control(RKISPP_CMD_GET_NRBUF_FD , &isppbuf_fd);
134 if (res)
135 return false;
136 LOGD("%s: buf_num=%d",__FUNCTION__, isppbuf_fd.buf_num);
137 _buf_num = isppbuf_fd.buf_num;
138 for (uint32_t i=0; i<isppbuf_fd.buf_num; i++) {
139 if (isppbuf_fd.dmafd[i] < 0) {
140 LOGE("nrbuf_fd[%u]:%d is illegal!",isppbuf_fd.index[i],isppbuf_fd.dmafd[i]);
141 LOGE("\n*** ASSERT: In File %s,line %d ***\n", __FILE__, __LINE__);
142 assert(0);
143 }
144 _idx_array[i] = isppbuf_fd.index[i];
145 _fd_array[i] = isppbuf_fd.dmafd[i];
146 LOGD("nrbuf_fd[%u]:%d",isppbuf_fd.index[i],isppbuf_fd.dmafd[i]);
147 }
148
149 return true;
150 }
151
get_NRimg_fd_by_index(int index)152 int NrStatsStream::get_NRimg_fd_by_index(int index)
153 {
154 int ret = -1;
155
156 if (index < 0)
157 return ret;
158 for (int i=0; i<_buf_num; i++) {
159 if (_idx_array[i] == index)
160 return _fd_array[i];
161 }
162 return ret;
163 }
164
deinit_nrbuf_fd()165 bool NrStatsStream::deinit_nrbuf_fd()
166 {
167 for (int i=0; i<_buf_num; i++) {
168 ::close(_fd_array[i]);
169 }
170 _buf_num = 0;
171 return true;
172 }
173
queue_NRImg_fd(int fd,uint32_t frameid)174 int NrStatsStream::queue_NRImg_fd(int fd, uint32_t frameid)
175 {
176 if (fd < 0)
177 return -1;
178 _list_mutex.lock();
179 _NrImg_ready_map[frameid] = fd;
180 _list_mutex.unlock();
181 return 0;
182 }
183
184
get_NRImg_fd(uint32_t frameid)185 int NrStatsStream::get_NRImg_fd(uint32_t frameid)
186 {
187 int fd = -1;
188 std::map<uint32_t, int>::iterator it;
189 _list_mutex.lock();
190 it = _NrImg_ready_map.find(frameid);
191 if (it == _NrImg_ready_map.end())
192 fd = -1;
193 else
194 fd = it->second;
195 _list_mutex.unlock();
196 return fd;
197 }
198
199 } //namspace RkCam
200