blob: 0a84d110cb756efd00a404d7ad30ce650f826d97 [file] [log] [blame]
codeworkx62f02ba2012-05-20 12:00:36 +02001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 * Copyright@ Samsung Electronics Co. LTD
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//#define DEBUG_LIB_FIMC
19#define LOG_TAG "libgscaler"
20//#define USE_GSC_USERPTR
21#include <cutils/log.h>
22#include "../libhdmi/SecHdmi/SecGscaler.h"
23
24#ifdef USE_GSC_USERPTR
25#define V4L2_MEMORY_TYPE V4L2_MEMORY_USERPTR
26#else
27#define V4L2_MEMORY_TYPE V4L2_MEMORY_MMAP
28#endif
29
30struct yuv_fmt_list yuv_list[] = {
31 { "V4L2_PIX_FMT_NV12", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12, 12, 1 },
32 { "V4L2_PIX_FMT_NV12M", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12M, 12, 2 },
33 { "V4L2_PIX_FMT_NV12MT", "YUV420/2P/LSB_CBCR", V4L2_PIX_FMT_NV12MT, 12, 2 },
34 { "V4L2_PIX_FMT_NV21", "YUV420/2P/LSB_CRCB", V4L2_PIX_FMT_NV21, 12, 1 },
35 { "V4L2_PIX_FMT_NV21X", "YUV420/2P/MSB_CBCR", V4L2_PIX_FMT_NV21X, 12, 2 },
36 { "V4L2_PIX_FMT_NV12X", "YUV420/2P/MSB_CRCB", V4L2_PIX_FMT_NV12X, 12, 2 },
37 { "V4L2_PIX_FMT_YUV420", "YUV420/3P", V4L2_PIX_FMT_YUV420, 12, 3 },
38 { "V4L2_PIX_FMT_YUV420M", "YUV420/3P", V4L2_PIX_FMT_YUV420M, 12, 3 },
39 { "V4L2_PIX_FMT_YUYV", "YUV422/1P/YCBYCR", V4L2_PIX_FMT_YUYV, 16, 1 },
40 { "V4L2_PIX_FMT_YVYU", "YUV422/1P/YCRYCB", V4L2_PIX_FMT_YVYU, 16, 1 },
41 { "V4L2_PIX_FMT_UYVY", "YUV422/1P/CBYCRY", V4L2_PIX_FMT_UYVY, 16, 1 },
42 { "V4L2_PIX_FMT_VYUY", "YUV422/1P/CRYCBY", V4L2_PIX_FMT_VYUY, 16, 1 },
43 { "V4L2_PIX_FMT_UV12", "YUV422/2P/LSB_CBCR", V4L2_PIX_FMT_NV16, 16, 2 },
44 { "V4L2_PIX_FMT_UV21", "YUV422/2P/LSB_CRCB", V4L2_PIX_FMT_NV61, 16, 2 },
45 { "V4L2_PIX_FMT_UV12X", "YUV422/2P/MSB_CBCR", V4L2_PIX_FMT_NV16X, 16, 2 },
46 { "V4L2_PIX_FMT_UV21X", "YUV422/2P/MSB_CRCB", V4L2_PIX_FMT_NV61X, 16, 2 },
47 { "V4L2_PIX_FMT_YUV422P", "YUV422/3P", V4L2_PIX_FMT_YUV422P, 16, 3 },
48};
49
50void dump_pixfmt_mp(struct v4l2_pix_format_mplane *pix_mp)
51{
52 LOGI("w: %d", pix_mp->width);
53 LOGI("h: %d", pix_mp->height);
54 LOGI("color: %x", pix_mp->colorspace);
55
56 switch (pix_mp->pixelformat) {
57 case V4L2_PIX_FMT_YUYV:
58 LOGI ("YUYV");
59 break;
60 case V4L2_PIX_FMT_UYVY:
61 LOGI ("UYVY");
62 break;
63 case V4L2_PIX_FMT_RGB565:
64 LOGI ("RGB565");
65 break;
66 case V4L2_PIX_FMT_RGB565X:
67 LOGI ("RGB565X");
68 break;
69 default:
70 LOGI("not supported");
71 }
72}
73
74void dump_crop(struct v4l2_rect *rect)
75{
76 LOGI("crop l: %d", rect->left);
77 LOGI("crop t: %d", rect->top);
78 LOGI("crop w: %d", rect->width);
79 LOGI("crop h: %d", rect->height);
80}
81
82void gsc_v4l2_dump_state(int fd)
83{
84 struct v4l2_format format;
85 struct v4l2_crop crop;
86 struct v4l2_subdev_crop sCrop;
87
88 format.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
89 if (ioctl(fd, VIDIOC_G_FMT, &format) < 0)
90 return;
91
92 LOGI("dumping driver state:");
93 dump_pixfmt_mp(&format.fmt.pix_mp);
94
95 crop.type = format.type;
96 if (ioctl(fd, VIDIOC_G_CROP, &crop) < 0)
97 return;
98
99 LOGI("input image crop:");
100 dump_crop(&(crop.c));
101
102 sCrop.pad = GSC_SUBDEV_PAD_SOURCE;
103 sCrop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
104 if (ioctl(fd, VIDIOC_SUBDEV_G_CROP, &sCrop) < 0)
105 return;
106
107 LOGI("output image crop:");
108 dump_crop(&(sCrop.rect));
109
110}
111
112int gsc_v4l2_querycap(int fd, char *node)
113{
114#ifdef DEBUG_LIB_FIMC
115 LOGD("%s", __func__);
116#endif
117 struct v4l2_capability v4l2cap;
118
119 if (ioctl(fd, VIDIOC_QUERYCAP, &v4l2cap) < 0) {
120 LOGE("%s::VIDIOC_QUERYCAP failed", __func__);
121 return -1;
122 }
123
124 if (!(v4l2cap.capabilities & V4L2_CAP_STREAMING)) {
125 LOGE("%s::%s is not support streaming", __func__, node);
126 return -1;
127 }
128
129 if (!(v4l2cap.capabilities & V4L2_CAP_VIDEO_OUTPUT_MPLANE)) {
130 LOGE("%s::%s is not support video output mplane", __func__, node);
131 return -1;
132 }
133
134 return 0;
135}
136
137int gsc_v4l2_query_buf(int fd, SecBuffer *secBuf, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int buf_index, int num_plane)
138{
139#ifdef DEBUG_LIB_FIMC
140 LOGD("%s", __func__);
141#endif
142 struct v4l2_buffer buf;
143 struct v4l2_plane planes[MAX_PLANES_GSCALER];
144
145 memset(&buf, 0, sizeof(struct v4l2_buffer));
146
147 for (int i = 0; i < MAX_PLANES_GSCALER; i++)
148 memset(&planes[i], 0, sizeof(struct v4l2_plane));
149
150 if (MAX_BUFFERS_GSCALER <= buf_index || MAX_PLANES_GSCALER < num_plane) {
151 LOGE("%s::exceed MAX! : buf_index=%d, num_plane=%d", __func__, buf_index, num_plane);
152 return -1;
153 }
154
155 buf.type = type;
156 buf.memory = V4L2_MEMORY_MMAP;
157 buf.index = buf_index;
158 buf.length = num_plane;
159 buf.m.planes = planes;
160
161 if (ioctl(fd, VIDIOC_QUERYBUF, &buf) < 0) {
162 LOGE("%s::VIDIOC_QUERYBUF failed, plane_cnt=%d", __func__, buf.length);
163 return -1;
164 }
165
166 for (int i = 0; i < num_plane; i++) {
167 if ((secBuf->virt.extP[i] = (char *)mmap(0, buf.m.planes[i].length,
168 PROT_READ | PROT_WRITE, MAP_SHARED, fd, buf.m.planes[i].m.mem_offset)) < 0) {
169 LOGE("%s::mmap failed", __func__);
170 LOGE("%s::Offset = 0x%x", __func__, buf.m.planes[i].m.mem_offset);
171 LOGE("%s::Legnth = %d" , __func__, buf.m.planes[i].length);
172 LOGE("%s::vaddr[%d][%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]);
173 return -1;
174 }
175 secBuf->size.extS[i] = buf.m.planes[i].length;
176
177#ifdef DEBUG_LIB_FIMC
178 LOGD("%s::vaddr[bufindex=%d][planeindex=%d] = 0x%x", __func__, buf_index, i, (unsigned int)secBuf->virt.extP[i]);
179 LOGD("%s::Legnth = %d" , __func__, buf.m.planes[i].length);
180#endif
181 }
182
183 return 0;
184}
185
186int gsc_v4l2_req_buf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int num_bufs)
187{
188#ifdef DEBUG_LIB_FIMC
189 LOGD("%s", __func__);
190#endif
191 struct v4l2_requestbuffers reqbuf;
192
193 reqbuf.type = type;
194 reqbuf.memory = memory;
195 reqbuf.count = num_bufs;
196
197#ifdef DEBUG_LIB_FIMC
198 LOGI("%d buffers needed", reqbuf.count);
199#endif
200
201 if (ioctl(fd, VIDIOC_REQBUFS, &reqbuf) < 0) {
202 LOGE("%s::VIDIOC_REQBUFS failed, reqbuf.count=%d", __func__, reqbuf.count);
203 return -1;
204 }
205
206#ifdef DEBUG_LIB_FIMC
207 LOGI("%d buffers allocated", reqbuf.count);
208#endif
209
210 if (reqbuf.count < num_bufs) {
211 LOGE("%s::VIDIOC_REQBUFS failed ((reqbuf.count(%d) < num_bufs(%d))",
212 __func__, reqbuf.count, num_bufs);
213 return -1;
214 }
215
216 return 0;
217}
218
219int gsc_v4l2_s_ctrl(int fd, int id, int value)
220{
221#ifdef DEBUG_LIB_FIMC
222 LOGD("%s", __func__);
223#endif
224 struct v4l2_control vc;
225
226 vc.id = id;
227 vc.value = value;
228
229 if (ioctl(fd, VIDIOC_S_CTRL, &vc) < 0) {
230 LOGE("%s::VIDIOC_S_CTRL (id=%d,value=%d) failed", __func__, id, value);
231 return -1;
232 }
233
234 return 0;
235}
236
237int gsc_v4l2_set_fmt(int fd, enum v4l2_buf_type type, enum v4l2_field field, s5p_fimc_img_info *img_info)
238{
239#ifdef DEBUG_LIB_FIMC
240 LOGD("%s", __func__);
241#endif
242 struct v4l2_format fmt;
243 struct v4l2_crop crop;
244
245 fmt.type = type;
246#ifdef DEBUG_LIB_FIMC
247 LOGD("%s::fmt.type=%d", __func__, fmt.type);
248#endif
249 if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) {
250 LOGE("%s::VIDIOC_G_FMT failed", __func__);
251 return -1;
252 }
253
254 switch (fmt.type) {
255 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
256 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
257 fmt.fmt.pix.width = img_info->full_width;
258 fmt.fmt.pix.height = img_info->full_height;
259 fmt.fmt.pix.pixelformat = img_info->color_space;
260 fmt.fmt.pix.field = field;
261 break;
262 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
263 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
264 fmt.fmt.pix_mp.width = img_info->full_width;
265 fmt.fmt.pix_mp.height = img_info->full_height;
266 fmt.fmt.pix_mp.pixelformat = img_info->color_space;
267 fmt.fmt.pix_mp.field = field;
268 fmt.fmt.pix_mp.num_planes = img_info->planes;
269 break;
270 default:
271 LOGE("%s::invalid buffer type", __func__);
272 return -1;
273 break;
274 }
275
276#ifdef DEBUG_LIB_FIMC
277for (int i = 0; i < 3; i++) {
278 LOGD("%s::fmt.fmt.pix_mp. w=%d, h=%d, pixelformat=0x%08x, filed=%d, num_planes=%d",
279 __func__,
280 fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
281 fmt.fmt.pix_mp.pixelformat, fmt.fmt.pix_mp.field,
282 fmt.fmt.pix_mp.num_planes);
283}
284#endif
285
286 if (ioctl(fd, VIDIOC_S_FMT, &fmt) < 0) {
287 LOGE("%s::VIDIOC_S_FMT failed", __func__);
288 return -1;
289 }
290
291#ifdef DEBUG_LIB_FIMC
292for (int i = 0; i < 3; i++) {
293 LOGD("%s::pix_mp.pix_mp.plane_fmt[%d].sizeimage =0x%08x", __func__, i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
294 LOGD("%s::pix_mp.pix_mp.plane_fmt[%d].bytesperline=0x%08x", __func__, i, fmt.fmt.pix_mp.plane_fmt[i].bytesperline);
295}
296#endif
297
298 crop.type = type;
299 crop.c.left = img_info->start_x;
300 crop.c.top = img_info->start_y;
301 crop.c.width = img_info->width;
302 crop.c.height = img_info->height;
303
304 if (ioctl(fd, VIDIOC_S_CROP, &crop) < 0) {
305 LOGE("%s::VIDIOC_S_CROP (x=%d, y=%d, w=%d, h=%d) failed",
306 __func__,
307 img_info->start_x,
308 img_info->start_y,
309 img_info->width,
310 img_info->height);
311 return -1;
312 }
313
314#ifdef DEBUG_LIB_FIMC
315 LOGD("%s::pix_mp pixelformat=0x%08x", __func__, fmt.fmt.pix_mp.pixelformat);
316 LOGD("%s::pix_mp w=%d, h=%d, planes=%d", __func__, fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.num_planes);
317 LOGD("%s::crop x=%d, y=%d, w=%d, h=%d", __func__, crop.c.left, crop.c.top, crop.c.width, crop.c.height);
318#endif
319
320 return 0;
321}
322
323int gsc_v4l2_stream_on(int fd, enum v4l2_buf_type type)
324{
325#ifdef DEBUG_LIB_FIMC
326 LOGD("%s", __func__);
327#endif
328 if (ioctl(fd, VIDIOC_STREAMON, &type) < 0) {
329 LOGE("%s::VIDIOC_STREAMON failed", __func__);
330 return -1;
331 }
332
333 return 0;
334}
335
336int gsc_v4l2_queue(int fd, SecBuffer *secBuf, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int index, int num_plane)
337{
338#ifdef DEBUG_LIB_FIMC
339 LOGD("%s", __func__);
340 LOGD("%s::num_plane=%d", __func__, num_plane);
341#endif
342 struct v4l2_buffer buf;
343 struct v4l2_plane planes[MAX_PLANES_GSCALER];
344
345 memset(&buf, 0, sizeof(struct v4l2_buffer));
346
347 for (int i = 0; i < MAX_PLANES_GSCALER; i++)
348 memset(&planes[i], 0, sizeof(struct v4l2_plane));
349
350 buf.type = type;
351 buf.memory = memory;
352 buf.length = num_plane;
353 buf.index = index;
354 buf.m.planes = planes;
355
356 for (unsigned int i = 0; i < buf.length; i++) {
357 buf.m.planes[i].m.userptr = (unsigned long)secBuf->virt.extP[i];
358 buf.m.planes[i].length = secBuf->size.extS[i];
359 buf.m.planes[i].bytesused = buf.m.planes[i].length;
360#ifdef DEBUG_LIB_FIMC
361 LOGD("%s::buf.index=%d", __func__, buf.index);
362 LOGD("%s::buf.m.planes[%d].m.userptr=0x%08x", __func__, i, (unsigned int)buf.m.planes[i].m.userptr);
363 LOGD("%s::buf.m.planes[%d].length =0x%08x", __func__, i, buf.m.planes[i].length);
364 LOGD("%s::buf.m.planes[%d].bytesused=0x%08x", __func__, i, buf.m.planes[i].bytesused);
365#endif
366 }
367
368 if (ioctl(fd, VIDIOC_QBUF, &buf) < 0) {
369 LOGE("%s::VIDIOC_QBUF failed", __func__);
370 return -1;
371 }
372
373 return 0;
374}
375
376int gsc_v4l2_dequeue(int fd, enum v4l2_buf_type type, enum v4l2_memory memory, unsigned int *index, int num_plane)
377{
378#ifdef DEBUG_LIB_FIMC
379 LOGD("%s", __func__);
380#endif
381 struct v4l2_buffer buf;
382 struct v4l2_plane planes[MAX_PLANES_GSCALER];
383
384 memset(&buf, 0, sizeof(struct v4l2_buffer));
385
386 for (int i = 0; i < MAX_PLANES_GSCALER; i++)
387 memset(&planes[i], 0, sizeof(struct v4l2_plane));
388
389
390 buf.type = type;
391 buf.memory = memory;
392 buf.length = num_plane;
393 buf.m.planes = planes;
394
395 if (ioctl(fd, VIDIOC_DQBUF, &buf) < 0) {
396 LOGE("%s::VIDIOC_DQBUF failed", __func__);
397 return -1;
398 }
399
400 *index = buf.index;
401
402#ifdef DEBUG_LIB_FIMC
403 LOGD("%s::buf.index=%d", __func__, buf.index);
404#endif
405
406 return 0;
407}
408
409int gsc_v4l2_stream_off(int fd, enum v4l2_buf_type type)
410{
411#ifdef DEBUG_LIB_FIMC
412 LOGD("%s", __func__);
413#endif
414 if (ioctl(fd, VIDIOC_STREAMOFF, &type) < 0) {
415 LOGE("%s::VIDIOC_STREAMOFF failed", __func__);
416 return -1;
417 }
418
419 return 0;
420}
421
422int gsc_v4l2_clr_buf(int fd, enum v4l2_buf_type type, enum v4l2_memory memory)
423{
424#ifdef DEBUG_LIB_FIMC
425 LOGD("%s", __func__);
426#endif
427 struct v4l2_requestbuffers req;
428
429 req.count = 0;
430 req.type = type;
431 req.memory = memory;
432
433 if (ioctl(fd, VIDIOC_REQBUFS, &req) < 0) {
434 LOGE("%s::VIDIOC_REQBUFS failed", __func__);
435 return -1;
436 }
437
438 return 0;
439}
440
441int gsc_subdev_set_fmt(int fd, unsigned int pad, enum v4l2_mbus_pixelcode code, s5p_fimc_img_info *img_info)
442{
443#ifdef DEBUG_LIB_FIMC
444 LOGD("%s", __func__);
445#endif
446 struct v4l2_subdev_format fmt;
447 struct v4l2_subdev_crop crop;
448
449 fmt.pad = pad;
450 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
451 fmt.format.width = img_info->full_width;
452 fmt.format.height = img_info->full_height;
453 fmt.format.code = code;
454
455 if (ioctl(fd, VIDIOC_SUBDEV_S_FMT, &fmt) < 0) {
456 LOGE("%s::VIDIOC_SUBDEV_S_FMT failed", __func__);
457 return -1;
458 }
459
460 crop.pad = pad;
461 crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
462 crop.rect.left = img_info->start_x;
463 crop.rect.top = img_info->start_y;
464 crop.rect.width = img_info->width;
465 crop.rect.height = img_info->height;
466
467#ifdef DEBUG_LIB_FIMC
468 LOGD("%s::pix_mp w=%d, h=%d", __func__, fmt.format.width, fmt.format.height);
469 LOGD("%s::crop x=%d, y=%d, w=%d, h=%d", __func__, crop.rect.left, crop.rect.top, crop.rect.width, crop.rect.height);
470#endif
471
472 if (ioctl(fd, VIDIOC_SUBDEV_S_CROP, &crop) < 0) {
473 LOGE("%s::VIDIOC_SUBDEV_S_CROP failed", __func__);
474 return -1;
475 }
476
477 return 0;
478}
479
480static inline int multipleOfN(int number, int N)
481{
482 int result = number;
483 switch (N) {
484 case 1:
485 case 2:
486 case 4:
487 case 8:
488 case 16:
489 case 32:
490 case 64:
491 case 128:
492 case 256:
493 result = (number - (number & (N-1)));
494 break;
495 default:
496 result = number - (number % N);
497 break;
498 }
499 return result;
500}
501
502SecGscaler::SecGscaler()
503: mFlagCreate(false)
504{
505}
506
507SecGscaler::~SecGscaler()
508{
509 if (mFlagCreate == true) {
510 LOGE("%s::this is not Destroyed fail", __func__);
511
512 if (destroy() == false)
513 LOGE("%s::destroy failed", __func__);
514 }
515}
516
517bool SecGscaler::create(enum DEV dev, enum MODE mode, unsigned int numOfBuf)
518{
519 create(dev, numOfBuf);
520 return true;
521}
522
523bool SecGscaler::create(enum DEV dev, unsigned int numOfBuf)
524{
525#ifdef DEBUG_LIB_FIMC
526 LOGD("%s", __func__);
527#endif
528 if (mFlagCreate == true) {
529 LOGE("%s::Already Created", __func__);
530 return true;
531 }
532
533 char node[20];
534 char subdevname[32];
535 char videodevname[32];
536
537 struct v4l2_capability v4l2cap;
538 struct media_entity_desc entity_desc;
539
540 mDev = dev;
541 mVideoNodeNum = dev;
542 mNumOfBuf = numOfBuf;
543
544 mVideodevFd = 0;
545 mMediadevFd = 0;
546 mSubdevFd = 0;
547
548 mSrcIndex = 0;
549 mRotVal = 0;
550 mFlagGlobalAlpha = false;
551 mGlobalAlpha = 0x0;
552 mFlagLocalAlpha = false;
553 mFlagColorKey = false;
554 mColorKey = 0x0;
555 mFlagSetSrcParam = false;
556 mFlagSetDstParam = false;
557 mFlagStreamOn = false;
558
559 memset(&mS5pFimc, 0, sizeof(s5p_fimc_t));
560
561 switch(mDev) {
562 case DEV_0:
563 mVideoNodeNum = 24;
564 mSubdevNodeNum = 4;
565 break;
566 case DEV_1:
567 mVideoNodeNum = 27;
568 mSubdevNodeNum = 5;
569 break;
570 case DEV_2:
571 mVideoNodeNum = 30;
572 mSubdevNodeNum = 6;
573 break;
574 case DEV_3:
575 mVideoNodeNum = 33;
576 mSubdevNodeNum = 3; // need to modify //carrotsm
577 break;
578 default:
579 LOGE("%s::invalid mDev(%d)", __func__, mDev);
580 goto err;
581 break;
582 }
583
584 sprintf(node, "%s%d", PFX_NODE_MEDIADEV, 0);
585 mMediadevFd = open(node, O_RDONLY);
586
587 if (mMediadevFd < 0) {
588 LOGE("%s::open(%s) failed : O_RDONLY", __func__, node);
589 goto err;
590 }
591
592 sprintf(subdevname, PFX_ENTITY_SUBDEV_GSC, mDev);
593 sprintf(videodevname, PFX_ENTITY_OUTPUTDEV_GSC, mDev);
594
595 for (__u32 id = 0; ; id = entity_desc.id) {
596 entity_desc.id = id | MEDIA_ENT_ID_FLAG_NEXT;
597
598 if (ioctl(mMediadevFd, MEDIA_IOC_ENUM_ENTITIES, &entity_desc) < 0) {
599 if (errno == EINVAL) {
600 LOGD("%s::MEDIA_IOC_ENUM_ENTITIES ended", __func__);
601 break;
602 }
603 LOGE("%s::MEDIA_IOC_ENUM_ENTITIES failed", __func__);
604 goto err;
605 }
606
607#ifdef DEBUG_LIB_FIMC
608 LOGD("%s::entity_desc.id=%d, .minor=%d .name=%s", __func__, entity_desc.id, entity_desc.v4l.minor, entity_desc.name);
609#endif
610
611 if (strncmp(entity_desc.name, subdevname, strlen(subdevname)) == 0)
612 mSubdevEntity = entity_desc.id;
613
614 if (strncmp(entity_desc.name, videodevname, strlen(videodevname)) == 0)
615 mVideodevEntity = entity_desc.id;
616 }
617
618 if (0 < mMediadevFd)
619 close(mMediadevFd);
620 mMediadevFd = -1;
621
622 sprintf(node, "%s%d", PFX_NODE_SUBDEV, mSubdevNodeNum);
623 mSubdevFd = open(node, O_RDWR);
624 if (mSubdevFd < 0) {
625 LOGE("%s::open(%s) failed", __func__, node);
626 goto err;
627 }
628
629 sprintf(node, "%s%d", PFX_NODE_VIDEODEV, mVideoNodeNum);
630 mVideodevFd = open(node, O_RDWR);
631 if (mVideodevFd < 0) {
632 LOGE("%s::open(%s) failed", __func__, node);
633 goto err;
634 }
635
636 /* check capability */
637 if (gsc_v4l2_querycap(mVideodevFd, node) < 0 ) {
638 LOGE("%s::tvout_std_v4l2_querycap failed", __func__);
639 goto err;
640 }
641
642 mFlagCreate = true;
643
644 return true;
645
646err :
647 if (0 < mVideodevFd)
648 close(mVideodevFd);
649
650 if (0 < mMediadevFd)
651 close(mMediadevFd);
652
653 if (0 < mSubdevFd)
654 close(mSubdevFd);
655
656 mVideodevFd = -1;
657 mMediadevFd = -1;
658 mSubdevFd = -1;
659
660 return false;
661}
662
663bool SecGscaler::destroy()
664{
665 s5p_fimc_params_t *params = &(mS5pFimc.params);
666
667 if (mFlagCreate == false) {
668 LOGE("%s::Already Destroyed", __func__);
669 return true;
670 }
671
672 if (mFlagStreamOn == true) {
673 if (streamOff() == false) {
674 LOGE("%s::streamOff() failed", __func__);
675 return false;
676 }
677
678 if (closeVideodevFd() == false) {
679 LOGE("%s::closeVideodevFd() failed", __func__);
680 return false;
681 }
682
683 mFlagStreamOn = false;
684 }
685
686 if (0 < mMediadevFd)
687 close(mMediadevFd);
688
689 if (0 < mSubdevFd)
690 close(mSubdevFd);
691
692 mVideodevFd = -1;
693 mMediadevFd = -1;
694 mSubdevFd = -1;
695
696 mFlagCreate = false;
697
698 return true;
699}
700
701bool SecGscaler::flagCreate(void)
702{
703 return mFlagCreate;
704}
705
706int SecGscaler::getFd(void)
707{
708 return getVideodevFd();
709}
710
711int SecGscaler::getVideodevFd(void)
712{
713 return mVideodevFd;
714}
715
716bool SecGscaler::openVideodevFd(void)
717{
718 char node[32];
719
720 sprintf(node, "%s%d", PFX_NODE_VIDEODEV, mVideoNodeNum);
721 mVideodevFd = open(node, O_RDWR);
722 if (mVideodevFd < 0) {
723 LOGE("%s::open(%s) failed", __func__, node);
724 return false;
725 }
726
727 return true;
728}
729
730bool SecGscaler::closeVideodevFd(void)
731{
732 if (mFlagSetSrcParam == true) {
733 if (gsc_v4l2_clr_buf(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE) < 0) {
734 LOGE("%s::gsc_v4l2_clr_buf() failed", __func__);
735 return false;
736 }
737 }
738
739 if (0 < mVideodevFd) {
740 if (close(mVideodevFd) < 0) {
741 LOGE("%s::close Videodev failed", __func__);
742 return false;
743 }
744 }
745 mVideodevFd = -1;
746
747 return true;
748}
749
750int SecGscaler::getSubdevFd(void)
751{
752 return mSubdevFd;
753}
754
755__u32 SecGscaler::getSubdevEntity(void)
756{
757 return mSubdevEntity;
758}
759
760__u32 SecGscaler::getVideodevEntity(void)
761{
762 return mVideodevEntity;
763}
764
765bool SecGscaler::getFlagSteamOn(void)
766{
767 return mFlagStreamOn;
768}
769
770SecBuffer * SecGscaler::getSrcBufferAddr(int index)
771{
772 if (mFlagCreate == false) {
773 LOGE("%s::Not yet created", __func__);
774 return false;
775 }
776
777 return &mSrcBuffer[index];
778}
779
780bool SecGscaler::setSrcParams(unsigned int width, unsigned int height,
781 unsigned int cropX, unsigned int cropY,
782 unsigned int *cropWidth, unsigned int *cropHeight,
783 int colorFormat,
784 bool forceChange)
785{
786#ifdef DEBUG_LIB_FIMC
787 LOGD("%s", __func__);
788#endif
789
790 if (mFlagCreate == false) {
791 LOGE("%s::Not yet created", __func__);
792 return false;
793 }
794
795 int v4l2ColorFormat = HAL_PIXEL_FORMAT_2_V4L2_PIX(colorFormat);
796 if (v4l2ColorFormat < 0) {
797 LOGE("%s::not supported color format", __func__);
798 return false;
799 }
800
801 s5p_fimc_params_t *params = &(mS5pFimc.params);
802
803 unsigned int fimcWidth = *cropWidth;
804 unsigned int fimcHeight = *cropHeight;
805 int src_planes = m_getYuvPlanes(v4l2ColorFormat);
806 int src_bpp = m_getYuvBpp(v4l2ColorFormat);
807 unsigned int frame_size = width * height;
808 unsigned int frame_ratio = 8;
809
810 if (m_checkSrcSize(width, height, cropX, cropY,
811 &fimcWidth, &fimcHeight, v4l2ColorFormat, false) == false) {
812 LOGE("%s::::size align error!", __func__);
813 return false;
814 }
815
816 if (fimcWidth != *cropWidth || fimcHeight != *cropHeight) {
817 if (forceChange == true) {
818#ifdef DEBUG_LIB_FIMC
819 LOGD("size is changed from [w=%d, h=%d] to [w=%d, h=%d]",
820 *cropWidth, *cropHeight, fimcWidth, fimcHeight);
821#endif
822 } else {
823 LOGE("%s::invalid source params", __func__);
824 return false;
825 }
826 }
827
828 if ( (params->src.full_width == width)
829 && (params->src.full_height == height)
830 && (params->src.start_x == cropX)
831 && (params->src.start_y == cropY)
832 && (params->src.width == fimcWidth)
833 && (params->src.height == fimcHeight)
834 && (params->src.color_space == (unsigned int)v4l2ColorFormat))
835 return true;
836
837 params->src.full_width = width;
838 params->src.full_height = height;
839 params->src.start_x = cropX;
840 params->src.start_y = cropY;
841 params->src.width = fimcWidth;
842 params->src.height = fimcHeight;
843 params->src.color_space = v4l2ColorFormat;
844 src_planes = (src_planes == -1) ? 1 : src_planes;
845 params->src.planes = src_planes;
846
847 mSrcBuffer[mSrcIndex].size.extS[0] = 0;
848 mSrcBuffer[mSrcIndex].size.extS[1] = 0;
849 mSrcBuffer[mSrcIndex].size.extS[2] = 0;
850
851 frame_ratio = frame_ratio * (src_planes -1) / (src_bpp - 8);
852#ifdef USE_GSC_USERPTR
853 for (int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) {
854 switch (src_planes) {
855 case 1:
856 switch (v4l2ColorFormat) {
857 case V4L2_PIX_FMT_BGR32:
858 params->src.color_space = V4L2_PIX_FMT_RGB32;
859 case V4L2_PIX_FMT_RGB32:
860 mSrcBuffer[buf_index].size.extS[0] = frame_size << 2;
861 break;
862 case V4L2_PIX_FMT_RGB565X:
863 case V4L2_PIX_FMT_NV16:
864 case V4L2_PIX_FMT_NV61:
865 case V4L2_PIX_FMT_YUYV:
866 case V4L2_PIX_FMT_UYVY:
867 case V4L2_PIX_FMT_VYUY:
868 case V4L2_PIX_FMT_YVYU:
869 mSrcBuffer[buf_index].size.extS[0] = frame_size << 1;
870 break;
871 case V4L2_PIX_FMT_YUV420:
872 case V4L2_PIX_FMT_NV12:
873 case V4L2_PIX_FMT_NV21:
874 mSrcBuffer[buf_index].size.extS[0] = (frame_size * 3) >> 1;
875 break;
876 default:
877 LOGE("%s::invalid color type", __func__);
878 return false;
879 break;
880 }
881 mSrcBuffer[buf_index].size.extS[1] = 0;
882 mSrcBuffer[buf_index].size.extS[2] = 0;
883 break;
884 case 2:
885 case 3:
886 mSrcBuffer[buf_index].size.extS[0] = frame_size;
887 mSrcBuffer[buf_index].size.extS[1] = frame_size / frame_ratio;
888 mSrcBuffer[buf_index].size.extS[2] = frame_size / frame_ratio;
889 break;
890 default:
891 LOGE("%s::invalid color foarmt", __func__);
892 return false;
893 break;
894 }
895 }
896#else
897 if (v4l2ColorFormat == V4L2_PIX_FMT_BGR32)
898 params->src.color_space = V4L2_PIX_FMT_RGB32;
899#endif
900
901 if (mFlagSetSrcParam == true) {
902 if (gsc_v4l2_clr_buf(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE) < 0) {
903 LOGE("%s::gsc_v4l2_clr_buf() failed", __func__);
904 return false;
905 }
906 }
907
908 if (gsc_v4l2_set_fmt(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_FIELD_NONE, &(params->src)) < 0) {
909 LOGE("%s::fimc_v4l2_set_fmt()[src] failed", __func__);
910 return false;
911 }
912
913 if (gsc_v4l2_req_buf(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, mNumOfBuf) < 0) {
914 LOGE("%s::fimc_v4l2_req_buf()[src] failed", __func__);
915 return false;
916 }
917#ifdef USE_GSC_USERPTR
918#else
919 for (unsigned int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) {
920 if (gsc_v4l2_query_buf(mVideodevFd, &mSrcBuffer[buf_index], V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_MMAP, buf_index, params->src.planes) < 0) {
921 LOGE("%s::gsc_v4l2_query_buf() failed", __func__);
922 return false;
923 }
924 }
925#endif
926
927 *cropWidth = fimcWidth;
928 *cropHeight = fimcHeight;
929
930 mFlagSetSrcParam = true;
931
932 return true;
933}
934
935bool SecGscaler::getSrcParams(unsigned int *width, unsigned int *height,
936 unsigned int *cropX, unsigned int *cropY,
937 unsigned int *cropWidth, unsigned int *cropHeight,
938 int *v4l2colorFormat)
939{
940 struct v4l2_format fmt;
941 struct v4l2_crop crop;
942
943 fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
944
945 if (ioctl(mVideodevFd, VIDIOC_G_FMT, &fmt) < 0) {
946 LOGE("%s::VIDIOC_G_FMT(fmt.type : %d) failed", __func__, fmt.type);
947 return false;
948 }
949
950 switch (fmt.type) {
951 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
952 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
953 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
954 *width = fmt.fmt.pix.width;
955 *height = fmt.fmt.pix.height;
956 *v4l2colorFormat = fmt.fmt.pix.pixelformat;
957 break;
958 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
959 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
960 *width = fmt.fmt.pix_mp.width;
961 *height = fmt.fmt.pix_mp.height;
962 *v4l2colorFormat = fmt.fmt.pix_mp.pixelformat;
963 break;
964 default:
965 LOGE("%s::Invalid buffer type", __func__);
966 return false;
967 break;
968 }
969
970 crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
971 if (ioctl(mVideodevFd, VIDIOC_G_CROP, &crop) < 0) {
972 LOGE("%s::VIDIOC_G_CROP failed", __func__);
973 return false;
974 }
975
976 *cropX = crop.c.left;
977 *cropY = crop.c.top;
978 *cropWidth = crop.c.width;
979 *cropHeight = crop.c.height;
980
981 return true;
982}
983
984bool SecGscaler::setSrcAddr(unsigned int YAddr,
985 unsigned int CbAddr,
986 unsigned int CrAddr,
987 int colorFormat)
988{
989#ifdef DEBUG_LIB_FIMC
990 LOGD("%s", __func__);
991#endif
992
993 if (mFlagCreate == false) {
994 LOGE("%s::Not yet created", __func__);
995 return false;
996 }
997
998 if (mFlagSetSrcParam == false) {
999 LOGE("%s::mFlagSetSrcParam == false", __func__);
1000 return false;
1001 }
1002
1003#ifdef USE_GSC_USERPTR
1004 mSrcBuffer[mSrcIndex].virt.extP[0] = (char *)YAddr;
1005 mSrcBuffer[mSrcIndex].virt.extP[1] = (char *)CbAddr;
1006 mSrcBuffer[mSrcIndex].virt.extP[2] = (char *)CrAddr;
1007#else
1008 unsigned int srcAddr[MAX_PLANES_GSCALER];
1009
1010 srcAddr[0] = YAddr;
1011 srcAddr[1] = CbAddr;
1012 srcAddr[2] = CrAddr;
1013
1014 for (int plane_index = 0; plane_index < mS5pFimc.params.src.planes; plane_index++) {
1015 memcpy((void *)mSrcBuffer[mSrcIndex].virt.extP[plane_index], (void *)srcAddr[plane_index], mSrcBuffer[mSrcIndex].size.extS[plane_index]);
1016 }
1017#endif
1018
1019 return true;
1020}
1021
1022bool SecGscaler::setDstParams(unsigned int width, unsigned int height,
1023 unsigned int cropX, unsigned int cropY,
1024 unsigned int *cropWidth, unsigned int *cropHeight,
1025 int colorFormat,
1026 bool forceChange)
1027{
1028#ifdef DEBUG_LIB_FIMC
1029 LOGD("%s", __func__);
1030#endif
1031
1032 if (mFlagCreate == false) {
1033 LOGE("%s::Not yet created", __func__);
1034 return false;
1035 }
1036
1037 int mbusFormat = V4L2_MBUS_FMT_YUV8_1X24;
1038
1039 s5p_fimc_params_t *params = &(mS5pFimc.params);
1040
1041 unsigned int fimcWidth = *cropWidth;
1042 unsigned int fimcHeight = *cropHeight;
1043
1044 if( m_checkDstSize(width, height, cropX, cropY,
1045 &fimcWidth, &fimcHeight, V4L2_PIX_FMT_YUV444,
1046 mRotVal, true) == false) {
1047 LOGE("%s::size align error!", __func__);
1048 return false;
1049 }
1050
1051
1052 if (fimcWidth != *cropWidth || fimcHeight != *cropHeight) {
1053 if (forceChange == true) {
1054#ifdef DEBUG_LIB_FIMC
1055 LOGD("size is changed from [w = %d, h= %d] to [w = %d, h = %d]",
1056 *cropWidth, *cropHeight, fimcWidth, fimcHeight);
1057#endif
1058 } else {
1059 LOGE("%s::Invalid destination params", __func__);
1060 return false;
1061 }
1062 }
1063
1064 if (90 == mRotVal || 270 == mRotVal) {
1065 params->dst.full_width = height;
1066 params->dst.full_height = width;
1067
1068 if (90 == mRotVal) {
1069 params->dst.start_x = cropY;
1070 params->dst.start_y = width - (cropX + fimcWidth);
1071 } else {
1072 params->dst.start_x = height - (cropY + fimcHeight);
1073 params->dst.start_y = cropX;
1074 }
1075
1076 params->dst.width = fimcHeight;
1077 params->dst.height = fimcWidth;
1078
1079 params->dst.start_y += (fimcWidth - params->dst.height);
1080
1081 } else {
1082 params->dst.full_width = width;
1083 params->dst.full_height = height;
1084
1085 if (180 == mRotVal) {
1086 params->dst.start_x = width - (cropX + fimcWidth);
1087 params->dst.start_y = height - (cropY + fimcHeight);
1088 } else {
1089 params->dst.start_x = cropX;
1090 params->dst.start_y = cropY;
1091 }
1092
1093 params->dst.width = fimcWidth;
1094 params->dst.height = fimcHeight;
1095 }
1096
1097 if (gsc_subdev_set_fmt(mSubdevFd, GSC_SUBDEV_PAD_SOURCE, V4L2_MBUS_FMT_YUV8_1X24, &(params->dst)) < 0) {
1098 LOGE("%s::gsc_subdev_set_fmt()[dst] failed", __func__);
1099 return false;
1100 }
1101
1102 mFlagSetDstParam = true;
1103
1104 return true;
1105}
1106
1107bool SecGscaler::getDstParams(unsigned int *width, unsigned int *height,
1108 unsigned int *cropX, unsigned int *cropY,
1109 unsigned int *cropWidth, unsigned int *cropHeight,
1110 int *mbusColorFormat)
1111{
1112 struct v4l2_subdev_format fmt;
1113 struct v4l2_subdev_crop crop;
1114
1115 fmt.pad = GSC_SUBDEV_PAD_SOURCE;
1116 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1117
1118 if (ioctl(mSubdevFd, VIDIOC_SUBDEV_G_FMT, &fmt) < 0) {
1119 LOGE("%s::VIDIOC_SUBDEV_S_FMT", __func__);
1120 return -1;
1121 }
1122
1123 *width = fmt.format.width;
1124 *height = fmt.format.height;
1125 *mbusColorFormat = fmt.format.code;
1126
1127 crop.pad = GSC_SUBDEV_PAD_SOURCE;
1128 crop.which = V4L2_SUBDEV_FORMAT_ACTIVE;
1129
1130 if (ioctl(mSubdevFd, VIDIOC_SUBDEV_G_CROP, &crop) < 0) {
1131 LOGE("%s::VIDIOC_SUBDEV_S_CROP", __func__);
1132 return -1;
1133 }
1134
1135 *cropX = crop.rect.left;
1136 *cropY = crop.rect.top;
1137 *cropWidth = crop.rect.width;
1138 *cropHeight = crop.rect.height;
1139
1140 return true;
1141}
1142
1143bool SecGscaler::setDstAddr(unsigned int YAddr, unsigned int CbAddr, unsigned int CrAddr, int buf_index)
1144{
1145#ifdef DEBUG_LIB_FIMC
1146 LOGD("%s", __func__);
1147#endif
1148
1149 if (mFlagCreate == false) {
1150 LOGE("%s::Not yet created", __func__);
1151 return false;
1152 }
1153
1154 return true;
1155}
1156
1157bool SecGscaler::setRotVal(unsigned int rotVal)
1158{
1159 struct v4l2_control vc;
1160
1161 if (mFlagCreate == false) {
1162 LOGE("%s::Not yet created", __func__);
1163 return false;
1164 }
1165
1166 if (gsc_v4l2_s_ctrl(mVideodevFd, V4L2_CID_ROTATE, rotVal) < 0) {
1167 LOGE("%s::fimc_v4l2_s_ctrl(V4L2_CID_ROTATE) failed", __func__);
1168 return false;
1169 }
1170
1171 mRotVal = rotVal;
1172 return true;
1173}
1174
1175bool SecGscaler::setGlobalAlpha(bool enable, int alpha)
1176{
1177 if (mFlagCreate == false) {
1178 LOGE("%s::Not yet created", __func__);
1179 return false;
1180 }
1181
1182 if (mFlagStreamOn == true) {
1183 LOGE("%s::mFlagStreamOn == true", __func__);
1184 return false;
1185 }
1186
1187 mFlagGlobalAlpha = enable;
1188 mGlobalAlpha = alpha;
1189
1190 return true;
1191
1192}
1193
1194bool SecGscaler::setLocalAlpha(bool enable)
1195{
1196 if (mFlagCreate == false) {
1197 LOGE("%s::Not yet created", __func__);
1198 return false;
1199 }
1200
1201 if (mFlagStreamOn == true) {
1202 LOGE("%s::mFlagStreamOn == true", __func__);
1203 return false;
1204 }
1205
1206 if (mFlagLocalAlpha == enable)
1207 return true;
1208
1209 return true;
1210}
1211
1212bool SecGscaler::setColorKey(bool enable, int colorKey)
1213{
1214 if (mFlagCreate == false) {
1215 LOGE("%s::Not yet created", __func__);
1216 return false;
1217 }
1218
1219 if (mFlagStreamOn == true) {
1220 LOGE("%s::mFlagStreamOn == true", __func__);
1221 return false;
1222 }
1223
1224 mFlagColorKey = enable;
1225 mColorKey = colorKey;
1226
1227 return true;
1228}
1229
1230bool SecGscaler::run()
1231{
1232#ifdef DEBUG_LIB_FIMC
1233 LOGD("%s", __func__);
1234#endif
1235
1236 if (mFlagCreate == false) {
1237 LOGE("%s::Not yet created", __func__);
1238 return false;
1239 }
1240
1241 if (mFlagSetSrcParam == false) {
1242 LOGE("%s::faild : Need to set source parameters of Gscaler", __func__);
1243 return false;
1244 }
1245
1246 if (mFlagSetDstParam == false) {
1247 LOGE("%s::faild : Need to set destination parameters of Gscaler", __func__);
1248 return false;
1249 }
1250
1251 s5p_fimc_params_t *params = &(mS5pFimc.params);
1252 int src_planes = m_getYuvPlanes(params->src.color_space);
1253 unsigned int dqIndex = 0;
1254 src_planes = (src_planes == -1) ? 1 : src_planes;
1255
1256 if (gsc_v4l2_queue(mVideodevFd, &(mSrcBuffer[mSrcIndex]), V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, mSrcIndex, src_planes) < 0) {
1257 LOGE("%s::fimc_v4l2_queue[src](mNumOfBuf : %d,mSrcIndex=%d) failed", __func__, mNumOfBuf, mSrcIndex);
1258 return false;
1259 }
1260
1261 mSrcIndex++;
1262 if (mSrcIndex >= MAX_BUFFERS_GSCALER) {
1263 mSrcIndex = 0;
1264 }
1265
1266 if (gsc_v4l2_dequeue(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, &dqIndex, src_planes) < 0) {
1267 LOGE("%s::fimc_v4l2_dequeue[src](mNumOfBuf : %d, dqIndex=%d) failed", __func__, mNumOfBuf, dqIndex);
1268 return false;
1269 }
1270
1271 return true;
1272}
1273
1274bool SecGscaler::streamOn(void)
1275{
1276#ifdef DEBUG_LIB_FIMC
1277 LOGD("%s", __func__);
1278#endif
1279
1280 if (mFlagCreate == false) {
1281 LOGE("%s::Not yet created", __func__);
1282 return false;
1283 }
1284
1285 if (mFlagStreamOn == true) {
1286 LOGE("%s::already streamon", __func__);
1287 return true;
1288 }
1289
1290 s5p_fimc_params_t *params = &(mS5pFimc.params);
1291 int src_planes = m_getYuvPlanes(params->src.color_space);
1292 src_planes = (src_planes == -1) ? 1 : src_planes;
1293
1294 if (gsc_v4l2_queue(mVideodevFd, &(mSrcBuffer[mSrcIndex]), V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE, V4L2_MEMORY_TYPE, mSrcIndex, src_planes) < 0) {
1295 LOGE("%s::fimc_v4l2_queue[src](mNumOfBuf : %d,mSrcIndex=%d) failed", __func__, mNumOfBuf, mSrcIndex);
1296 return false;
1297 }
1298
1299 mSrcIndex++;
1300 if (mSrcIndex == MAX_BUFFERS_GSCALER - 1) {
1301 if (gsc_v4l2_stream_on(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
1302 LOGE("%s::fimc_v4l2_stream_on() failed", __func__);
1303 return false;
1304 }
1305 mFlagStreamOn = true;
1306 }
1307
1308 if (mSrcIndex >= MAX_BUFFERS_GSCALER) {
1309 mSrcIndex = 0;
1310 }
1311
1312 return true;
1313}
1314
1315bool SecGscaler::streamOff(void)
1316{
1317#ifdef DEBUG_LIB_FIMC
1318 LOGD("%s", __func__);
1319#endif
1320
1321 if (mFlagCreate == false) {
1322 LOGE("%s::Not yet created", __func__);
1323 return false;
1324 }
1325
1326 if (mFlagStreamOn == false) {
1327 LOGE("%s::already streamoff", __func__);
1328 return true;
1329 }
1330
1331 if (gsc_v4l2_stream_off(mVideodevFd, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) < 0) {
1332 LOGE("%s::fimc_v4l2_stream_off() failed", __func__);
1333 return false;
1334 }
1335
1336 mSrcIndex = 0;
1337#ifdef USE_GSC_USERPTR
1338 SecBuffer zeroBuf;
1339 for (int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++)
1340 mSrcBuffer[buf_index] = zeroBuf;
1341#else
1342 for (int buf_index = 0; buf_index < MAX_BUFFERS_GSCALER; buf_index++) {
1343 for (int plane_index = 0; plane_index < MAX_PLANES_GSCALER; plane_index++) {
1344 munmap((void *)mSrcBuffer[buf_index].virt.extP[plane_index], mSrcBuffer[buf_index].size.extS[plane_index]);
1345 }
1346 }
1347#endif
1348
1349 mFlagStreamOn = false;
1350
1351 return true;
1352}
1353
1354bool SecGscaler::m_checkSrcSize(unsigned int width, unsigned int height,
1355 unsigned int cropX, unsigned int cropY,
1356 unsigned int *cropWidth, unsigned int *cropHeight,
1357 int colorFormat,
1358 bool forceChange)
1359{
1360 bool ret = true;
1361
1362 if (8 <= height && *cropHeight < 8) {
1363 if (forceChange)
1364 *cropHeight = 8;
1365 ret = false;
1366 }
1367
1368 if (16 <= width && *cropWidth < 16) {
1369 if (forceChange)
1370 *cropWidth = 16;
1371 ret = false;
1372 }
1373
1374 if (height < 8)
1375 return false;
1376
1377 if (width % 16 != 0)
1378 return false;
1379
1380 if (*cropWidth % 16 != 0) {
1381 if (forceChange)
1382 *cropWidth = multipleOfN(*cropWidth, 16);
1383 ret = false;
1384 }
1385
1386 return ret;
1387}
1388
1389bool SecGscaler::m_checkDstSize(unsigned int width, unsigned int height,
1390 unsigned int cropX, unsigned int cropY,
1391 unsigned int *cropWidth, unsigned int *cropHeight,
1392 int colorFormat, int rotVal, bool forceChange)
1393{
1394 bool ret = true;
1395 unsigned int rotWidth;
1396 unsigned int rotHeight;
1397 unsigned int *rotCropWidth;
1398 unsigned int *rotCropHeight;
1399
1400 if (rotVal == 90 || rotVal == 270) {
1401 rotWidth = height;
1402 rotHeight = width;
1403 rotCropWidth = cropHeight;
1404 rotCropHeight = cropWidth;
1405 } else {
1406 rotWidth = width;
1407 rotHeight = height;
1408 rotCropWidth = cropWidth;
1409 rotCropHeight = cropHeight;
1410 }
1411
1412 if (rotHeight < 8)
1413 return false;
1414
1415 if (rotWidth % 8 != 0)
1416 return false;
1417
1418 switch (colorFormat) {
1419 case V4L2_PIX_FMT_NV21:
1420 case V4L2_PIX_FMT_NV12:
1421 case V4L2_PIX_FMT_NV12T:
1422 case V4L2_PIX_FMT_NV12M:
1423 case V4L2_PIX_FMT_NV12MT:
1424 case V4L2_PIX_FMT_YUV420M:
1425 case V4L2_PIX_FMT_YUV420:
1426 if (*rotCropHeight % 2 != 0) {
1427 if (forceChange)
1428 *rotCropHeight = multipleOfN(*rotCropHeight, 2);
1429 ret = false;
1430 }
1431 }
1432 return ret;
1433}
1434
1435int SecGscaler::m_widthOfFimc(int v4l2ColorFormat, int width)
1436{
1437 int newWidth = width;
1438
1439 switch (v4l2ColorFormat) {
1440 case V4L2_PIX_FMT_RGB565:
1441 newWidth = multipleOfN(width, 8);
1442 break;
1443 case V4L2_PIX_FMT_RGB32:
1444 newWidth = multipleOfN(width, 4);
1445 break;
1446 case V4L2_PIX_FMT_YUYV:
1447 case V4L2_PIX_FMT_UYVY:
1448 newWidth = multipleOfN(width, 4);
1449 break;
1450 case V4L2_PIX_FMT_NV61:
1451 case V4L2_PIX_FMT_NV16:
1452 newWidth = multipleOfN(width, 8);
1453 break;
1454 case V4L2_PIX_FMT_YUV422P:
1455 newWidth = multipleOfN(width, 16);
1456 break;
1457 case V4L2_PIX_FMT_NV21:
1458 case V4L2_PIX_FMT_NV12:
1459 case V4L2_PIX_FMT_NV12MT:
1460 newWidth = multipleOfN(width, 8);
1461 break;
1462 case V4L2_PIX_FMT_YUV420:
1463 case V4L2_PIX_FMT_YUV420M:
1464 newWidth = multipleOfN(width, 16);
1465 break;
1466 default :
1467 break;
1468 }
1469
1470 return newWidth;
1471}
1472
1473int SecGscaler::m_heightOfFimc(int v4l2ColorFormat, int height)
1474{
1475 int newHeight = height;
1476
1477 switch (v4l2ColorFormat) {
1478 case V4L2_PIX_FMT_NV21:
1479 case V4L2_PIX_FMT_NV12:
1480 case V4L2_PIX_FMT_NV12T:
1481 case V4L2_PIX_FMT_NV12MT:
1482 case V4L2_PIX_FMT_YUV420:
1483 case V4L2_PIX_FMT_YUV420M:
1484 newHeight = multipleOfN(height, 2);
1485 break;
1486 default :
1487 break;
1488 }
1489 return newHeight;
1490}
1491
1492int SecGscaler::m_getYuvBpp(unsigned int fmt)
1493{
1494 int i, sel = -1;
1495
1496 for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) {
1497 if (yuv_list[i].fmt == fmt) {
1498 sel = i;
1499 break;
1500 }
1501 }
1502
1503 if (sel == -1)
1504 return sel;
1505 else
1506 return yuv_list[sel].bpp;
1507}
1508
1509int SecGscaler::m_getYuvPlanes(unsigned int fmt)
1510{
1511 int i, sel = -1;
1512
1513 for (i = 0; i < (int)(sizeof(yuv_list) / sizeof(struct yuv_fmt_list)); i++) {
1514 if (yuv_list[i].fmt == fmt) {
1515 sel = i;
1516 break;
1517 }
1518 }
1519
1520 if (sel == -1)
1521 return sel;
1522 else
1523 return yuv_list[sel].planes;
1524}