| /* |
| * v4l2_buffer_proxy.cpp - v4l2 buffer proxy |
| * |
| * Copyright (c) 2014-2015 Intel Corporation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * Author: Wind Yuan <[email protected]> |
| */ |
| |
| #include "v4l2_buffer_proxy.h" |
| #include "v4l2_device.h" |
| |
| namespace XCam { |
| V4l2Buffer::V4l2Buffer (const struct v4l2_buffer &buf, const struct v4l2_format &format) |
| { |
| _buf = buf; |
| _format = format; |
| } |
| |
| V4l2Buffer::~V4l2Buffer () |
| { |
| } |
| |
| uint8_t * |
| V4l2Buffer::map () |
| { |
| if (_buf.memory == V4L2_MEMORY_DMABUF) |
| return NULL; |
| return (uint8_t *)(_buf.m.userptr); |
| } |
| |
| bool |
| V4l2Buffer::unmap () |
| { |
| return true; |
| } |
| |
| int |
| V4l2Buffer::get_fd () |
| { |
| if (_buf.memory == V4L2_MEMORY_MMAP) |
| return -1; |
| return _buf.m.fd; |
| } |
| |
| V4l2BufferProxy::V4l2BufferProxy (SmartPtr<V4l2Buffer> &buf, SmartPtr<V4l2Device> &device) |
| : BufferProxy (buf) |
| , _device (device) |
| { |
| VideoBufferInfo info; |
| struct timeval ts = buf->get_buf().timestamp; |
| |
| v4l2_format_to_video_info (buf->get_format(), info); |
| set_video_info (info); |
| set_timestamp (XCAM_TIMEVAL_2_USEC (ts)); |
| } |
| |
| V4l2BufferProxy::~V4l2BufferProxy () |
| { |
| SmartPtr<BufferData> data = get_buffer_data (); |
| SmartPtr<V4l2Buffer> v4l2_data = data.dynamic_cast_ptr<V4l2Buffer> (); |
| if (_device.ptr () && v4l2_data.ptr ()) |
| _device->queue_buffer (v4l2_data); |
| XCAM_LOG_DEBUG ("v4l2 buffer released"); |
| } |
| |
| void |
| V4l2BufferProxy::v4l2_format_to_video_info ( |
| const struct v4l2_format &format, VideoBufferInfo &info) |
| { |
| info.format = format.fmt.pix.pixelformat; |
| info.color_bits = 8; |
| info.width = format.fmt.pix.width; |
| info.height = format.fmt.pix.height; |
| info.aligned_width = 0; |
| info.aligned_height = 0; |
| info.size = format.fmt.pix.sizeimage; |
| switch (format.fmt.pix.pixelformat) { |
| case V4L2_PIX_FMT_NV12: // 420 |
| case V4L2_PIX_FMT_NV21: |
| info.components = 2; |
| info.strides [0] = format.fmt.pix.bytesperline * 2 / 3; |
| info.strides [1] = info.strides [0]; |
| info.offsets[0] = 0; |
| info.offsets[1] = info.strides [0] * format.fmt.pix.height; |
| break; |
| case V4L2_PIX_FMT_YUV422P: // 422 Planar |
| info.components = 3; |
| info.strides [0] = format.fmt.pix.bytesperline / 2; |
| info.strides [1] = info.strides [0] / 2 ; |
| info.strides [2] = info.strides [0] / 2 ; |
| info.offsets[0] = 0; |
| info.offsets[1] = info.strides [0] * format.fmt.pix.height; |
| info.offsets[2] = info.offsets[1] + info.strides [1] * format.fmt.pix.height; |
| break; |
| case V4L2_PIX_FMT_YUYV: // 422 |
| info.components = 1; |
| info.strides [0] = format.fmt.pix.bytesperline; |
| info.offsets[0] = 0; |
| info.aligned_width = info.strides [0] / 2; |
| break; |
| case V4L2_PIX_FMT_SBGGR10: |
| case V4L2_PIX_FMT_SGBRG10: |
| case V4L2_PIX_FMT_SGRBG10: |
| case V4L2_PIX_FMT_SRGGB10: |
| info.color_bits = 10; |
| info.components = 1; |
| info.strides [0] = format.fmt.pix.bytesperline; |
| info.offsets[0] = 0; |
| break; |
| case V4L2_PIX_FMT_SBGGR12: |
| case V4L2_PIX_FMT_SGBRG12: |
| case V4L2_PIX_FMT_SGRBG12: |
| case V4L2_PIX_FMT_SRGGB12: |
| info.color_bits = 12; |
| info.components = 1; |
| info.strides [0] = format.fmt.pix.bytesperline; |
| info.offsets[0] = 0; |
| break; |
| default: |
| XCAM_LOG_WARNING ( |
| "unknown v4l2 format(%s) to video info", |
| xcam_fourcc_to_string (format.fmt.pix.pixelformat)); |
| break; |
| } |
| |
| if (!info.aligned_width) |
| info.aligned_width = info.strides [0]; |
| |
| if (!info.aligned_height) |
| info.aligned_height = info.height; |
| |
| } |
| |
| const struct v4l2_buffer & |
| V4l2BufferProxy::get_v4l2_buf () |
| { |
| SmartPtr<BufferData> &data = get_buffer_data (); |
| SmartPtr<V4l2Buffer> v4l2_data = data.dynamic_cast_ptr<V4l2Buffer> (); |
| XCAM_ASSERT (v4l2_data.ptr ()); |
| return v4l2_data->get_buf (); |
| } |
| |
| }; |