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 "avcodec/common/frame_record.h"
17
18 #include "moving_photo/moving_photo_surface_wrapper.h"
19
20 namespace OHOS {
21 namespace CameraStandard {
22
FrameRecord(sptr<SurfaceBuffer> videoBuffer,int64_t timestamp,GraphicTransformType type)23 FrameRecord::FrameRecord(sptr<SurfaceBuffer> videoBuffer, int64_t timestamp, GraphicTransformType type)
24 : videoBuffer_(videoBuffer), timestamp_(timestamp), transformType_(type)
25 {
26 frameId_ = std::to_string(timestamp);
27 size = make_shared<Size>();
28 size->width = static_cast<uint32_t>(videoBuffer->GetSurfaceBufferWidth());
29 size->height = static_cast<uint32_t>(videoBuffer->GetSurfaceBufferHeight());
30 bufferSize = videoBuffer->GetSize();
31 format = videoBuffer->GetFormat();
32 usage = videoBuffer->GetUsage();
33 }
34
~FrameRecord()35 FrameRecord::~FrameRecord()
36 {
37 MEDIA_DEBUG_LOG("FrameRecord::~FrameRecord");
38 if (encodedBuffer) {
39 OH_AVBuffer_Destroy(encodedBuffer);
40 }
41 encodedBuffer = nullptr;
42 }
43
ReleaseSurfaceBuffer(sptr<MovingPhotoSurfaceWrapper> surfaceWrapper)44 void FrameRecord::ReleaseSurfaceBuffer(sptr<MovingPhotoSurfaceWrapper> surfaceWrapper)
45 {
46 std::unique_lock<std::mutex> lock(mutex_);
47 if (IsReadyConvert()) {
48 MEDIA_DEBUG_LOG("FrameRecord::ReleaseSurfaceBuffer isReadyConvert");
49 auto thisPtr = sptr<FrameRecord>(this);
50 canReleased_.wait_for(lock, std::chrono::milliseconds(BUFFER_RELEASE_EXPIREATION_TIME),
51 [thisPtr] { return thisPtr->IsFinishCache(); });
52 MEDIA_DEBUG_LOG("FrameRecord::ReleaseSurfaceBuffer wait end");
53 }
54 if (videoBuffer_) {
55 if (surfaceWrapper != nullptr) {
56 surfaceWrapper->RecycleBuffer(videoBuffer_);
57 }
58 videoBuffer_ = nullptr;
59 MEDIA_DEBUG_LOG("release buffer end %{public}s", frameId_.c_str());
60 }
61 }
62
ReleaseMetaBuffer(sptr<Surface> surface,bool reuse)63 void FrameRecord::ReleaseMetaBuffer(sptr<Surface> surface, bool reuse)
64 {
65 std::unique_lock<std::mutex> lock(metaBufferMutex_);
66 sptr<SurfaceBuffer> buffer = nullptr;
67 if (status != STATUS_NONE && metaBuffer_) {
68 buffer = SurfaceBuffer::Create();
69 DeepCopyBuffer(buffer, metaBuffer_);
70 }
71 if (metaBuffer_) {
72 if (reuse) {
73 SurfaceError surfaceRet = surface->AttachBufferToQueue(metaBuffer_);
74 if (surfaceRet != SURFACE_ERROR_OK) {
75 MEDIA_ERR_LOG("Failed to attach meta buffer %{public}d", surfaceRet);
76 return;
77 }
78 surfaceRet = surface->ReleaseBuffer(metaBuffer_, -1);
79 if (surfaceRet != SURFACE_ERROR_OK) {
80 MEDIA_ERR_LOG("Failed to Release meta Buffer %{public}d", surfaceRet);
81 return;
82 }
83 }
84 metaBuffer_ = buffer;
85 MEDIA_DEBUG_LOG("release meta buffer end %{public}s", frameId_.c_str());
86 }
87 }
88
NotifyBufferRelease()89 void FrameRecord::NotifyBufferRelease()
90 {
91 MEDIA_DEBUG_LOG("notifyBufferRelease");
92 status = STATUS_FINISH_ENCODE;
93 canReleased_.notify_one();
94 }
95
DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer,sptr<SurfaceBuffer> surfaceBuffer) const96 void FrameRecord::DeepCopyBuffer(sptr<SurfaceBuffer> newSurfaceBuffer, sptr<SurfaceBuffer> surfaceBuffer) const
97 {
98 BufferRequestConfig requestConfig = {
99 .width = surfaceBuffer->GetWidth(),
100 .height = surfaceBuffer->GetHeight(),
101 .strideAlignment = 0x8, // default stride is 8 Bytes.
102 .format = surfaceBuffer->GetFormat(),
103 .usage = surfaceBuffer->GetUsage(),
104 .timeout = 0,
105 .colorGamut = surfaceBuffer->GetSurfaceBufferColorGamut(),
106 .transform = surfaceBuffer->GetSurfaceBufferTransform(),
107 };
108 auto allocErrorCode = newSurfaceBuffer->Alloc(requestConfig);
109 if (allocErrorCode != GSERROR_OK) {
110 MEDIA_ERR_LOG("SurfaceBuffer alloc ret: %d", allocErrorCode);
111 return;
112 }
113 if (memcpy_s(newSurfaceBuffer->GetVirAddr(), newSurfaceBuffer->GetSize(),
114 surfaceBuffer->GetVirAddr(), surfaceBuffer->GetSize()) != EOK) {
115 MEDIA_ERR_LOG("SurfaceBuffer memcpy_s failed");
116 }
117 }
118 } // namespace CameraStandard
119 } // namespace OHOS