1 /*
2 * Copyright (c) 2025 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 #include "photo_asset_auxiliary_consumer.h"
16
17 #include "camera_log.h"
18 #include "hstream_capture.h"
19 #include "task_manager.h"
20 #include "camera_surface_buffer_util.h"
21 #include "dp_utils.h"
22 #include "buffer_extra_data_impl.h"
23
24 namespace OHOS {
25 namespace CameraStandard {
26
AuxiliaryBufferConsumer(const std::string surfaceName,wptr<HStreamCapture> streamCapture)27 AuxiliaryBufferConsumer::AuxiliaryBufferConsumer(const std::string surfaceName, wptr<HStreamCapture> streamCapture)
28 : surfaceName_(surfaceName), streamCapture_(streamCapture)
29 {
30 MEDIA_INFO_LOG("AuxiliaryBufferConsumer new E, surfaceName:%{public}s", surfaceName_.c_str());
31 }
32
~AuxiliaryBufferConsumer()33 AuxiliaryBufferConsumer::~AuxiliaryBufferConsumer()
34 {
35 MEDIA_INFO_LOG("AuxiliaryBufferConsumer ~ E, surfaceName:%{public}s", surfaceName_.c_str());
36 }
37
OnBufferAvailable()38 void AuxiliaryBufferConsumer::OnBufferAvailable()
39 {
40 MEDIA_INFO_LOG("OnBufferAvailable E, surfaceName:%{public}s", surfaceName_.c_str());
41 sptr<HStreamCapture> streamCapture = streamCapture_.promote();
42 CHECK_RETURN_ELOG(streamCapture == nullptr, "streamCapture is null");
43 CHECK_RETURN_ELOG(streamCapture->photoSubTask_ == nullptr, "photoSubTask is null");
44 wptr<AuxiliaryBufferConsumer> thisPtr(this);
45 streamCapture->photoSubTask_->SubmitTask([thisPtr]() {
46 auto listener = thisPtr.promote();
47 CHECK_EXECUTE(listener, listener->ExecuteOnBufferAvailable());
48 });
49
50 MEDIA_INFO_LOG("OnBufferAvailable X");
51 }
52
ExecuteOnBufferAvailable()53 void AuxiliaryBufferConsumer::ExecuteOnBufferAvailable()
54 {
55 MEDIA_INFO_LOG("A_ExecuteOnBufferAvailable E, surfaceName:%{public}s", surfaceName_.c_str());
56 CAMERA_SYNC_TRACE;
57 sptr<HStreamCapture> streamCapture = streamCapture_.promote();
58 CHECK_RETURN_ELOG(streamCapture == nullptr, "streamCapture is null");
59 sptr<Surface> surface;
60 if (surfaceName_ == S_GAINMAP) {
61 surface = streamCapture->gainmapSurface_;
62 } else if (surfaceName_ == S_DEEP) {
63 surface = streamCapture->deepSurface_;
64 } else if (surfaceName_ == S_EXIF) {
65 surface = streamCapture->exifSurface_;
66 } else if (surfaceName_ == S_DEBUG) {
67 surface = streamCapture->debugSurface_;
68 }
69 // acquire copy release buffer
70 sptr<SurfaceBuffer> surfaceBuffer = nullptr;
71 int32_t fence = -1;
72 int64_t timestamp;
73 OHOS::Rect damage;
74 SurfaceError surfaceRet = surface->AcquireBuffer(surfaceBuffer, fence, timestamp, damage);
75 MEDIA_INFO_LOG("AuxiliaryBufferConsumer surfaceName = %{public}s AcquireBuffer end", surfaceName_.c_str());
76 if (surfaceRet != SURFACE_ERROR_OK) {
77 MEDIA_ERR_LOG("AuxiliaryBufferConsumer Failed to acquire surface buffer");
78 }
79 sptr<SurfaceBuffer> newSurfaceBuffer = CameraSurfaceBufferUtil::DeepCopyBuffer(surfaceBuffer);
80 surface->ReleaseBuffer(surfaceBuffer, -1);
81 CHECK_RETURN_ELOG(newSurfaceBuffer == nullptr, "newSurfaceBuffer is null");
82 if (surfaceName_ == S_EXIF) {
83 int32_t dataSize = CameraSurfaceBufferUtil::GetDataSize(newSurfaceBuffer);
84 sptr<BufferExtraData> extraData = newSurfaceBuffer->GetExtraData();
85 extraData->ExtraSet("exifDataSize", dataSize);
86 newSurfaceBuffer->SetExtraData(extraData);
87 MEDIA_INFO_LOG("AuxiliaryBufferConsumer exifDataSize = %{public}d", dataSize);
88 }
89
90 int32_t captureId = CameraSurfaceBufferUtil::GetMaskCaptureId(newSurfaceBuffer);
91 MEDIA_INFO_LOG("AuxiliaryBufferConsumer captureId:%{public}d", captureId);
92 {
93 std::lock_guard<std::mutex> lock(streamCapture->g_photoImageMutex);
94 if (streamCapture->captureIdAuxiliaryCountMap_.count(captureId)) {
95 int32_t auxiliaryCount = streamCapture->captureIdAuxiliaryCountMap_[captureId];
96 int32_t expectCount = streamCapture->captureIdCountMap_[captureId];
97 // AuxiliaryBuffer unexpected
98 if (auxiliaryCount == -1 || (expectCount != 0 && auxiliaryCount == expectCount)) {
99 MEDIA_INFO_LOG("AuxiliaryBufferConsumer ReleaseBuffer, captureId=%{public}d", captureId);
100 return;
101 }
102 }
103 // cache buffer and check assemble
104 streamCapture->captureIdAuxiliaryCountMap_[captureId]++;
105 if (surfaceName_ == S_GAINMAP) {
106 streamCapture->captureIdGainmapMap_[captureId] = newSurfaceBuffer;
107 MEDIA_INFO_LOG("AuxiliaryBufferConsumer gainmapSurfaceBuffer_, captureId=%{public}d", captureId);
108 } else if (surfaceName_ == S_DEEP) {
109 streamCapture->captureIdDepthMap_.EnsureInsert(captureId, newSurfaceBuffer);
110 MEDIA_INFO_LOG("AuxiliaryBufferConsumer deepSurfaceBuffer_, captureId=%{public}d", captureId);
111 } else if (surfaceName_ == S_EXIF) {
112 streamCapture->captureIdExifMap_[captureId] = newSurfaceBuffer;
113 MEDIA_INFO_LOG("AuxiliaryBufferConsumer exifSurfaceBuffer_, captureId=%{public}d", captureId);
114 } else if (surfaceName_ == S_DEBUG) {
115 streamCapture->captureIdDebugMap_[captureId] = newSurfaceBuffer;
116 MEDIA_INFO_LOG("AuxiliaryBufferConsumer debugSurfaceBuffer_, captureId=%{public}d", captureId);
117 }
118 MEDIA_INFO_LOG("AuxiliaryBufferConsumer auxiliaryPhotoCount = %{public}d, captureCount = %{public}d, "
119 "surfaceName=%{public}s, captureId=%{public}d",
120 streamCapture->captureIdAuxiliaryCountMap_[captureId], streamCapture->captureIdCountMap_[captureId],
121 surfaceName_.c_str(), captureId);
122 if (streamCapture->captureIdCountMap_[captureId] != 0 &&
123 streamCapture->captureIdAuxiliaryCountMap_[captureId] == streamCapture->captureIdCountMap_[captureId]) {
124 uint32_t pictureHandle = streamCapture->captureIdHandleMap_[captureId];
125 MEDIA_INFO_LOG("AuxiliaryBufferConsumer StopMonitor, surfaceName=%{public}s, pictureHandle = %{public}d, "
126 "captureId = %{public}d",
127 surfaceName_.c_str(), pictureHandle, captureId);
128 DeferredProcessing::GetGlobalWatchdog().DoTimeout(pictureHandle);
129 DeferredProcessing::GetGlobalWatchdog().StopMonitor(pictureHandle);
130 streamCapture->captureIdAuxiliaryCountMap_[captureId] = -1;
131 MEDIA_INFO_LOG("AuxiliaryBufferConsumer captureIdAuxiliaryCountMap_ = -1");
132 }
133 }
134 MEDIA_INFO_LOG("A_ExecuteOnBufferAvailable X");
135 }
136 } // namespace CameraStandard
137 } // namespace OHOS