• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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