/* * Copyright (c) 2021 by Allwinnertech Co., Ltd. * * 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. */ #define LOG_TAG "CameraHALv3_V4L2Wrapper" #include "v4l2_wrapper.h" #include #include #include #include #include #include #include #include #include #include #include "linux/videodev2.h" #include "stream_format.h" #include "type_camera.h" #include "v4l2_log.h" #include "v4l2_stream.h" #include GPU_PUBLIC_INCLUDE namespace v4l2_camera_hal { V4L2Wrapper* V4L2Wrapper::NewV4L2Wrapper( const int id, std::shared_ptr pCameraCfg) { HAL_LOG_ENTER(); return new V4L2Wrapper(id, pCameraCfg); } std::shared_ptr V4L2Wrapper::getStream(STREAM_SERIAL ss) { HAL_LOG_ENTER(); std::lock_guard lock(connection_lock_); STREAM_SERIAL tmpss = MAIN_STREAM; switch (ss) { case MAIN_STREAM: case MAIN_STREAM_BLOB: case MAIN_MIRROR_STREAM: case MAIN_MIRROR_STREAM_BLOB: tmpss = MAIN_STREAM; break; case SUB_0_STREAM: case SUB_0_STREAM_BLOB: case SUB_0_MIRROR_STREAM: case SUB_0_MIRROR_STREAM_BLOB: tmpss = SUB_0_STREAM; break; default: HAL_LOGE("Failed to set stream device_path."); break; } if (array_stream_obj[tmpss] == nullptr) { HAL_LOGE("Failed to find stream obj, you should connect device first."); return nullptr; } HAL_LOGV("getStream %d successfully.", tmpss); return array_stream_obj[tmpss]; } V4L2Wrapper::V4L2Wrapper(const int id, std::shared_ptr pCameraCfg) : mCameraConfig(pCameraCfg), device_id_(id), has_StreamOn(false), buffer_state_(BUFFER_UNINIT), #ifdef USE_ISP mAWIspApi(NULL), mIspId(-1), #endif isTakePicure(false) { HAL_LOG_ENTER(); for (int ss = 0; ss < MAX_STREAM; ss++) { connection_count_[ss] = 0; } } V4L2Wrapper::~V4L2Wrapper() {} int V4L2Wrapper::Connect(STREAM_SERIAL ss, int merge_status) { HAL_LOG_ENTER(); std::lock_guard lock(connection_lock_); std::string device_path; STREAM_SERIAL tmpss = MAIN_STREAM; int Support_Id = getSupportCameraId(device_id_); HAL_LOGD("device_id:%d Support_Id:%d", device_id_, Support_Id); switch (ss) { case MAIN_STREAM: case MAIN_STREAM_BLOB: case MAIN_MIRROR_STREAM: case MAIN_MIRROR_STREAM_BLOB: if (device_id_ == 0 && merge_status) { device_path = MAIN_MERGE_STREAM_PATH; } else if (device_id_ == 0 && merge_status == 0) { device_path = MAIN_STREAM_PATH; } tmpss = MAIN_STREAM; break; case SUB_0_STREAM: case SUB_0_STREAM_BLOB: case SUB_0_MIRROR_STREAM: case SUB_0_MIRROR_STREAM_BLOB: if (device_id_ == 0 && merge_status) { device_path = SUB_0_MERGE_STREAM_PATH; } else if (device_id_ == 0 && merge_status == 0) { device_path = SUB_0_STREAM_PATH; } tmpss = SUB_0_STREAM; break; default: HAL_LOGE("Failed to set stream device_path."); break; } if (connected(tmpss)) { HAL_LOGD("Camera stream %s is already connected.", device_path_.c_str()); ++connection_count_[tmpss]; return 0; } if (Support_Id == 1 && tmpss == MAIN_STREAM) { device_path = MAIN_FRONT_STREAM_PATH; } if (Support_Id == 1 && tmpss == SUB_0_STREAM) { device_path = SUB_0_FRONT_STREAM_PATH; } std::shared_ptr stream(V4L2Stream::NewV4L2Stream(device_id_, device_path, mCameraConfig, merge_status )); if (!stream) { HAL_LOGE("Failed to initialize stream helper."); return -1; } stream_connection[tmpss].reset(new ConnectionStream(stream, merge_status)); if (stream_connection[tmpss]->status()) { HAL_LOGE("Failed to connect to device: %d.", stream_connection[tmpss]->status()); return stream_connection[tmpss]->status(); } array_stream_obj[tmpss] = stream; ++connection_count_[tmpss]; return 0; } void V4L2Wrapper::Disconnect(STREAM_SERIAL ss) { HAL_LOG_ENTER(); std::lock_guard lock(connection_lock_); std::string device_path; STREAM_SERIAL tmpss = MAIN_STREAM; switch (ss) { case MAIN_STREAM: case MAIN_STREAM_BLOB: case MAIN_MIRROR_STREAM: case MAIN_MIRROR_STREAM_BLOB: //if (device_id_ == 0) { // device_path = MAIN_STREAM_PATH; //} tmpss = MAIN_STREAM; break; case SUB_0_STREAM: case SUB_0_STREAM_BLOB: case SUB_0_MIRROR_STREAM: case SUB_0_MIRROR_STREAM_BLOB: //if (device_id_ == 0) { // device_path = SUB_0_STREAM_PATH; //} tmpss = SUB_0_STREAM; break; default: HAL_LOGE("Failed to set stream device_path."); break; } if (connection_count_[tmpss] == 0) { // Not connected. HAL_LOGE("Camera device %s is not connected, cannot disconnect.", device_path_.c_str()); return; } //if (device_id_ == 1 && tmpss == MAIN_STREAM) { // device_path = MAIN_FRONT_STREAM_PATH; //} //if (device_id_ == 1 && tmpss == SUB_0_STREAM) { // device_path = SUB_0_FRONT_STREAM_PATH; //} --connection_count_[tmpss]; if (connection_count_[tmpss] > 0) { HAL_LOGV("Disconnected from camera device %s connections remain.", device_path_.c_str()); return; } stream_connection[tmpss].reset(); array_stream_obj[tmpss].reset(); device_fd_[MAIN_STREAM].reset(-1); // Includes close(). format_.reset(); buffers_.clear(); } } // namespace v4l2_camera_hal