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 "hdi_buffer_mgr.h"
17 #include <hdf_base.h>
18 #include "hdi_codec_util.h"
19 #include "media_log.h"
20 #include "media_errors.h"
21
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "HdiBufferMgr"};
24 }
25
26 namespace OHOS {
27 namespace Media {
HdiBufferMgr()28 HdiBufferMgr::HdiBufferMgr()
29 {
30 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
31 }
32
~HdiBufferMgr()33 HdiBufferMgr::~HdiBufferMgr()
34 {
35 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
36 }
37
Start()38 int32_t HdiBufferMgr::Start()
39 {
40 MEDIA_LOGD("Enter Start");
41 std::unique_lock<std::mutex> lock(mutex_);
42 isStart_ = true;
43 isFlushed_ = false;
44 return GST_CODEC_OK;
45 }
46
Init(CodecComponentType * handle,int32_t index,const CompVerInfo & verInfo)47 void HdiBufferMgr::Init(CodecComponentType *handle, int32_t index, const CompVerInfo &verInfo)
48 {
49 MEDIA_LOGD("Enter Init");
50 handle_ = handle;
51 verInfo_ = verInfo;
52 InitParam(mPortDef_, verInfo_);
53 mPortIndex_ = index;
54 mPortDef_.nPortIndex = (uint32_t)index;
55 }
56
GetCodecBuffer(GstBuffer * buffer)57 std::shared_ptr<HdiBufferWrap> HdiBufferMgr::GetCodecBuffer(GstBuffer *buffer)
58 {
59 MEDIA_LOGD("Enter GetCodecBuffer");
60 std::shared_ptr<HdiBufferWrap> codecBuffer = nullptr;
61 GstBufferTypeMeta *bufferType = gst_buffer_get_buffer_type_meta(buffer);
62 CHECK_AND_RETURN_RET_LOG(bufferType != nullptr, nullptr, "bufferType is nullptr");
63 for (auto iter = availableBuffers_.begin(); iter != availableBuffers_.end(); ++iter) {
64 if (*iter != nullptr) {
65 if ((*iter)->buf == bufferType->buf) {
66 codecBuffer = *iter;
67 codingBuffers_.push_back(std::make_pair(codecBuffer, buffer));
68 gst_buffer_ref(buffer);
69 (void)availableBuffers_.erase(iter);
70 UpdateCodecMeta(bufferType, codecBuffer);
71 codecBuffer->hdiBuffer.pts = (int64_t)(GST_BUFFER_PTS(buffer));
72 break;
73 }
74 }
75 }
76 return codecBuffer;
77 }
78
UpdateCodecMeta(GstBufferTypeMeta * bufferType,std::shared_ptr<HdiBufferWrap> & codecBuffer)79 void HdiBufferMgr::UpdateCodecMeta(GstBufferTypeMeta *bufferType, std::shared_ptr<HdiBufferWrap> &codecBuffer)
80 {
81 MEDIA_LOGD("Enter UpdateCodecMeta");
82 CHECK_AND_RETURN_LOG(codecBuffer != nullptr, "bufferType is nullptr");
83 CHECK_AND_RETURN_LOG(bufferType != nullptr, "bufferType is nullptr");
84 codecBuffer->hdiBuffer.allocLen = bufferType->totalSize;
85 codecBuffer->hdiBuffer.offset = bufferType->offset;
86 codecBuffer->hdiBuffer.filledLen = bufferType->length;
87 codecBuffer->hdiBuffer.fenceFd = bufferType->fenceFd;
88 codecBuffer->hdiBuffer.type = bufferType->memFlag == FLAGS_READ_ONLY ? READ_ONLY_TYPE : READ_WRITE_TYPE;
89 }
90
PreUseAshareMems(std::vector<GstBuffer * > & buffers)91 std::vector<std::shared_ptr<HdiBufferWrap>> HdiBufferMgr::PreUseAshareMems(std::vector<GstBuffer *> &buffers)
92 {
93 MEDIA_LOGD("Enter PreUseAshareMems");
94 std::vector<std::shared_ptr<HdiBufferWrap>> preBuffers;
95 auto ret = HdiGetParameter(handle_, OMX_IndexParamPortDefinition, mPortDef_);
96 CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, preBuffers, "HdiGetParameter failed");
97 CHECK_AND_RETURN_RET_LOG(buffers.size() == mPortDef_.nBufferCountActual, preBuffers, "BufferNum error");
98 for (auto buffer : buffers) {
99 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, preBuffers, "buffer is nullptr");
100 GstBufferTypeMeta *bufferType = gst_buffer_get_buffer_type_meta(buffer);
101 CHECK_AND_RETURN_RET_LOG(bufferType != nullptr, preBuffers, "bufferType is nullptr");
102 std::shared_ptr<HdiBufferWrap> codecBuffer = std::make_shared<HdiBufferWrap>();
103 codecBuffer->buf = bufferType->buf;
104 codecBuffer->hdiBuffer.size = sizeof(OmxCodecBuffer);
105 codecBuffer->hdiBuffer.version = verInfo_.compVersion;
106 codecBuffer->hdiBuffer.bufferType = CodecBufferType::CODEC_BUFFER_TYPE_AVSHARE_MEM_FD;
107 codecBuffer->hdiBuffer.bufferLen = bufferType->bufLen;
108 codecBuffer->hdiBuffer.buffer = reinterpret_cast<uint8_t *>(bufferType->buf);
109 codecBuffer->hdiBuffer.allocLen = bufferType->totalSize;
110 codecBuffer->hdiBuffer.offset = bufferType->offset;
111 codecBuffer->hdiBuffer.filledLen = bufferType->length;
112 codecBuffer->hdiBuffer.fenceFd = bufferType->fenceFd;
113 codecBuffer->hdiBuffer.flag = 0;
114 codecBuffer->hdiBuffer.type = bufferType->memFlag == FLAGS_READ_ONLY ? READ_ONLY_TYPE : READ_WRITE_TYPE;
115 preBuffers.push_back(codecBuffer);
116 }
117 return preBuffers;
118 }
119
UseHdiBuffers(std::vector<std::shared_ptr<HdiBufferWrap>> & buffers)120 int32_t HdiBufferMgr::UseHdiBuffers(std::vector<std::shared_ptr<HdiBufferWrap>> &buffers)
121 {
122 MEDIA_LOGD("Enter UseHdiBuffers");
123 CHECK_AND_RETURN_RET_LOG(buffers.size() == mPortDef_.nBufferCountActual, GST_CODEC_ERROR, "BufferNum error");
124 for (auto buffer : buffers) {
125 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, GST_CODEC_ERROR, "buffer is nullptr");
126 auto ret = handle_->UseBuffer(handle_, (uint32_t)mPortIndex_, &buffer->hdiBuffer);
127 CHECK_AND_RETURN_RET_LOG(ret == HDF_SUCCESS, GST_CODEC_ERROR, "UseBuffer failed");
128 MEDIA_LOGD("Enter buffer id %{public}d", buffer->hdiBuffer.bufferId);
129 availableBuffers_.push_back(buffer);
130 }
131 return GST_CODEC_OK;
132 }
133
FreeCodecBuffers()134 void HdiBufferMgr::FreeCodecBuffers()
135 {
136 MEDIA_LOGD("Enter FreeCodecBuffers");
137 for (auto codecBuffer : availableBuffers_) {
138 auto ret = handle_->FreeBuffer(handle_, mPortIndex_, &codecBuffer->hdiBuffer);
139 if (ret != HDF_SUCCESS) {
140 MEDIA_LOGE("free buffer %{public}u fail", codecBuffer->hdiBuffer.bufferId);
141 }
142 }
143 EmptyList(availableBuffers_);
144 MEDIA_LOGD("Enter FreeCodecBuffers End");
145 }
146
Stop(bool isFormatChange)147 int32_t HdiBufferMgr::Stop(bool isFormatChange)
148 {
149 MEDIA_LOGD("Enter Stop");
150 std::unique_lock<std::mutex> lock(mutex_);
151 isStart_ = false;
152 isFormatChange_ = isFormatChange;
153 bufferCond_.notify_all();
154 flushCond_.notify_all();
155 return GST_CODEC_OK;
156 }
157
Flush(bool enable)158 int32_t HdiBufferMgr::Flush(bool enable)
159 {
160 MEDIA_LOGD("Enter Flush %{public}d", enable);
161 std::unique_lock<std::mutex> lock(mutex_);
162 isFlushing_ = enable;
163 if (isFlushing_) {
164 bufferCond_.notify_all();
165 isFlushed_ = true;
166 }
167 if (!isFlushing_) {
168 flushCond_.notify_all();
169 }
170 return GST_CODEC_OK;
171 }
172
WaitFlushed()173 void HdiBufferMgr::WaitFlushed()
174 {
175 MEDIA_LOGD("Enter WaitFlushed");
176 std::unique_lock<std::mutex> lock(mutex_);
177 flushCond_.wait(lock, [this]() { return !isFlushing_ || !isStart_; });
178 }
179
NotifyAvailable()180 void HdiBufferMgr::NotifyAvailable()
181 {
182 if (isStart_ == false && availableBuffers_.size() == mPortDef_.nBufferCountActual) {
183 freeCond_.notify_all();
184 }
185 }
186
SetFlagToBuffer(GstBuffer * buffer,const uint32_t & flag)187 void HdiBufferMgr::SetFlagToBuffer(GstBuffer *buffer, const uint32_t &flag)
188 {
189 GstBufferTypeMeta *bufferType = gst_buffer_get_buffer_type_meta(buffer);
190 if (bufferType == nullptr) {
191 MEDIA_LOGW("bufferType is null, set flag %{public}d to gstbuffer fail", flag);
192 return;
193 }
194 bufferType->bufferFlag = BUFFER_FLAG_NONE;
195 if (flag & OMX_BUFFERFLAG_EOS) {
196 bufferType->bufferFlag |= BUFFER_FLAG_EOS;
197 }
198 if (flag & OMX_BUFFERFLAG_SYNCFRAME) {
199 bufferType->bufferFlag |= BUFFER_FLAG_SYNC_FRAME;
200 }
201 if (flag & OMX_BUFFERFLAG_CODECCONFIG) {
202 bufferType->bufferFlag |= BUFFER_FLAG_CODEC_DATA;
203 }
204 }
205 } // namespace Media
206 } // namespace OHOS
207