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 "CodecBuffer"
18
19 #include "codec_buffer.h"
20 #include "codec_utils.h"
21 #include "plugin/common/surface_memory.h"
22
23 namespace OHOS {
24 namespace Media {
25 namespace Plugin {
26 namespace CodecAdapter {
CodecBuffer(std::shared_ptr<Buffer> & buffer,CompVerInfo & verInfo,bool isInput,uint32_t bufferSize,MemoryType bufMemType)27 CodecBuffer::CodecBuffer(std::shared_ptr<Buffer>& buffer, CompVerInfo& verInfo,
28 bool isInput, uint32_t bufferSize, MemoryType bufMemType)
29 : buffer_(buffer), verInfo_(verInfo)
30 {
31 Init(isInput, bufferSize, bufMemType);
32 }
33
Init(bool isInput,uint32_t bufferSize,MemoryType bufMemType)34 void CodecBuffer::Init(bool isInput, uint32_t bufferSize, MemoryType bufMemType)
35 {
36 MEDIA_LOG_DD("CodecBuffer Init Start");
37 omxBuffer_ = std::make_shared<OmxCodecBuffer>();
38 omxBuffer_->size = sizeof(OmxCodecBuffer);
39 omxBuffer_->version.s.nVersionMajor = verInfo_.compVersion.s.nVersionMajor;
40 omxBuffer_->fenceFd = -1; // check use -1 first with no window
41 omxBuffer_->pts = 0;
42 omxBuffer_->flag = 0;
43 omxBuffer_->bufferType = GetOmxBufferType(bufMemType, isInput);
44 omxBuffer_->allocLen = bufferSize;
45 omxBuffer_->bufferLen = 0;
46 omxBuffer_->buffer = nullptr;
47 memory_ = buffer_->GetMemory();
48 FALSE_RETURN(memory_ != nullptr);
49 omxBuffer_->allocLen = memory_->GetCapacity();
50 switch (bufMemType) {
51 case MemoryType::SURFACE_BUFFER: {
52 BufferHandle* bufferHandle =
53 std::static_pointer_cast<Plugin::SurfaceMemory>(memory_)->GetSurfaceBuffer()->GetBufferHandle();
54 FALSE_LOG_MSG(bufferHandle != nullptr, "bufferHandle is null");
55 if (bufferHandle == NULL) {
56 return;
57 }
58 omxBuffer_->bufferLen =
59 sizeof(BufferHandle) + (sizeof(int32_t) * (bufferHandle->reserveFds + bufferHandle->reserveInts));
60 omxBuffer_->buffer = reinterpret_cast<uint8_t *>(bufferHandle);
61 break;
62 }
63 case MemoryType::SHARE_MEMORY: {
64 omxBuffer_->bufferLen = sizeof(int);
65 omxBuffer_->type = isInput ? READ_ONLY_TYPE : READ_WRITE_TYPE;
66 omxBuffer_->buffer = reinterpret_cast<uint8_t *>(static_cast<long long>(
67 std::static_pointer_cast<Plugin::ShareMemory>(memory_)->GetShareMemoryFd()));
68 MEDIA_LOG_D("share memory fd: " PUBLIC_LOG_D32,
69 std::static_pointer_cast<Plugin::ShareMemory>(memory_)->GetShareMemoryFd());
70 break;
71 }
72 default:
73 MEDIA_LOG_W("UnKnow MemoryType: " PUBLIC_LOG_D32, (int)memory_->GetMemoryType());
74 break;
75 }
76 }
77
GetOmxBuffer()78 std::shared_ptr<OmxCodecBuffer> CodecBuffer::GetOmxBuffer()
79 {
80 return omxBuffer_;
81 }
82
GetBufferId() const83 uint32_t CodecBuffer::GetBufferId() const
84 {
85 return omxBuffer_->bufferId;
86 }
87
Copy(const std::shared_ptr<Plugin::Buffer> & pluginBuffer)88 Status CodecBuffer::Copy(const std::shared_ptr<Plugin::Buffer>& pluginBuffer)
89 {
90 omxBuffer_->flag = Translate2omxFlagSet(pluginBuffer->flag);
91 omxBuffer_->pts = pluginBuffer->pts;
92 MEDIA_LOG_DD("plugin flag: " PUBLIC_LOG_U32 ", pts: " PUBLIC_LOG_D64, omxBuffer_->flag, omxBuffer_->pts);
93 if (pluginBuffer->flag & BUFFER_FLAG_EOS) {
94 MEDIA_LOG_D("EOS flag receive, return");
95 return Status::OK;
96 }
97 auto mem = pluginBuffer->GetMemory();
98 if (mem == nullptr) {
99 MEDIA_LOG_DD("pluginBuffer->GetMemory() return nullptr");
100 return Status::ERROR_INVALID_DATA;
101 }
102 const uint8_t* memAddr = mem->GetReadOnlyData();
103 if (memAddr == nullptr) {
104 MEDIA_LOG_DD("mem->GetReadOnlyData() return nullptr");
105 return Status::ERROR_INVALID_DATA;
106 }
107 memory_->Write(memAddr, mem->GetSize(), 0);
108 omxBuffer_->offset = 0;
109 omxBuffer_->filledLen = mem->GetSize();
110 MEDIA_LOG_DD("CopyBuffer end, bufferId: " PUBLIC_LOG_U32, omxBuffer_->bufferId);
111 return Status::OK;
112 }
113
Rebind(const std::shared_ptr<Plugin::Buffer> & pluginBuffer)114 Status CodecBuffer::Rebind(const std::shared_ptr<Plugin::Buffer>& pluginBuffer)
115 {
116 MEDIA_LOG_DD("Rebind Start");
117 omxBuffer_->flag = Translate2omxFlagSet(pluginBuffer->flag);
118 omxBuffer_->pts = pluginBuffer->pts;
119 MEDIA_LOG_DD("plugin flag: " PUBLIC_LOG_U32 ", pts: " PUBLIC_LOG_D64, omxBuffer_->flag, omxBuffer_->pts);
120 memory_ = pluginBuffer->GetMemory();
121 FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_NULL_POINTER, "Call pluginBuffer->GetMemory() failed.");
122 switch (memory_->GetMemoryType()) {
123 case MemoryType::SURFACE_BUFFER: {
124 auto outMem = std::static_pointer_cast<Plugin::SurfaceMemory>(memory_);
125 auto surfaceBuf = outMem->GetSurfaceBuffer();
126 FALSE_RETURN_V_MSG_E(surfaceBuf != nullptr, Status::ERROR_NULL_POINTER, "GetSurfaceBuffer failed");
127 BufferHandle* bufferHandle = surfaceBuf->GetBufferHandle();
128 FALSE_RETURN_V_MSG_E(bufferHandle != nullptr, Status::ERROR_NULL_POINTER, "GetBufferHandle failed");
129 omxBuffer_->bufferLen =
130 sizeof(BufferHandle) + sizeof(int32_t) * (bufferHandle->reserveFds + bufferHandle->reserveInts);
131 omxBuffer_->buffer = reinterpret_cast<uint8_t *>(bufferHandle);
132 break;
133 }
134 case MemoryType::SHARE_MEMORY:
135 omxBuffer_->bufferLen = sizeof(int);
136 omxBuffer_->buffer = reinterpret_cast<uint8_t *>(static_cast<long long>(
137 std::static_pointer_cast<Plugin::ShareMemory>(memory_)->GetShareMemoryFd()));
138 omxBuffer_->offset = 0;
139 omxBuffer_->filledLen = 0;
140 break;
141 case MemoryType::VIRTUAL_ADDR:
142 MEDIA_LOG_E("Rebind pluginBuffer failed, MemoryType is VIRTUAL_ADDR");
143 break;
144 default:
145 MEDIA_LOG_E("MemoryType invalid!");
146 break;
147 }
148 // 这里buffer需要保存一下,为了方便往下一节点传数据,通过GetBuffer()获取
149 buffer_ = pluginBuffer;
150 MEDIA_LOG_DD("Rebind end, omxBufferId: " PUBLIC_LOG_U32, omxBuffer_->bufferId);
151 return Status::OK;
152 }
153
154 /**
155 * Receive buffer_ with data contained in CodecBuffer for transmission to the filter
156 * @param buffer Copy the value of buffer_
157 * @param omxBuffer
158 * @return
159 */
Unbind(std::shared_ptr<Plugin::Buffer> & buffer,const OmxCodecBuffer * omxBuffer)160 Status CodecBuffer::Unbind(std::shared_ptr<Plugin::Buffer>& buffer, const OmxCodecBuffer* omxBuffer)
161 {
162 // 因为Rebind()里面用buffer_保存了PluginBuf,所以这里的buffer_需要主动释放,减少智能指针的引用计数
163 // decoder 时,PluginBuf 的真正释放时机应该是在sink节点,该数据送显后才能释放
164 FALSE_RETURN_V_MSG_E(memory_ != nullptr, Status::ERROR_NULL_POINTER, "Param memory_ is nullptr");
165 if (memory_->GetMemoryType() == MemoryType::SHARE_MEMORY) {
166 memory_->UpdateDataSize(static_cast<size_t>(omxBuffer->filledLen - omxBuffer->offset), 0);
167 }
168 buffer = buffer_;
169 buffer->flag = Translate2PluginFlagSet(omxBuffer->flag);
170 buffer->pts = omxBuffer->pts;
171 buffer_ = nullptr;
172 return Status::OK;
173 }
174 } // namespace CodecAdapter
175 } // namespace Plugin
176 } // namespace Media
177 } // namespace OHOS
178 #endif