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