1/* 2 * Copyright (c) 2022-2023 Shenzhen Kaihong DID 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 "codec_share_buffer.h" 17#include <hdf_base.h> 18#include <securec.h> 19#include <unistd.h> 20#include "codec_log_wrapper.h" 21using namespace OHOS::HDI::Codec::V3_0; 22namespace OHOS { 23namespace Codec { 24namespace Omx { 25CodecShareBuffer::CodecShareBuffer(struct OmxCodecBuffer &codecBuffer) : ICodecBuffer(codecBuffer) 26{} 27 28CodecShareBuffer::~CodecShareBuffer() 29{ 30 shMem_ = nullptr; 31} 32 33void CodecShareBuffer::SetAshMem(std::shared_ptr<OHOS::Ashmem> shMem) 34{ 35 shMem_ = shMem; 36} 37 38OHOS::sptr<ICodecBuffer> CodecShareBuffer::Create(struct OmxCodecBuffer &codecBuffer) 39{ 40 if (codecBuffer.fd < 0) { 41 CODEC_LOGE("codecBuffer.fd is invalid"); 42 return OHOS::sptr<ICodecBuffer>(); 43 } 44 int size = OHOS::AshmemGetSize(codecBuffer.fd); 45 std::shared_ptr<OHOS::Ashmem> sharedMem = std::make_shared<OHOS::Ashmem>(codecBuffer.fd, size); 46 if (sharedMem == nullptr) { 47 CODEC_LOGE("Failed to init sharedMem"); 48 return OHOS::sptr<ICodecBuffer>(); 49 } 50 bool mapd = false; 51 if (codecBuffer.type == READ_WRITE_TYPE) { 52 mapd = sharedMem->MapReadAndWriteAshmem(); 53 } else { 54 mapd = sharedMem->MapReadOnlyAshmem(); 55 } 56 if (!mapd) { 57 CODEC_LOGE("MapReadAndWriteAshmem or MapReadOnlyAshmem return false"); 58 return OHOS::sptr<ICodecBuffer>(); 59 } 60 codecBuffer.fd = -1; 61 CodecShareBuffer *buffer = new CodecShareBuffer(codecBuffer); 62 buffer->SetAshMem(sharedMem); 63 return OHOS::sptr<ICodecBuffer>(buffer); 64} 65 66OHOS::sptr<ICodecBuffer> CodecShareBuffer::Allocate(struct OmxCodecBuffer &codecBuffer) 67{ 68 codecBuffer.bufferType = CODEC_BUFFER_TYPE_AVSHARE_MEM_FD; 69 // create shared memory 70 int sharedFD = AshmemCreate(nullptr, codecBuffer.allocLen); 71 72 std::shared_ptr<Ashmem> sharedMemory = std::make_shared<Ashmem>(sharedFD, codecBuffer.allocLen); 73 if (sharedMemory == nullptr) { 74 CODEC_LOGE("Failed to init sharedMemory"); 75 return OHOS::sptr<ICodecBuffer>(); 76 } 77 bool mapd = false; 78 if (codecBuffer.type == READ_WRITE_TYPE) { 79 mapd = sharedMemory->MapReadAndWriteAshmem(); 80 } else { 81 mapd = sharedMemory->MapReadOnlyAshmem(); 82 } 83 if (!mapd) { 84 CODEC_LOGE("MapReadAndWriteAshmem or MapReadOnlyAshmem return false"); 85 return OHOS::sptr<ICodecBuffer>(); 86 } 87 codecBuffer.offset = 0; 88 codecBuffer.filledLen = 0; 89 CodecShareBuffer *buffer = new CodecShareBuffer(codecBuffer); 90 codecBuffer.fd = sharedFD; 91 buffer->SetAshMem(sharedMemory); 92 return OHOS::sptr<ICodecBuffer>(buffer); 93} 94 95int32_t CodecShareBuffer::FillOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) 96{ 97 if (!CheckInvalid(codecBuffer) || codecBuffer_.type != READ_WRITE_TYPE) { 98 CODEC_LOGE("CheckInvalid return false or mem has no right to write "); 99 return HDF_ERR_INVALID_PARAM; 100 } 101 102 return ICodecBuffer::FillOmxBuffer(codecBuffer, omxBuffer); 103} 104 105int32_t CodecShareBuffer::EmptyOmxBuffer(struct OmxCodecBuffer &codecBuffer, OMX_BUFFERHEADERTYPE &omxBuffer) 106{ 107 if (!CheckInvalid(codecBuffer)) { 108 CODEC_LOGE("shMem_ is null or CheckInvalid return false"); 109 return HDF_ERR_INVALID_PARAM; 110 } 111 112 void *sharedPtr = const_cast<void *>(shMem_->ReadFromAshmem(codecBuffer.filledLen, codecBuffer.offset)); 113 if (!sharedPtr) { 114 CODEC_LOGE("omxBuffer.length [%{public}d omxBuffer.offset[%{public}d]", codecBuffer.filledLen, 115 codecBuffer.offset); 116 return HDF_ERR_INVALID_PARAM; 117 } 118 auto ret = memcpy_s(omxBuffer.pBuffer + codecBuffer.offset, codecBuffer.allocLen - codecBuffer.offset, sharedPtr, 119 codecBuffer.filledLen); 120 if (ret != EOK) { 121 CODEC_LOGE("memcpy_s ret [%{public}d]", ret); 122 return HDF_ERR_INVALID_PARAM; 123 } 124 return ICodecBuffer::EmptyOmxBuffer(codecBuffer, omxBuffer); 125} 126 127int32_t CodecShareBuffer::FreeBuffer(struct OmxCodecBuffer &codecBuffer) 128{ 129 if (!CheckInvalid(codecBuffer)) { 130 CODEC_LOGE("shMem_ is null or CheckInvalid return false"); 131 return HDF_ERR_INVALID_PARAM; 132 } 133 134 shMem_ = nullptr; 135 return HDF_SUCCESS; 136} 137 138uint8_t *CodecShareBuffer::GetBuffer() 139{ 140 return nullptr; 141} 142 143int32_t CodecShareBuffer::EmptyOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) 144{ 145 return ICodecBuffer::EmptyOmxBufferDone(omxBuffer); 146} 147 148int32_t CodecShareBuffer::FillOmxBufferDone(OMX_BUFFERHEADERTYPE &omxBuffer) 149{ 150 if (shMem_ == nullptr || !shMem_->WriteToAshmem(omxBuffer.pBuffer, omxBuffer.nFilledLen, omxBuffer.nOffset)) { 151 CODEC_LOGE("write to ashmem fail"); 152 return HDF_ERR_INVALID_PARAM; 153 } 154 155 return ICodecBuffer::FillOmxBufferDone(omxBuffer); 156} 157 158bool CodecShareBuffer::CheckInvalid(struct OmxCodecBuffer &codecBuffer) 159{ 160 if (!ICodecBuffer::CheckInvalid(codecBuffer) || shMem_ == nullptr) { 161 CODEC_LOGE("shMem_ is null or CheckInvalid return false"); 162 return false; 163 } 164 return true; 165} 166} // namespace Omx 167} // namespace Codec 168} // namespace OHOS