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 #if defined(VIDEO_SUPPORT)
16
17 #define HST_LOG_TAG "CodecBufferPool"
18
19 #include "codec_buffer_pool.h"
20 #include "codec_utils.h"
21 #include "foundation/log.h"
22 #include "hdf_base.h"
23
24 namespace OHOS {
25 namespace Media {
26 namespace Plugin {
27 namespace CodecAdapter {
CodecBufferPool(CodecComponentType * compType,CompVerInfo & verInfo,uint32_t portIndex,uint32_t bufferCnt)28 CodecBufferPool::CodecBufferPool(CodecComponentType* compType, CompVerInfo& verInfo,
29 uint32_t portIndex, uint32_t bufferCnt)
30 : codecComp_(compType), verInfo_(verInfo), portIndex_(portIndex), freeBufferId_("hdiFreeBufferId", bufferCnt)
31 {
32 }
33
34 // 当前实现仅仅支持异步模式,hdi的工作模式决定了仅支持异步,要求提前将所有 out buffer 配置好
UseBuffers(OHOS::Media::BlockingQueue<std::shared_ptr<Buffer>> & bufQue,MemoryType bufMemType,bool isInput,uint32_t bufferSize)35 Status CodecBufferPool::UseBuffers(OHOS::Media::BlockingQueue<std::shared_ptr<Buffer>>& bufQue, MemoryType bufMemType,
36 bool isInput, uint32_t bufferSize)
37 {
38 MEDIA_LOG_D("UseBuffers begin");
39 FALSE_RETURN_V_MSG_E(ConfigBufType(bufMemType, isInput) == Status::OK, Status::ERROR_INVALID_DATA,
40 "ConfigBufType failed");
41 auto count = bufQue.Size();
42 for (uint32_t i = 0; i < count; i++) {
43 auto pluginBuffer = bufQue.Pop();
44 auto codecBuffer = std::make_shared<CodecBuffer>(pluginBuffer, verInfo_, isInput, bufferSize, bufMemType);
45 FALSE_RETURN_V_MSG(codecBuffer != nullptr, Status::ERROR_NULL_POINTER, "Create codec buffer failed");
46 auto err = codecComp_->UseBuffer(codecComp_, portIndex_, codecBuffer->GetOmxBuffer().get());
47 if (err != HDF_SUCCESS) {
48 MEDIA_LOG_E("failed to UseBuffer");
49 return Status::ERROR_INVALID_DATA;
50 }
51 MEDIA_LOG_D("UseBuffer returned bufferID: " PUBLIC_LOG_U32 ", PortIndex: " PUBLIC_LOG_U32,
52 codecBuffer->GetBufferId(), portIndex_);
53 codecBufMap_.emplace(codecBuffer->GetBufferId(), codecBuffer);
54 freeBufferId_.Push(codecBuffer->GetBufferId());
55 }
56 MEDIA_LOG_D("UseBuffers end, freeBufId.size: " PUBLIC_LOG_ZU ", portIndex: " PUBLIC_LOG_U32,
57 freeBufferId_.Size(), portIndex_);
58 return Status::OK;
59 }
60
FreeBuffers()61 Status CodecBufferPool::FreeBuffers()
62 {
63 MEDIA_LOG_D("FreeBuffers begin");
64 for (auto& codecBuf : codecBufMap_) {
65 auto& codecBuffer = codecBuf.second;
66 FALSE_RETURN_V_MSG_E(codecComp_ != nullptr, Status::ERROR_NULL_POINTER, "Codec component is null.");
67 FALSE_RETURN_V_MSG_E(codecBuffer != nullptr, Status::ERROR_NULL_POINTER, "Codec buffer is null.");
68 auto omxBuffer = codecBuffer->GetOmxBuffer().get();
69 FALSE_RETURN_V_MSG_E(omxBuffer != nullptr, Status::ERROR_NULL_POINTER, "Omx buffer is null.");
70 auto ret = codecComp_->FreeBuffer(codecComp_, portIndex_, omxBuffer);
71 FALSE_RETURN_V_MSG_E(ret == HDF_SUCCESS, TransHdiRetVal2Status(ret),
72 "codec component free buffer failed, omxBufId: " PUBLIC_LOG_U32, codecBuffer->GetBufferId());
73 }
74 codecBufMap_.clear();
75 freeBufferId_.Clear();
76 MEDIA_LOG_D("FreeBuffers end");
77 return Status::OK;
78 }
79
ConfigBufType(const MemoryType & bufMemType,bool isInput)80 Status CodecBufferPool::ConfigBufType(const MemoryType& bufMemType, bool isInput)
81 {
82 if (bufMemType == MemoryType::SHARE_MEMORY) {
83 return Status::OK;
84 }
85 UseBufferType bufType{};
86 InitHdiParam(bufType, verInfo_);
87 bufType.portIndex = portIndex_;
88 bufType.bufferType = GetOmxBufferType(bufMemType, isInput);
89 auto ret = codecComp_->SetParameter(codecComp_, OMX_IndexParamUseBufferType, (int8_t *)&bufType, sizeof(bufType));
90 FALSE_LOG_MSG(ret == HDF_SUCCESS, "isInput: " PUBLIC_LOG_D32 ", bufferTypes: " PUBLIC_LOG_D32 ", ret: "
91 PUBLIC_LOG_S, static_cast<int32_t>(isInput), bufType.bufferType, OmxErrorType2String(ret).c_str());
92 MEDIA_LOG_D("ConfigOutPortBufType end");
93 return TransHdiRetVal2Status(ret);
94 }
95
EmptyBufferCount()96 uint32_t CodecBufferPool::EmptyBufferCount()
97 {
98 OSAL::ScopedLock lock(mutex_);
99 return freeBufferId_.Size();
100 }
101
UseBufferDone(uint32_t bufId)102 Status CodecBufferPool::UseBufferDone(uint32_t bufId)
103 {
104 OSAL::ScopedLock lock(mutex_);
105 freeBufferId_.Push(bufId);
106 return Status::OK;
107 }
108
GetBuffer(int32_t bufferId)109 std::shared_ptr<CodecBuffer> CodecBufferPool::GetBuffer(int32_t bufferId)
110 {
111 OSAL::ScopedLock lock(mutex_);
112 auto bufId = bufferId >= 0 ? static_cast<uint32_t>(bufferId) : freeBufferId_.Pop(1);
113 return codecBufMap_.count(bufId) ? codecBufMap_[bufId] : nullptr;
114 }
115 } // namespace CodecAdapter
116 } // namespace Plugin
117 } // namespace Media
118 } // namespace OHOS
119 #endif