1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "hstream_common.h"
17
18 #include <atomic>
19 #include <cstdint>
20 #include <mutex>
21 #include <set>
22 #include <string>
23
24 #include "camera_log.h"
25 #include "camera_util.h"
26 #include "display/graphic/common/v1_0/cm_color_space.h"
27 #include "display/composer/v1_1/display_composer_type.h"
28 #include "ipc_skeleton.h"
29 #include "camera_report_uitls.h"
30
31 namespace OHOS {
32 namespace CameraStandard {
33 using namespace OHOS::HDI::Camera::V1_0;
34 using namespace OHOS::HDI::Display::Graphic::Common::V1_0;
35 using namespace OHOS::HDI::Display::Composer::V1_1;
36 static const std::map<ColorSpace, CM_ColorSpaceType> g_fwkToMetaColorSpaceMap_ = {
37 {COLOR_SPACE_UNKNOWN, CM_COLORSPACE_NONE},
38 {DISPLAY_P3, CM_P3_FULL},
39 {SRGB, CM_SRGB_FULL},
40 {BT709, CM_BT709_FULL},
41 {BT2020_HLG, CM_BT2020_HLG_FULL},
42 {BT2020_PQ, CM_BT2020_PQ_FULL},
43 {P3_HLG, CM_P3_HLG_FULL},
44 {P3_PQ, CM_P3_PQ_FULL},
45 {DISPLAY_P3_LIMIT, CM_P3_LIMIT},
46 {SRGB_LIMIT, CM_SRGB_LIMIT},
47 {BT709_LIMIT, CM_BT709_LIMIT},
48 {BT2020_HLG_LIMIT, CM_BT2020_HLG_LIMIT},
49 {BT2020_PQ_LIMIT, CM_BT2020_PQ_LIMIT},
50 {P3_HLG_LIMIT, CM_P3_HLG_LIMIT},
51 {P3_PQ_LIMIT, CM_P3_PQ_LIMIT}
52 };
53 namespace {
54 static const int32_t STREAMID_BEGIN = 1;
55 static const int32_t CAPTUREID_BEGIN = 1;
56 static const int32_t STREAMID_MAX = INT32_MAX - 1000;
57 static const int32_t CAPTUREID_MAX = INT32_MAX - 1000;
58 static std::atomic<int32_t> g_currentStreamId = STREAMID_BEGIN;
59
60 static std::atomic_int32_t g_currentCaptureId = CAPTUREID_BEGIN;
61
GenerateStreamId()62 static int32_t GenerateStreamId()
63 {
64 int newId = g_currentStreamId++;
65 if (newId == STREAMID_MAX) {
66 g_currentStreamId = STREAMID_BEGIN;
67 }
68 return newId;
69 }
70
GenerateCaptureId()71 static int32_t GenerateCaptureId()
72 {
73 int32_t newId = g_currentCaptureId++;
74 if (newId == CAPTUREID_MAX) {
75 g_currentCaptureId = CAPTUREID_BEGIN;
76 }
77 return newId;
78 }
79 } // namespace
80
HStreamCommon(StreamType streamType,sptr<OHOS::IBufferProducer> producer,int32_t format,int32_t width,int32_t height)81 HStreamCommon::HStreamCommon(
82 StreamType streamType, sptr<OHOS::IBufferProducer> producer, int32_t format, int32_t width, int32_t height)
83 : format_(format), width_(width), height_(height), producer_(producer), streamType_(streamType)
84 {
85 MEDIA_DEBUG_LOG("Enter Into HStreamCommon::HStreamCommon");
86 callerToken_ = IPCSkeleton::GetCallingTokenID();
87 const int32_t metaStreamId = -1;
88 fwkStreamId_ = streamType == StreamType::METADATA ? metaStreamId : GenerateStreamId();
89 MEDIA_DEBUG_LOG("HStreamCommon Create streamId:%{public}d type:%{public}d width:%{public}d height:%{public}d"
90 " format:%{public}d ",
91 fwkStreamId_, streamType_, width_, height_, format_);
92 }
93
~HStreamCommon()94 HStreamCommon::~HStreamCommon()
95 {
96 MEDIA_DEBUG_LOG("Enter Into HStreamCommon::~HStreamCommon streamId is:%{public}d, streamType is:%{public}d",
97 fwkStreamId_, streamType_);
98 streamOperator_ = nullptr;
99 }
100
SetColorSpace(ColorSpace colorSpace)101 void HStreamCommon::SetColorSpace(ColorSpace colorSpace)
102 {
103 auto itr = g_fwkToMetaColorSpaceMap_.find(colorSpace);
104 if (itr != g_fwkToMetaColorSpaceMap_.end()) {
105 dataSpace_ = itr->second;
106 } else {
107 MEDIA_ERR_LOG("HStreamCommon::SetColorSpace, %{public}d failed", static_cast<int32_t>(colorSpace));
108 }
109 }
110
LinkInput(wptr<OHOS::HDI::Camera::V1_0::IStreamOperator> streamOperator,std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility)111 int32_t HStreamCommon::LinkInput(wptr<OHOS::HDI::Camera::V1_0::IStreamOperator> streamOperator,
112 std::shared_ptr<OHOS::Camera::CameraMetadata> cameraAbility)
113 {
114 CHECK_ERROR_RETURN_RET_LOG(streamOperator == nullptr || cameraAbility == nullptr, CAMERA_INVALID_ARG,
115 "HStreamCommon::LinkInput streamOperator is null");
116 SetStreamOperator(streamOperator);
117 std::lock_guard<std::mutex> lock(cameraAbilityLock_);
118 cameraAbility_ = cameraAbility;
119 return CAMERA_OK;
120 }
121
UnlinkInput()122 int32_t HStreamCommon::UnlinkInput()
123 {
124 MEDIA_INFO_LOG("HStreamCommon::UnlinkInput streamType:%{public}d, streamId:%{public}d, hidStreamId:%{public}d",
125 streamType_, fwkStreamId_, hdiStreamId_);
126 StopStream();
127 SetStreamOperator(nullptr);
128 hdiStreamId_ = STREAM_ID_UNSET;
129 return CAMERA_OK;
130 }
131
StopStream()132 int32_t HStreamCommon::StopStream()
133 {
134 CAMERA_SYNC_TRACE;
135 MEDIA_INFO_LOG("HStreamCommon::StopStream streamType:%{public}d, streamId:%{public}d, hdiStreamId:%{public}d, "
136 "captureId:%{public}d", streamType_, fwkStreamId_, hdiStreamId_, curCaptureID_);
137 auto streamOperator = GetStreamOperator();
138 if (streamOperator == nullptr) {
139 MEDIA_DEBUG_LOG("HStreamCommon::StopStream streamOperator is nullptr");
140 return CAMERA_OK;
141 }
142
143 if (curCaptureID_ != CAPTURE_ID_UNSET) {
144 CamRetCode rc = (CamRetCode)(streamOperator->CancelCapture(curCaptureID_));
145 CHECK_ERROR_PRINT_LOG(rc != CamRetCode::NO_ERROR,
146 "HStreamCommon::StopStream streamOperator->CancelCapture get error code:%{public}d", rc);
147 ResetCaptureId();
148 return HdiToServiceError(rc);
149 }
150 return CAMERA_OK;
151 }
152
PrepareCaptureId()153 int32_t HStreamCommon::PrepareCaptureId()
154 {
155 curCaptureID_ = GenerateCaptureId();
156 captureIdForConfirmCapture_ = curCaptureID_;
157 return CAMERA_OK;
158 }
159
ResetCaptureId()160 void HStreamCommon::ResetCaptureId()
161 {
162 curCaptureID_ = CAPTURE_ID_UNSET;
163 }
164
GetPreparedCaptureId()165 int32_t HStreamCommon::GetPreparedCaptureId()
166 {
167 return curCaptureID_;
168 }
169
SetStreamInfo(StreamInfo_V1_1 & streamInfo)170 void HStreamCommon::SetStreamInfo(StreamInfo_V1_1 &streamInfo)
171 {
172 int32_t pixelFormat = OHOS::HDI::Display::Composer::V1_1::PIXEL_FMT_YCRCB_420_SP;
173 auto it = g_cameraToPixelFormat.find(format_);
174 if (it != g_cameraToPixelFormat.end()) {
175 pixelFormat = it->second;
176 } else {
177 MEDIA_ERR_LOG("HStreamCommon::SetStreamInfo find format error, pixelFormat use default format");
178 }
179 MEDIA_DEBUG_LOG("HStreamCommon::SetStreamInfo pixelFormat:%{public}d type:%{public}d colorSpace:%{public}d",
180 pixelFormat, streamType_, dataSpace_);
181 streamInfo.v1_0.streamId_ = hdiStreamId_;
182 streamInfo.v1_0.width_ = width_;
183 streamInfo.v1_0.height_ = height_;
184 streamInfo.v1_0.format_ = pixelFormat;
185 streamInfo.v1_0.dataspace_ = dataSpace_;
186 streamInfo.v1_0.minFrameDuration_ = 0;
187 streamInfo.v1_0.tunneledMode_ = true;
188 {
189 std::lock_guard<std::mutex> lock(producerLock_);
190 if (producer_ != nullptr) {
191 MEDIA_DEBUG_LOG("HStreamCommon:producer is not null");
192 streamInfo.v1_0.bufferQueue_ = new BufferProducerSequenceable(producer_);
193 } else {
194 streamInfo.v1_0.bufferQueue_ = nullptr;
195 }
196 }
197 streamInfo.extendedStreamInfos = {};
198 }
199
ReleaseStream(bool isDelay)200 int32_t HStreamCommon::ReleaseStream(bool isDelay)
201 {
202 MEDIA_INFO_LOG("Enter Into HStreamCommon::Release streamId is:%{public}d, hdiStreamId is:%{public}d, streamType "
203 "is:%{public}d, isDelay:%{public}d",
204 fwkStreamId_, hdiStreamId_, streamType_, isDelay);
205 StopStream();
206 if (!isDelay && hdiStreamId_ != STREAM_ID_UNSET) {
207 auto streamOperator = GetStreamOperator();
208 if (streamOperator != nullptr) {
209 streamOperator->ReleaseStreams({ hdiStreamId_ });
210 }
211 }
212 fwkStreamId_ = STREAM_ID_UNSET;
213 hdiStreamId_ = STREAM_ID_UNSET;
214 SetStreamOperator(nullptr);
215 {
216 std::lock_guard<std::mutex> lock(cameraAbilityLock_);
217 cameraAbility_ = nullptr;
218 }
219 {
220 std::lock_guard<std::mutex> lock(producerLock_);
221 producer_ = nullptr;
222 }
223 return CAMERA_OK;
224 }
225
DumpStreamInfo(CameraInfoDumper & infoDumper)226 void HStreamCommon::DumpStreamInfo(CameraInfoDumper& infoDumper)
227 {
228 StreamInfo_V1_1 curStreamInfo;
229 SetStreamInfo(curStreamInfo);
230 std::string streamInfo = "Buffer producer Id:";
231 {
232 std::lock_guard<std::mutex> lock(producerLock_);
233 if (curStreamInfo.v1_0.bufferQueue_ && curStreamInfo.v1_0.bufferQueue_->producer_) {
234 streamInfo.append("[" + std::to_string(curStreamInfo.v1_0.bufferQueue_->producer_->GetUniqueId()) + "]");
235 } else {
236 streamInfo.append("[empty]");
237 }
238 }
239 streamInfo.append(" stream Id:[" + std::to_string(curStreamInfo.v1_0.streamId_) + "]");
240 std::map<int, std::string>::const_iterator iter = g_cameraFormat.find(format_);
241 CHECK_EXECUTE(iter != g_cameraFormat.end(), streamInfo.append(" format:[" + iter->second + "]"));
242 streamInfo.append(" width:[" + std::to_string(curStreamInfo.v1_0.width_) + "]");
243 streamInfo.append(" height:[" + std::to_string(curStreamInfo.v1_0.height_) + "]");
244 streamInfo.append(" dataspace:[" + std::to_string(curStreamInfo.v1_0.dataspace_) + "]");
245 streamInfo.append(" StreamType:[" + std::to_string(curStreamInfo.v1_0.intent_) + "]");
246 streamInfo.append(" TunnelMode:[" + std::to_string(curStreamInfo.v1_0.tunneledMode_) + "]");
247 streamInfo.append(" Encoding Type:[" + std::to_string(curStreamInfo.v1_0.encodeType_) + "]");
248
249 infoDumper.Msg(streamInfo);
250 infoDumper.Push();
251 infoDumper.Title("Stream Extened Info");
252 for (auto& extInfo : curStreamInfo.extendedStreamInfos) {
253 auto bufferQueue = extInfo.bufferQueue;
254 infoDumper.Msg("type:" + std::to_string(static_cast<int32_t>(extInfo.type)) +
255 " width:" + std::to_string(static_cast<int32_t>(extInfo.width)) +
256 " height:" + std::to_string(static_cast<int32_t>(extInfo.height)) +
257 " format:" + std::to_string(static_cast<int32_t>(extInfo.format)) +
258 " dataspace:" + std::to_string(static_cast<int32_t>(extInfo.dataspace)) +
259 " producer:" + ((bufferQueue == nullptr || bufferQueue->producer_ == nullptr)
260 ? "empty"
261 : std::to_string(bufferQueue->producer_->GetUniqueId())));
262 }
263 infoDumper.Pop();
264 }
265
PrintCaptureDebugLog(const std::shared_ptr<OHOS::Camera::CameraMetadata> & captureMetadataSetting_)266 void HStreamCommon::PrintCaptureDebugLog(const std::shared_ptr<OHOS::Camera::CameraMetadata> &captureMetadataSetting_)
267 {
268 CHECK_ERROR_RETURN_LOG(captureMetadataSetting_ == nullptr,
269 "HStreamCapture::PrintCaptureDebugLog captureMetadataSetting_ is nullptr");
270 camera_metadata_item_t item;
271 int result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_QUALITY, &item);
272 if (result != CAM_META_SUCCESS) {
273 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_JPEG_QUALITY tag");
274 } else {
275 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_JPEG_QUALITY value = %{public}d", item.data.u8[0]);
276 CameraReportUtils::GetInstance().UpdateImagingInfo(DFX_PHOTO_SETTING_QUALITY, std::to_string(item.data.u8[0]));
277 }
278
279 // debug log for capture mirror
280 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_CONTROL_CAPTURE_MIRROR, &item);
281 if (result != CAM_META_SUCCESS) {
282 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_CONTROL_CAPTURE_MIRROR tag");
283 } else {
284 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_CONTROL_CAPTURE_MIRROR value = %{public}d", item.data.u8[0]);
285 CameraReportUtils::GetInstance().UpdateImagingInfo(DFX_PHOTO_SETTING_MIRROR, std::to_string(item.data.u8[0]));
286 }
287
288 // debug log for image rotation
289 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_JPEG_ORIENTATION, &item);
290 if (result != CAM_META_SUCCESS) {
291 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_JPEG_ORIENTATION tag");
292 } else {
293 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_JPEG_ORIENTATION value = %{public}d", item.data.i32[0]);
294 CameraReportUtils::GetInstance().UpdateImagingInfo(DFX_PHOTO_SETTING_ROTATION,
295 std::to_string(item.data.i32[0]));
296 }
297
298 // debug log for video frame rate range
299 CallerInfo caller = CameraReportUtils::GetCallerInfo();
300 result = OHOS::Camera::FindCameraMetadataItem(captureMetadataSetting_->get(), OHOS_CONTROL_FPS_RANGES, &item);
301 if (result != CAM_META_SUCCESS) {
302 MEDIA_DEBUG_LOG("HStreamCapture::Failed to find OHOS_CONTROL_FPS_RANGES tag");
303 } else {
304 MEDIA_DEBUG_LOG("HStreamCapture::find OHOS_CONTROL_FPS_RANGES value = %{public}d",
305 item.data.i32[0]);
306 CameraReportUtils::GetInstance().ReportUserBehavior(DFX_UB_SET_FRAMERATERANGE,
307 std::to_string(item.data.i32[0]), caller);
308 }
309 }
310 } // namespace CameraStandard
311 } // namespace OHOS
312