* Copyright (c) 2023-2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined(VIDEO_SUPPORT)
#define HST_LOG_TAG "CodecBufferPool"
#include "codec_buffer_pool.h"
#include "codec_utils.h"
#include "foundation/log.h"
#include "hdf_base.h"
#include "codec_port.h"
namespace OHOS {
namespace Media {
namespace Plugin {
namespace CodecAdapter {
using namespace CodecHDI;
CodecBufferPool::CodecBufferPool(sptr<ICodecComponent>& compType, CompVerInfo& verInfo,
uint32_t portIndex, uint32_t bufferCnt)
: codecComp_(compType), verInfo_(verInfo), portIndex_(portIndex), freeBufferId_("hdiFreeBufferId", bufferCnt)
{
}
Status CodecBufferPool::UseBuffers(OHOS::Media::BlockingQueue<std::shared_ptr<Buffer>>& bufQue, MemoryType bufMemType,
bool isInput, uint32_t bufferSize)
{
MEDIA_LOG_D("UseBuffers begin");
FALSE_RETURN_V_MSG_E(ConfigBufType(bufMemType, isInput) == Status::OK, Status::ERROR_INVALID_DATA,
"ConfigBufType failed");
auto count = bufQue.Size();
for (uint32_t i = 0; i < count; i++) {
auto pluginBuffer = bufQue.Pop();
auto codecBuffer = std::make_shared<CodecBuffer>(pluginBuffer, verInfo_, isInput, bufferSize, bufMemType);
FALSE_RETURN_V_MSG(codecBuffer != nullptr, Status::ERROR_NULL_POINTER, "Create codec buffer failed");
std::shared_ptr<OmxCodecBuffer> outBuffer = std::make_shared<OmxCodecBuffer>();
auto err = codecComp_->UseBuffer(portIndex_, *codecBuffer->GetOmxBuffer(), *outBuffer);
if (err != HDF_SUCCESS) {
MEDIA_LOG_E("failed to UseBuffer");
return Status::ERROR_INVALID_DATA;
}
MEDIA_LOG_D("UseBuffer returned bufferID: " PUBLIC_LOG_U32 ", PortIndex: " PUBLIC_LOG_U32,
codecBuffer->GetBufferId(), portIndex_);
codecBufMap_.emplace(codecBuffer->GetBufferId(), codecBuffer);
freeBufferId_.Push(codecBuffer->GetBufferId());
}
MEDIA_LOG_D("UseBuffers end, freeBufId.size: " PUBLIC_LOG_ZU ", portIndex: " PUBLIC_LOG_U32,
freeBufferId_.Size(), portIndex_);
return Status::OK;
}
Status CodecBufferPool::FreeBuffers()
{
MEDIA_LOG_D("FreeBuffers begin");
for (auto& codecBuf : codecBufMap_) {
auto& codecBuffer = codecBuf.second;
FALSE_RETURN_V_MSG_E(codecComp_ != nullptr, Status::ERROR_NULL_POINTER, "Codec component is null.");
FALSE_RETURN_V_MSG_E(codecBuffer != nullptr, Status::ERROR_NULL_POINTER, "Codec buffer is null.");
auto omxBuffer = codecBuffer->GetOmxBuffer();
FALSE_RETURN_V_MSG_E(omxBuffer != nullptr, Status::ERROR_NULL_POINTER, "Omx buffer is null.");
auto ret = codecComp_->FreeBuffer(portIndex_, *omxBuffer);
FALSE_RETURN_V_MSG_E(ret == HDF_SUCCESS, TransHdiRetVal2Status(ret),
"codec component free buffer failed, omxBufId: " PUBLIC_LOG_U32, codecBuffer->GetBufferId());
}
codecBufMap_.clear();
freeBufferId_.Clear();
MEDIA_LOG_D("FreeBuffers end");
return Status::OK;
}
Status CodecBufferPool::ConfigBufType(const MemoryType& bufMemType, bool isInput)
{
if (bufMemType == MemoryType::SHARE_MEMORY) {
return Status::OK;
}
UseBufferType bufType{};
InitHdiParam(bufType, verInfo_);
bufType.portIndex = portIndex_;
bufType.bufferType = GetOmxBufferType(bufMemType, isInput);
auto ret = HdiSetParameter(codecComp_, OMX_IndexParamUseBufferType, bufType);
FALSE_LOG_MSG(ret == HDF_SUCCESS, "isInput: " PUBLIC_LOG_D32 ", bufferTypes: " PUBLIC_LOG_D32 ", ret: "
PUBLIC_LOG_S, static_cast<int32_t>(isInput), bufType.bufferType, OmxErrorType2String(ret).c_str());
MEDIA_LOG_D("ConfigOutPortBufType end");
return TransHdiRetVal2Status(ret);
}
uint32_t CodecBufferPool::EmptyBufferCount()
{
OSAL::ScopedLock lock(mutex_);
return freeBufferId_.Size();
}
Status CodecBufferPool::UseBufferDone(uint32_t bufId)
{
OSAL::ScopedLock lock(mutex_);
freeBufferId_.Push(bufId);
return Status::OK;
}
std::shared_ptr<CodecBuffer> CodecBufferPool::GetBuffer(int32_t bufferId)
{
OSAL::ScopedLock lock(mutex_);
auto bufId = bufferId >= 0 ? static_cast<uint32_t>(bufferId) : freeBufferId_.Pop(1);
return codecBufMap_.count(bufId) ? codecBufMap_[bufId] : nullptr;
}
}
}
}
}
#endif