1 /*
2 * Copyright (c) 2024-2024 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 "moving_photo/moving_photo_surface_wrapper.h"
17
18 #include <memory>
19 #include <mutex>
20 #include <new>
21
22 #include "camera_log.h"
23 #include "graphic_common_c.h"
24 #include "surface_type.h"
25 #include "sync_fence.h"
26
27 namespace OHOS {
28 namespace CameraStandard {
CreateMovingPhotoSurfaceWrapper(int32_t width,int32_t height)29 sptr<MovingPhotoSurfaceWrapper> MovingPhotoSurfaceWrapper::CreateMovingPhotoSurfaceWrapper(
30 int32_t width, int32_t height)
31 {
32 CHECK_ERROR_RETURN_RET_LOG(width <= 0 || height <= 0, nullptr,
33 "CreateMovingPhotoSurfaceWrapper size invalid, width:%{public}d, height:%{public}d", width, height);
34 sptr<MovingPhotoSurfaceWrapper> movingPhotoSurfaceWrapper = new (std::nothrow) MovingPhotoSurfaceWrapper();
35 CHECK_ERROR_RETURN_RET_LOG(movingPhotoSurfaceWrapper == nullptr, nullptr,
36 "MovingPhotoSurfaceWrapper::CreateMovingPhotoSurfaceWrapper fail.");
37 bool initResult = movingPhotoSurfaceWrapper->Init(width, height);
38 if (initResult) {
39 return movingPhotoSurfaceWrapper;
40 }
41 MEDIA_ERR_LOG("MovingPhotoSurfaceWrapper::CreateMovingPhotoSurfaceWrapper init fail.");
42 return nullptr;
43 }
44
~MovingPhotoSurfaceWrapper()45 MovingPhotoSurfaceWrapper::~MovingPhotoSurfaceWrapper()
46 {
47 MEDIA_INFO_LOG("MovingPhotoSurfaceWrapper::~MovingPhotoSurfaceWrapper");
48 }
49
GetProducer() const50 sptr<OHOS::IBufferProducer> MovingPhotoSurfaceWrapper::GetProducer() const
51 {
52 std::lock_guard<std::recursive_mutex> lock(videoSurfaceMutex_);
53 CHECK_ERROR_RETURN_RET(videoSurface_ == nullptr, nullptr);
54 return videoSurface_->GetProducer();
55 }
56
Init(int32_t width,int32_t height)57 bool MovingPhotoSurfaceWrapper::Init(int32_t width, int32_t height)
58 {
59 std::lock_guard<std::recursive_mutex> lock(videoSurfaceMutex_);
60 videoSurface_ = Surface::CreateSurfaceAsConsumer("movingPhoto");
61 CHECK_ERROR_RETURN_RET_LOG(videoSurface_ == nullptr, false, "Init create surface fail.");
62
63 auto err = videoSurface_->SetDefaultUsage(BUFFER_USAGE_VIDEO_ENCODER);
64 CHECK_ERROR_RETURN_RET_LOG(err != GSERROR_OK, false, "MovingPhotoSurfaceWrapper::Init SetDefaultUsage fail.");
65
66 bufferConsumerListener_ = new (std::nothrow) BufferConsumerListener(this);
67 CHECK_ERROR_RETURN_RET_LOG(bufferConsumerListener_ == nullptr, false, "New bufferConsumerListener failed.");
68
69 err = videoSurface_->RegisterConsumerListener(bufferConsumerListener_);
70 CHECK_ERROR_RETURN_RET_LOG(err != GSERROR_OK, false, "Init RegisterConsumerListener fail.");
71
72 err = videoSurface_->SetDefaultWidthAndHeight(width, height);
73 CHECK_ERROR_RETURN_RET_LOG(err != GSERROR_OK, false, "Init SetDefaultWidthAndHeight fail.");
74
75 return true;
76 }
77
OnBufferArrival()78 void MovingPhotoSurfaceWrapper::OnBufferArrival()
79 {
80 std::lock_guard<std::recursive_mutex> lock(videoSurfaceMutex_);
81 CHECK_ERROR_RETURN_LOG(videoSurface_ == nullptr, "MovingPhotoSurfaceWrapper::OnBufferArrival surface is nullptr");
82 auto transform = videoSurface_->GetTransform();
83 MEDIA_DEBUG_LOG("MovingPhotoSurfaceWrapper::OnBufferArrival queueSize %{public}u, transform %{public}d",
84 videoSurface_->GetQueueSize(), transform);
85
86 int64_t timestamp;
87 OHOS::Rect damage;
88 sptr<SurfaceBuffer> buffer;
89 sptr<SyncFence> syncFence = SyncFence::INVALID_FENCE;
90 GSError err = videoSurface_->AcquireBuffer(buffer, syncFence, timestamp, damage);
91 CHECK_ERROR_RETURN_LOG(err != GSERROR_OK, "Failed to acquire surface buffer");
92
93 auto surfaceBufferListener = GetSurfaceBufferListener();
94 if (surfaceBufferListener == nullptr) {
95 MEDIA_DEBUG_LOG("MovingPhotoSurfaceWrapper::OnBufferArrival surfaceBufferListener_ is nullptr.");
96 err = videoSurface_->ReleaseBuffer(buffer, SyncFence::INVALID_FENCE);
97 CHECK_ERROR_PRINT_LOG(err != GSERROR_OK,
98 "MovingPhotoSurfaceWrapper::OnBufferArrival ReleaseBuffer fail.");
99 return;
100 }
101
102 err = videoSurface_->DetachBufferFromQueue(buffer);
103 CHECK_ERROR_RETURN_LOG(err != GSERROR_OK,
104 "MovingPhotoSurfaceWrapper::OnBufferArrival detach buffer fail. %{public}d", err);
105
106 MEDIA_DEBUG_LOG("MovingPhotoSurfaceWrapper::OnBufferArrival buffer %{public}d x %{public}d, stride is %{public}d",
107 buffer->GetSurfaceBufferWidth(), buffer->GetSurfaceBufferHeight(), buffer->GetStride());
108 surfaceBufferListener->OnBufferArrival(buffer, timestamp, transform);
109 }
110
BufferConsumerListener(sptr<MovingPhotoSurfaceWrapper> surfaceWrapper)111 MovingPhotoSurfaceWrapper::BufferConsumerListener::BufferConsumerListener(
112 sptr<MovingPhotoSurfaceWrapper> surfaceWrapper)
113 : movingPhotoSurfaceWrapper_(surfaceWrapper)
114 {}
115
OnBufferAvailable()116 void MovingPhotoSurfaceWrapper::BufferConsumerListener::OnBufferAvailable()
117 {
118 auto surfaceWrapper = movingPhotoSurfaceWrapper_.promote();
119 if (surfaceWrapper != nullptr) {
120 surfaceWrapper->OnBufferArrival();
121 }
122 }
123
RecycleBuffer(sptr<SurfaceBuffer> buffer)124 void MovingPhotoSurfaceWrapper::RecycleBuffer(sptr<SurfaceBuffer> buffer)
125 {
126 std::lock_guard<std::recursive_mutex> lock(videoSurfaceMutex_);
127
128 GSError err = videoSurface_->AttachBufferToQueue(buffer);
129 CHECK_ERROR_RETURN_LOG(err != GSERROR_OK, "Failed to attach buffer %{public}d", err);
130 err = videoSurface_->ReleaseBuffer(buffer, SyncFence::INVALID_FENCE);
131 CHECK_ERROR_RETURN_LOG(err != GSERROR_OK, "Failed to Release buffer %{public}d", err);
132 }
133 } // namespace CameraStandard
134 } // namespace OHOS