• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2023 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 <memory>
17 #include "securec.h"
18 #include "avcodec_log.h"
19 #include "avcodec_errors.h"
20 #include "fsurface_memory.h"
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AvCodec-FSurfaceMemory"};
23 }
24 namespace OHOS {
25 namespace MediaAVCodec {
26 sptr<Surface> FSurfaceMemory::surface_ = nullptr;
27 BufferRequestConfig FSurfaceMemory::requestConfig_ = {0};
28 ScalingMode FSurfaceMemory::scalingMode_ = {ScalingMode::SCALING_MODE_SCALE_TO_WINDOW};
29 
30 
Create()31 std::shared_ptr<FSurfaceMemory> FSurfaceMemory::Create()
32 {
33     CHECK_AND_RETURN_RET_LOG(surface_ != nullptr, nullptr, "surface is nullptr");
34     CHECK_AND_RETURN_RET_LOG(requestConfig_.width != 0 && requestConfig_.height != 0, nullptr,
35                              "surface config invalid");
36     std::shared_ptr<FSurfaceMemory> buffer = std::make_shared<FSurfaceMemory>();
37     buffer->AllocSurfaceBuffer();
38     return buffer;
39 }
40 
~FSurfaceMemory()41 FSurfaceMemory::~FSurfaceMemory()
42 {
43     ReleaseSurfaceBuffer();
44 }
45 
AllocSurfaceBuffer()46 void FSurfaceMemory::AllocSurfaceBuffer()
47 {
48     if (surface_ == nullptr || surfaceBuffer_ != nullptr) {
49         AVCODEC_LOGE("surface is nullptr or surfaceBuffer is not nullptr");
50         return;
51     }
52     fence_ = -1;
53     sptr<SurfaceBuffer> surfaceBuffer = nullptr;
54     auto ret = surface_->RequestBuffer(surfaceBuffer, fence_, requestConfig_);
55     if (ret != OHOS::SurfaceError::SURFACE_ERROR_OK || surfaceBuffer == nullptr) {
56         if (ret == OHOS::SurfaceError::SURFACE_ERROR_NO_BUFFER) {
57             AVCODEC_LOGD("buffer queue is no more buffers");
58         } else {
59             AVCODEC_LOGE("surface RequestBuffer fail, ret: %{public}" PRIu64, static_cast<uint64_t>(ret));
60         }
61         return;
62     }
63 
64     surfaceBuffer_ = surfaceBuffer;
65     AVCODEC_LOGD("request surface buffer success, releaseFence: %{public}d", fence_);
66 }
67 
ReleaseSurfaceBuffer()68 void FSurfaceMemory::ReleaseSurfaceBuffer()
69 {
70     if (surfaceBuffer_ == nullptr) {
71         return;
72     }
73     if (!needRender_) {
74         auto ret = surface_->CancelBuffer(surfaceBuffer_);
75         if (ret != OHOS::SurfaceError::SURFACE_ERROR_OK) {
76             AVCODEC_LOGE("surface CancelBuffer fail, ret:  %{public}" PRIu64, static_cast<uint64_t>(ret));
77         }
78     }
79     surfaceBuffer_ = nullptr;
80 }
81 
GetSurfaceBuffer()82 sptr<SurfaceBuffer> FSurfaceMemory::GetSurfaceBuffer()
83 {
84     if (!surfaceBuffer_) {
85         // request surface buffer again when old buffer flush to nullptr
86         AllocSurfaceBuffer();
87     }
88     return surfaceBuffer_;
89 }
90 
GetSurfaceBufferStride()91 int32_t FSurfaceMemory::GetSurfaceBufferStride()
92 {
93     CHECK_AND_RETURN_RET_LOG(surfaceBuffer_ != nullptr, 0, "surfaceBuffer is nullptr");
94     auto bufferHandle = surfaceBuffer_->GetBufferHandle();
95     if (bufferHandle == nullptr) {
96         AVCODEC_LOGE("Fail to get bufferHandle");
97         return AVCS_ERR_UNKNOWN;
98     }
99     stride_ = bufferHandle->stride;
100     return stride_;
101 }
102 
GetFence()103 int32_t FSurfaceMemory::GetFence()
104 {
105     return fence_;
106 }
107 
SetNeedRender(bool needRender)108 void FSurfaceMemory::SetNeedRender(bool needRender)
109 {
110     needRender_ = needRender;
111 }
112 
UpdateSurfaceBufferScaleMode()113 void FSurfaceMemory::UpdateSurfaceBufferScaleMode()
114 {
115     if (surfaceBuffer_ == nullptr) {
116         AVCODEC_LOGE("surfaceBuffer is nullptr");
117         return;
118     }
119     auto ret = surface_->SetScalingMode(surfaceBuffer_->GetSeqNum(), scalingMode_);
120     if (ret != OHOS::SurfaceError::SURFACE_ERROR_OK) {
121         AVCODEC_LOGE("update surface buffer scaling mode fail, ret: %{public}" PRIu64, static_cast<uint64_t>(ret));
122     }
123 }
124 
SetSurface(sptr<Surface> surface)125 void FSurfaceMemory::SetSurface(sptr<Surface> surface)
126 {
127     surface_ = surface;
128 }
129 
SetConfig(int32_t width,int32_t height,int32_t format,uint64_t usage,int32_t strideAlign,int32_t timeout)130 void FSurfaceMemory::SetConfig(int32_t width, int32_t height, int32_t format, uint64_t usage, int32_t strideAlign,
131                                int32_t timeout)
132 {
133     requestConfig_ = {.width = width,
134                       .height = height,
135                       .strideAlignment = strideAlign,
136                       .format = format,
137                       .usage = usage,
138                       .timeout = timeout};
139 }
140 
SetScaleType(ScalingMode videoScaleMode)141 void FSurfaceMemory::SetScaleType(ScalingMode videoScaleMode)
142 {
143     scalingMode_ = videoScaleMode;
144 }
145 
GetBase() const146 uint8_t *FSurfaceMemory::GetBase() const
147 {
148     CHECK_AND_RETURN_RET_LOG(surfaceBuffer_ != nullptr, nullptr, "surfaceBuffer is nullptr");
149     return static_cast<uint8_t *>(surfaceBuffer_->GetVirAddr());
150 }
151 
GetSize() const152 int32_t FSurfaceMemory::GetSize() const
153 {
154     CHECK_AND_RETURN_RET_LOG(surfaceBuffer_ != nullptr, -1, "surfaceBuffer is nullptr");
155     uint32_t size = surfaceBuffer_->GetSize();
156     return static_cast<int32_t>(size);
157 }
158 } // namespace MediaAVCodec
159 } // namespace OHOS
160