1/*
2 * xcam_buffer.cpp - video buffer standard version
3 *
4 *  Copyright (c) 2016 Intel Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Author: Wind Yuan <feng.yuan@intel.com>
19 */
20
21#include <base/xcam_buffer.h>
22
23XCamReturn
24xcam_video_buffer_info_reset (
25    XCamVideoBufferInfo *info,
26    uint32_t format,
27    uint32_t width, uint32_t height,
28    uint32_t aligned_width, uint32_t aligned_height, uint32_t size)
29{
30    uint32_t image_size = 0;
31    uint32_t i = 0;
32
33    XCAM_ASSERT (info && format);
34    XCAM_ASSERT (!aligned_width  || aligned_width >= width);
35    XCAM_ASSERT (!aligned_height  || aligned_height >= height);
36
37    if (!aligned_width)
38        aligned_width = XCAM_ALIGN_UP (width, 4);
39    if (!aligned_height)
40        aligned_height = XCAM_ALIGN_UP (height, 2);
41
42    info->format = format;
43    info->width = width;
44    info->height = height;
45    info->aligned_width = aligned_width;
46    info->aligned_height = aligned_height;
47
48    switch (format) {
49    case V4L2_PIX_FMT_GREY:
50        info->color_bits = 8;
51        info->components = 1;
52        info->strides [0] = aligned_width;
53        info->offsets [0] = 0;
54        image_size = info->strides [0] * aligned_height;
55        break;
56    case V4L2_PIX_FMT_NV12:
57        info->color_bits = 8;
58        info->components = 2;
59        info->strides [0] = aligned_width;
60        info->strides [1] = info->strides [0];
61        info->offsets [0] = 0;
62        info->offsets [1] = info->offsets [0] + info->strides [0] * aligned_height;
63        image_size = info->strides [0] * aligned_height + info->strides [1] * aligned_height / 2;
64        break;
65    case V4L2_PIX_FMT_YUYV:
66        info->color_bits = 8;
67        info->components = 1;
68        info->strides [0] = aligned_width * 2;
69        info->offsets [0] = 0;
70        image_size = info->strides [0] * aligned_height;
71        break;
72    case V4L2_PIX_FMT_RGB565:
73        info->color_bits = 16;
74        info->components = 1;
75        info->strides [0] = aligned_width * 2;
76        info->offsets [0] = 0;
77        image_size = info->strides [0] * aligned_height;
78        break;
79    case V4L2_PIX_FMT_RGB24:
80        info->color_bits = 8;
81        info->components = 1;
82        info->strides [0] = aligned_width * 3;
83        info->offsets [0] = 0;
84        image_size = info->strides [0] * aligned_height;
85        break;
86        // memory order RGBA 8-8-8-8
87    case V4L2_PIX_FMT_RGBA32:
88        // memory order: BGRA 8-8-8-8
89    case V4L2_PIX_FMT_XBGR32:
90    case V4L2_PIX_FMT_ABGR32:
91    case V4L2_PIX_FMT_BGR32:
92        // memory order: ARGB 8-8-8-8
93    case V4L2_PIX_FMT_RGB32:
94    case V4L2_PIX_FMT_ARGB32:
95    case V4L2_PIX_FMT_XRGB32:
96        info->color_bits = 8;
97        info->components = 1;
98        info->strides [0] = aligned_width * 4;
99        info->offsets [0] = 0;
100        image_size = info->strides [0] * aligned_height;
101        break;
102    case XCAM_PIX_FMT_RGB48:
103        info->color_bits = 16;
104        info->components = 1;
105        info->strides [0] = aligned_width * 3 * 2;
106        info->offsets [0] = 0;
107        image_size = info->strides [0] * aligned_height;
108        break;
109    case XCAM_PIX_FMT_RGBA64:
110        info->color_bits = 16;
111        info->components = 1;
112        info->strides [0] = aligned_width * 4 * 2;
113        info->offsets [0] = 0;
114        image_size = info->strides [0] * aligned_height;
115        break;
116
117    case V4L2_PIX_FMT_SBGGR8:
118    case V4L2_PIX_FMT_SGBRG8:
119    case V4L2_PIX_FMT_SGRBG8:
120    case V4L2_PIX_FMT_SRGGB8:
121        info->color_bits = 8;
122        info->components = 1;
123        info->strides [0] = aligned_width;
124        info->offsets [0] = 0;
125        image_size = info->strides [0] * aligned_height;
126        break;
127
128    case V4L2_PIX_FMT_SBGGR10:
129    case V4L2_PIX_FMT_SGBRG10:
130    case V4L2_PIX_FMT_SGRBG10:
131    case V4L2_PIX_FMT_SRGGB10:
132        info->color_bits = 10;
133        info->components = 1;
134        info->strides [0] = aligned_width * 2;
135        info->offsets [0] = 0;
136        image_size = info->strides [0] * aligned_height;
137        break;
138
139    case V4L2_PIX_FMT_SBGGR12:
140    case V4L2_PIX_FMT_SGBRG12:
141    case V4L2_PIX_FMT_SGRBG12:
142    case V4L2_PIX_FMT_SRGGB12:
143        info->color_bits = 12;
144        info->components = 1;
145        info->strides [0] = aligned_width * 2;
146        info->offsets [0] = 0;
147        image_size = info->strides [0] * aligned_height;
148        break;
149
150    case V4L2_PIX_FMT_SBGGR16:
151    case XCAM_PIX_FMT_SGRBG16:
152        info->color_bits = 16;
153        info->components = 1;
154        info->strides [0] = aligned_width * 2;
155        info->offsets [0] = 0;
156        image_size = info->strides [0] * aligned_height;
157        break;
158
159    case XCAM_PIX_FMT_LAB:
160        info->color_bits = 8;
161        info->components = 1;
162        info->strides [0] = aligned_width * 3;
163        info->offsets [0] = 0;
164        image_size = info->strides [0] * aligned_height;
165        break;
166
167    case XCAM_PIX_FMT_RGB48_planar:
168    case XCAM_PIX_FMT_RGB24_planar:
169        if (XCAM_PIX_FMT_RGB48_planar == format)
170            info->color_bits = 16;
171        else
172            info->color_bits = 8;
173        info->components = 3;
174        info->strides [0] = info->strides [1] = info->strides [2] = aligned_width * (info->color_bits / 8);
175        info->offsets [0] = 0;
176        info->offsets [1] = info->offsets [0] + info->strides [0] * aligned_height;
177        info->offsets [2] = info->offsets [1] + info->strides [1] * aligned_height;
178        image_size = info->offsets [2] + info->strides [2] * aligned_height;
179        break;
180
181    case XCAM_PIX_FMT_SGRBG16_planar:
182    case XCAM_PIX_FMT_SGRBG8_planar:
183        if (XCAM_PIX_FMT_SGRBG16_planar == format)
184            info->color_bits = 16;
185        else
186            info->color_bits = 8;
187        info->components = 4;
188        for (i = 0; i < info->components; ++i) {
189            info->strides [i] = aligned_width * (info->color_bits / 8);
190        }
191        info->offsets [0] = 0;
192        for (i = 1; i < info->components; ++i) {
193            info->offsets [i] = info->offsets [i - 1] + info->strides [i - 1] * aligned_height;
194        }
195        image_size = info->offsets [info->components - 1] + info->strides [info->components - 1] * aligned_height;
196        break;
197
198    default:
199        XCAM_LOG_WARNING ("XCamVideoBufferInfo reset failed, unsupported format:%s", xcam_fourcc_to_string (format));
200        return XCAM_RETURN_ERROR_PARAM;
201    }
202
203    if (!size)
204        info->size = image_size;
205    else {
206        XCAM_ASSERT (size >= image_size);
207        info->size = size;
208    }
209
210    return XCAM_RETURN_NO_ERROR;
211}
212
213XCamReturn
214xcam_video_buffer_get_planar_info (
215    const XCamVideoBufferInfo *buf_info,  XCamVideoBufferPlanarInfo *planar_info, const uint32_t index)
216{
217    XCAM_ASSERT (buf_info);
218    XCAM_ASSERT (planar_info);
219
220    planar_info->width = buf_info->width;
221    planar_info->height = buf_info->height;
222    planar_info->pixel_bytes = XCAM_ALIGN_UP (buf_info->color_bits, 8) / 8;
223
224    switch (buf_info->format) {
225    case V4L2_PIX_FMT_NV12:
226        XCAM_ASSERT (index <= 1);
227        if (index == 1) {
228            planar_info->height = buf_info->height / 2;
229        }
230        break;
231
232    case V4L2_PIX_FMT_GREY:
233    case V4L2_PIX_FMT_YUYV:
234    case V4L2_PIX_FMT_RGB565:
235    case V4L2_PIX_FMT_SBGGR8:
236    case V4L2_PIX_FMT_SGBRG8:
237    case V4L2_PIX_FMT_SGRBG8:
238    case V4L2_PIX_FMT_SRGGB8:
239    case V4L2_PIX_FMT_SBGGR10:
240    case V4L2_PIX_FMT_SGBRG10:
241    case V4L2_PIX_FMT_SGRBG10:
242    case V4L2_PIX_FMT_SRGGB10:
243    case V4L2_PIX_FMT_SBGGR12:
244    case V4L2_PIX_FMT_SGBRG12:
245    case V4L2_PIX_FMT_SGRBG12:
246    case V4L2_PIX_FMT_SRGGB12:
247    case V4L2_PIX_FMT_SBGGR16:
248    case XCAM_PIX_FMT_SGRBG16:
249        XCAM_ASSERT (index <= 0);
250        break;
251
252    case V4L2_PIX_FMT_RGB24:
253        XCAM_ASSERT (index <= 0);
254        planar_info->pixel_bytes = 3;
255        break;
256
257    case V4L2_PIX_FMT_RGBA32:
258    case V4L2_PIX_FMT_XBGR32:
259    case V4L2_PIX_FMT_ABGR32:
260    case V4L2_PIX_FMT_BGR32:
261    case V4L2_PIX_FMT_RGB32:
262    case V4L2_PIX_FMT_ARGB32:
263    case V4L2_PIX_FMT_XRGB32:
264        XCAM_ASSERT (index <= 0);
265        planar_info->pixel_bytes = 4;
266        break;
267
268    case XCAM_PIX_FMT_RGB48:
269        XCAM_ASSERT (index <= 0);
270        planar_info->pixel_bytes = 3 * 2;
271        break;
272
273    case XCAM_PIX_FMT_RGBA64:
274        planar_info->pixel_bytes = 4 * 2;
275        break;
276
277    case XCAM_PIX_FMT_LAB:
278        planar_info->pixel_bytes = 3;
279        break;
280
281    case XCAM_PIX_FMT_RGB48_planar:
282    case XCAM_PIX_FMT_RGB24_planar:
283        XCAM_ASSERT (index <= 2);
284        break;
285
286    case XCAM_PIX_FMT_SGRBG16_planar:
287    case XCAM_PIX_FMT_SGRBG8_planar:
288        XCAM_ASSERT (index <= 3);
289        break;
290
291    default:
292        XCAM_LOG_WARNING ("VideoBufferInfo get_planar_info failed, unsupported format:%s", xcam_fourcc_to_string (buf_info->format));
293        return XCAM_RETURN_ERROR_PARAM;
294    }
295
296    return XCAM_RETURN_NO_ERROR;
297}
298