1 /*
2 * Copyright (C) 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
16 #include "codec_listener_stub.h"
17 #include <shared_mutex>
18 #include <sstream>
19 #include <string>
20 #include "avcodec_errors.h"
21 #include "avcodec_parcel.h"
22 #include "avsharedmemory_ipc.h"
23 #include "buffer/avsharedmemorybase.h"
24 #include "meta/meta.h"
25 namespace {
26 constexpr uint8_t LOG_FREQ = 10;
27 } // namespace
28
29 namespace OHOS {
30 namespace MediaAVCodec {
31 using namespace Media;
32 typedef enum : uint8_t {
33 OWNED_BY_SERVER = 0,
34 OWNED_BY_USER = 1,
35 } BufferOwner;
36
37 typedef struct BufferElem {
38 std::shared_ptr<AVSharedMemory> memory = nullptr;
39 std::shared_ptr<AVBuffer> buffer = nullptr;
40 std::shared_ptr<Format> parameter = nullptr;
41 std::shared_ptr<Format> attribute = nullptr;
42 BufferOwner owner = OWNED_BY_SERVER;
43 } BufferElem;
44
45 typedef enum : uint8_t {
46 ELEM_GET_AVBUFFER,
47 ELEM_GET_AVMEMORY,
48 ELEM_GET_PARAMETER,
49 ELEM_GET_ATRRIBUTE,
50 } UpdateFilter;
51
52 class CodecListenerStub::CodecBufferCache : public NoCopyable {
53 public:
CodecBufferCache(bool isOutput)54 explicit CodecBufferCache(bool isOutput) : isOutput_(isOutput) {}
55 ~CodecBufferCache() = default;
56
ReadFromParcel(uint32_t index,MessageParcel & parcel,BufferElem & elem,const UpdateFilter filter=ELEM_GET_AVBUFFER)57 bool ReadFromParcel(uint32_t index, MessageParcel &parcel, BufferElem &elem,
58 const UpdateFilter filter = ELEM_GET_AVBUFFER)
59 {
60 std::lock_guard<std::shared_mutex> lock(mutex_);
61 auto iter = caches_.find(index);
62 flag_ = static_cast<CacheFlag>(parcel.ReadUint8());
63 if (flag_ == CacheFlag::HIT_CACHE && iter == caches_.end()) {
64 AVCODEC_LOGW("Mark hit cache, but can find the index's cache, index: %{public}u", index);
65 flag_ = CacheFlag::UPDATE_CACHE;
66 }
67 if (flag_ == CacheFlag::HIT_CACHE) {
68 iter->second.owner = OWNED_BY_USER;
69 isOutput_ ? HitOutputCache(iter->second, parcel, filter) : HitInputCache(iter->second, parcel, filter);
70 elem = iter->second;
71 return CheckReadFromParcelResult(elem, filter);
72 }
73 if (flag_ == CacheFlag::UPDATE_CACHE) {
74 elem.owner = OWNED_BY_USER;
75 isOutput_ ? UpdateOutputCache(elem, parcel, filter) : UpdateInputCache(elem, parcel, filter);
76 if (iter == caches_.end()) {
77 PrintLogOnUpdateBuffer(index);
78 caches_.emplace(index, elem);
79 } else {
80 iter->second = elem;
81 PrintLogOnUpdateBuffer(index);
82 }
83 return CheckReadFromParcelResult(elem, filter);
84 }
85 // invalidate cache flag_
86 if (iter != caches_.end()) {
87 caches_.erase(iter);
88 }
89 AVCODEC_LOGE("Invalidate cache for index: %{public}u, flag: %{public}hhu", index, flag_);
90 return false;
91 }
92
ReturnBufferToServer(uint32_t index,BufferElem & elem)93 void ReturnBufferToServer(uint32_t index, BufferElem &elem)
94 {
95 std::shared_lock<std::shared_mutex> lock(mutex_);
96 auto iter = caches_.find(index);
97 if (iter == caches_.end()) {
98 AVCODEC_LOGE("Get cache failed, index: %{public}u", index);
99 return;
100 }
101 elem = iter->second;
102 if (elem.owner == OWNED_BY_USER) {
103 elem.owner = OWNED_BY_SERVER;
104 } else {
105 AVCODEC_LOGW("Did not receive new callback of this index(%{public}u)", index);
106 }
107 EXPECT_AND_LOGD(elem.buffer != nullptr, "index=%{public}d, flag=%{public}u, pts=%{public}" PRId64, index,
108 elem.buffer->flag_, elem.buffer->pts_);
109 }
110
ClearCaches()111 void ClearCaches()
112 {
113 std::lock_guard<std::shared_mutex> lock(mutex_);
114 PrintCachesInfo();
115 caches_.clear();
116 }
117
FlushCaches()118 void FlushCaches()
119 {
120 std::lock_guard<std::shared_mutex> lock(mutex_);
121 PrintCachesInfo();
122 for (auto &val : caches_) {
123 val.second.owner = OWNED_BY_SERVER;
124 }
125 }
126
SetConverter(std::shared_ptr<BufferConverter> & converter)127 void SetConverter(std::shared_ptr<BufferConverter> &converter)
128 {
129 converter_ = converter;
130 }
131
PrintLogOnUpdateBuffer(const uint32_t & index)132 inline void PrintLogOnUpdateBuffer(const uint32_t &index)
133 {
134 if (caches_.size() <= 1) {
135 AVCODEC_LOGI("add caches. index: %{public}u", index);
136 } else {
137 AVCODEC_LOGD("add caches. index: %{public}u", index);
138 }
139 }
140
PrintCachesInfo()141 void PrintCachesInfo()
142 {
143 std::stringstream serverCaches;
144 std::stringstream userCaches;
145 serverCaches << "server(";
146 userCaches << "user(";
147 for (auto &val : caches_) {
148 switch (val.second.owner) {
149 case OWNED_BY_SERVER:
150 serverCaches << val.first << " ";
151 break;
152 case OWNED_BY_USER:
153 userCaches << val.first << " ";
154 break;
155 default:
156 break;
157 }
158 }
159 serverCaches << ")";
160 userCaches << ")";
161 AVCODEC_LOGI("%{public}s caches: %{public}s, %{public}s", (isOutput_ ? "out" : "in"), userCaches.str().c_str(),
162 serverCaches.str().c_str());
163 }
164
InitLabel(const uint64_t uid)165 void InitLabel(const uint64_t uid)
166 {
167 std::lock_guard<std::shared_mutex> lock(mutex_);
168 tag_ = isOutput_ ? "OutCache[" : "InCache[";
169 tag_ += std::to_string(uid) + "]";
170 auto &label = const_cast<OHOS::HiviewDFX::HiLogLabel &>(LABEL);
171 label.tag = tag_.c_str();
172 }
173
174 private:
AVBufferToAVSharedMemory(const std::shared_ptr<AVBuffer> & buffer,std::shared_ptr<AVSharedMemory> & memory)175 void AVBufferToAVSharedMemory(const std::shared_ptr<AVBuffer> &buffer, std::shared_ptr<AVSharedMemory> &memory)
176 {
177 using Flags = AVSharedMemory::Flags;
178 std::shared_ptr<AVMemory> &bufferMem = buffer->memory_;
179 if (bufferMem == nullptr || memory != nullptr) {
180 return;
181 }
182 MemoryType type = bufferMem->GetMemoryType();
183 int32_t capacity = bufferMem->GetCapacity();
184 if (type == MemoryType::SHARED_MEMORY) {
185 std::string name = std::string("SharedMem_") + std::to_string(buffer->GetUniqueId());
186 int32_t fd = bufferMem->GetFileDescriptor();
187 bool isReadable = bufferMem->GetMemoryFlag() == MemoryFlag::MEMORY_READ_ONLY;
188 uint32_t flag = isReadable ? Flags::FLAGS_READ_ONLY : Flags::FLAGS_READ_WRITE;
189 memory = AVSharedMemoryBase::CreateFromRemote(fd, capacity, flag, name);
190 } else {
191 std::string name = std::string("SharedMem_") + std::to_string(buffer->GetUniqueId());
192 memory = AVSharedMemoryBase::CreateFromLocal(capacity, Flags::FLAGS_READ_WRITE, name);
193 CHECK_AND_RETURN_LOG(memory != nullptr, "Create shared memory from local failed.");
194 }
195 }
196
HitInputCache(BufferElem & elem,MessageParcel & parcel,const UpdateFilter & filter)197 void HitInputCache(BufferElem &elem, MessageParcel &parcel, const UpdateFilter &filter)
198 {
199 if (filter == ELEM_GET_AVMEMORY) {
200 return;
201 }
202 bool isReadSuc = elem.buffer->ReadFromMessageParcel(parcel);
203 CHECK_AND_RETURN_LOG(isReadSuc, "Read input buffer from parcel failed");
204 elem.buffer->flag_ = 0;
205 if (elem.buffer->memory_ != nullptr) {
206 elem.buffer->memory_->SetOffset(0);
207 elem.buffer->memory_->SetSize(0);
208 }
209 if (filter == ELEM_GET_ATRRIBUTE) {
210 elem.attribute->PutLongValue(Media::Tag::MEDIA_TIME_STAMP, elem.buffer->pts_);
211 return;
212 }
213 if (filter == ELEM_GET_PARAMETER) {
214 return;
215 }
216 elem.buffer->pts_ = 0;
217 }
218
HitOutputCache(BufferElem & elem,MessageParcel & parcel,const UpdateFilter & filter)219 void HitOutputCache(BufferElem &elem, MessageParcel &parcel, const UpdateFilter &filter)
220 {
221 bool isReadSuc = elem.buffer->ReadFromMessageParcel(parcel);
222 CHECK_AND_RETURN_LOG(isReadSuc, "Read output buffer from parcel failed");
223 if (filter == ELEM_GET_AVMEMORY && converter_ != nullptr) {
224 converter_->ReadFromBuffer(elem.buffer, elem.memory);
225 }
226 }
227
UpdateInputCache(BufferElem & elem,MessageParcel & parcel,const UpdateFilter & filter)228 void UpdateInputCache(BufferElem &elem, MessageParcel &parcel, const UpdateFilter &filter)
229 {
230 elem.buffer = AVBuffer::CreateAVBuffer();
231 bool isReadSuc = (elem.buffer != nullptr) && elem.buffer->ReadFromMessageParcel(parcel);
232 CHECK_AND_RETURN_LOG(isReadSuc, "Create input buffer from parcel failed");
233 if (filter == ELEM_GET_PARAMETER) {
234 elem.parameter = std::make_shared<Format>();
235 elem.parameter->SetMeta(std::move(elem.buffer->meta_));
236 elem.buffer->meta_ = elem.parameter->GetMeta();
237 } else if (filter == ELEM_GET_ATRRIBUTE) {
238 elem.parameter = std::make_shared<Format>();
239 elem.parameter->SetMeta(std::move(elem.buffer->meta_));
240 elem.buffer->meta_ = elem.parameter->GetMeta();
241
242 elem.attribute = std::make_shared<Format>();
243 elem.attribute->PutLongValue(Media::Tag::MEDIA_TIME_STAMP, elem.buffer->pts_);
244 } else if (filter == ELEM_GET_AVMEMORY) {
245 AVBufferToAVSharedMemory(elem.buffer, elem.memory);
246 if (converter_ != nullptr) {
247 converter_->SetInputBufferFormat(elem.buffer);
248 }
249 }
250 }
251
UpdateOutputCache(BufferElem & elem,MessageParcel & parcel,const UpdateFilter & filter)252 void UpdateOutputCache(BufferElem &elem, MessageParcel &parcel, const UpdateFilter &filter)
253 {
254 elem.buffer = AVBuffer::CreateAVBuffer();
255 bool isReadSuc = (elem.buffer != nullptr) && elem.buffer->ReadFromMessageParcel(parcel);
256 CHECK_AND_RETURN_LOG(isReadSuc, "Create output buffer from parcel failed");
257 if (filter == ELEM_GET_AVMEMORY) {
258 AVBufferToAVSharedMemory(elem.buffer, elem.memory);
259 if (converter_ != nullptr) {
260 converter_->SetOutputBufferFormat(elem.buffer);
261 converter_->ReadFromBuffer(elem.buffer, elem.memory);
262 }
263 }
264 }
265
CheckReadFromParcelResult(const BufferElem & elem,const UpdateFilter filter)266 bool CheckReadFromParcelResult(const BufferElem &elem, const UpdateFilter filter)
267 {
268 switch (filter) {
269 case ELEM_GET_AVBUFFER:
270 return true;
271 case ELEM_GET_AVMEMORY:
272 return elem.buffer != nullptr;
273 case ELEM_GET_PARAMETER:
274 return elem.buffer != nullptr && elem.parameter != nullptr;
275 case ELEM_GET_ATRRIBUTE:
276 return elem.buffer != nullptr && elem.parameter != nullptr && elem.attribute != nullptr;
277 default:
278 AVCODEC_LOGE("unknown filter:%{public}d", static_cast<int32_t>(filter));
279 break;
280 }
281 return false;
282 }
283
284 enum class CacheFlag : uint8_t {
285 HIT_CACHE = 1,
286 UPDATE_CACHE,
287 INVALIDATE_CACHE,
288 };
289 bool isOutput_ = false;
290 CacheFlag flag_ = CacheFlag::INVALIDATE_CACHE;
291 std::shared_mutex mutex_;
292 std::unordered_map<uint32_t, BufferElem> caches_;
293 std::shared_ptr<BufferConverter> converter_ = nullptr;
294
295 const OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "ClientCaches"};
296 std::string tag_ = "";
297 };
298
CodecListenerStub()299 CodecListenerStub::CodecListenerStub()
300 {
301 if (inputBufferCache_ == nullptr) {
302 inputBufferCache_ = std::make_unique<CodecBufferCache>(false);
303 }
304
305 if (outputBufferCache_ == nullptr) {
306 outputBufferCache_ = std::make_unique<CodecBufferCache>(true);
307 }
308 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
309 }
310
~CodecListenerStub()311 CodecListenerStub::~CodecListenerStub()
312 {
313 inputBufferCache_ = nullptr;
314 outputBufferCache_ = nullptr;
315 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
316 }
317
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)318 int CodecListenerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option)
319 {
320 auto remoteDescriptor = data.ReadInterfaceToken();
321 CHECK_AND_RETURN_RET_LOG(CodecListenerStub::GetDescriptor() == remoteDescriptor, AVCS_ERR_INVALID_OPERATION,
322 "Invalid descriptor");
323 CHECK_AND_RETURN_RET_LOG(inputBufferCache_ != nullptr, AVCS_ERR_INVALID_OPERATION, "inputBufferCache is nullptr");
324 CHECK_AND_RETURN_RET_LOG(outputBufferCache_ != nullptr, AVCS_ERR_INVALID_OPERATION, "outputBufferCache is nullptr");
325
326 CHECK_AND_RETURN_RET_LOG(syncMutex_ != nullptr, AVCS_ERR_INVALID_OPERATION, "sync mutex is nullptr");
327 std::lock_guard<std::recursive_mutex> lock(*syncMutex_);
328 if (!needListen_ || !CheckGeneration(data.ReadUint64())) {
329 AVCODEC_LOGW_LIMIT(LOG_FREQ, "abandon message");
330 return AVCS_ERR_OK;
331 }
332 switch (code) {
333 case static_cast<uint32_t>(CodecListenerInterfaceCode::ON_ERROR): {
334 int32_t errorType = data.ReadInt32();
335 int32_t errorCode = data.ReadInt32();
336 OnError(static_cast<AVCodecErrorType>(errorType), errorCode);
337 return AVCS_ERR_OK;
338 }
339 case static_cast<uint32_t>(CodecListenerInterfaceCode::ON_OUTPUT_FORMAT_CHANGED): {
340 Format format;
341 (void)AVCodecParcel::Unmarshalling(data, format);
342 outputBufferCache_->ClearCaches();
343 OnOutputFormatChanged(format);
344 return AVCS_ERR_OK;
345 }
346 case static_cast<uint32_t>(CodecListenerInterfaceCode::ON_INPUT_BUFFER_AVAILABLE): {
347 uint32_t index = data.ReadUint32();
348 OnInputBufferAvailable(index, data);
349 return AVCS_ERR_OK;
350 }
351 case static_cast<uint32_t>(CodecListenerInterfaceCode::ON_OUTPUT_BUFFER_AVAILABLE): {
352 uint32_t index = data.ReadUint32();
353 OnOutputBufferAvailable(index, data);
354 return AVCS_ERR_OK;
355 }
356 default: {
357 AVCODEC_LOGE("Default case, please check codec listener stub");
358 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
359 }
360 }
361 }
362
OnError(AVCodecErrorType errorType,int32_t errorCode)363 void CodecListenerStub::OnError(AVCodecErrorType errorType, int32_t errorCode)
364 {
365 std::shared_ptr<MediaCodecCallback> vCb = videoCallback_.lock();
366 if (vCb != nullptr) {
367 vCb->OnError(errorType, errorCode);
368 return;
369 }
370 std::shared_ptr<AVCodecCallback> cb = callback_.lock();
371 if (cb != nullptr) {
372 cb->OnError(errorType, errorCode);
373 return;
374 }
375 }
376
OnOutputFormatChanged(const Format & format)377 void CodecListenerStub::OnOutputFormatChanged(const Format &format)
378 {
379 std::shared_ptr<MediaCodecCallback> vCb = videoCallback_.lock();
380 if (vCb != nullptr) {
381 vCb->OnOutputFormatChanged(format);
382 return;
383 }
384 std::shared_ptr<AVCodecCallback> cb = callback_.lock();
385 if (cb != nullptr) {
386 cb->OnOutputFormatChanged(format);
387 return;
388 }
389 }
390
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)391 void CodecListenerStub::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
392 {
393 (void)index;
394 (void)buffer;
395 }
396
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)397 void CodecListenerStub::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
398 {
399 (void)index;
400 (void)buffer;
401 }
402
OnInputBufferAvailable(uint32_t index,MessageParcel & data)403 void CodecListenerStub::OnInputBufferAvailable(uint32_t index, MessageParcel &data)
404 {
405 BufferElem elem;
406 std::shared_ptr<MediaCodecParameterCallback> paramCb = paramCallback_.lock();
407 if (paramCb != nullptr) {
408 bool ret = inputBufferCache_->ReadFromParcel(index, data, elem, ELEM_GET_PARAMETER);
409 CHECK_AND_RETURN_LOG(ret, "read from parel failed");
410 paramCb->OnInputParameterAvailable(index, elem.parameter);
411 elem.buffer->meta_ = elem.parameter->GetMeta();
412 return;
413 }
414 std::shared_ptr<MediaCodecParameterWithAttrCallback> attrCb = paramWithAttrCallback_.lock();
415 if (attrCb != nullptr) {
416 bool ret = inputBufferCache_->ReadFromParcel(index, data, elem, ELEM_GET_ATRRIBUTE);
417 CHECK_AND_RETURN_LOG(ret, "read from parel failed");
418 attrCb->OnInputParameterWithAttrAvailable(index, elem.attribute, elem.parameter);
419 elem.buffer->meta_ = elem.parameter->GetMeta();
420 return;
421 }
422 std::shared_ptr<MediaCodecCallback> mediaCb = videoCallback_.lock();
423 if (mediaCb != nullptr) {
424 bool ret = inputBufferCache_->ReadFromParcel(index, data, elem, ELEM_GET_AVBUFFER);
425 CHECK_AND_RETURN_LOG(ret, "read from parel failed");
426 mediaCb->OnInputBufferAvailable(index, elem.buffer);
427 return;
428 }
429 std::shared_ptr<AVCodecCallback> cb = callback_.lock();
430 if (cb != nullptr) {
431 bool ret = inputBufferCache_->ReadFromParcel(index, data, elem, ELEM_GET_AVMEMORY);
432 CHECK_AND_RETURN_LOG(ret, "read from parel failed");
433 cb->OnInputBufferAvailable(index, elem.memory);
434 return;
435 }
436 }
437
OnOutputBufferAvailable(uint32_t index,MessageParcel & data)438 void CodecListenerStub::OnOutputBufferAvailable(uint32_t index, MessageParcel &data)
439 {
440 BufferElem elem;
441 std::shared_ptr<MediaCodecCallback> mediaCb = videoCallback_.lock();
442 if (mediaCb != nullptr) {
443 bool ret = outputBufferCache_->ReadFromParcel(index, data, elem, ELEM_GET_AVBUFFER);
444 CHECK_AND_RETURN_LOG(ret, "read from parel failed");
445 mediaCb->OnOutputBufferAvailable(index, elem.buffer);
446 return;
447 }
448 std::shared_ptr<AVCodecCallback> cb = callback_.lock();
449 if (cb != nullptr) {
450 bool ret = outputBufferCache_->ReadFromParcel(index, data, elem, ELEM_GET_AVMEMORY);
451 CHECK_AND_RETURN_LOG(ret, "read from parel failed");
452 std::shared_ptr<AVBuffer> &buffer = elem.buffer;
453 AVCodecBufferInfo info;
454 info.presentationTimeUs = buffer->pts_;
455 AVCodecBufferFlag flag = static_cast<AVCodecBufferFlag>(buffer->flag_);
456 if (buffer->memory_ != nullptr) {
457 info.offset = buffer->memory_->GetOffset();
458 info.size = buffer->memory_->GetSize();
459 }
460 cb->OnOutputBufferAvailable(index, info, flag, elem.memory);
461 return;
462 }
463 }
464
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)465 void CodecListenerStub::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
466 {
467 callback_ = callback;
468 }
469
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)470 void CodecListenerStub::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
471 {
472 videoCallback_ = callback;
473 }
474
SetCallback(const std::shared_ptr<MediaCodecParameterCallback> & callback)475 void CodecListenerStub::SetCallback(const std::shared_ptr<MediaCodecParameterCallback> &callback)
476 {
477 paramCallback_ = callback;
478 }
479
SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> & callback)480 void CodecListenerStub::SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> &callback)
481 {
482 paramWithAttrCallback_ = callback;
483 }
484
ClearListenerCache()485 void CodecListenerStub::ClearListenerCache()
486 {
487 inputBufferCache_->ClearCaches();
488 outputBufferCache_->ClearCaches();
489 }
490
FlushListenerCache()491 void CodecListenerStub::FlushListenerCache()
492 {
493 inputBufferCache_->FlushCaches();
494 outputBufferCache_->FlushCaches();
495 }
496
WriteInputMemoryToParcel(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,MessageParcel & data)497 bool CodecListenerStub::WriteInputMemoryToParcel(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
498 MessageParcel &data)
499 {
500 BufferElem elem;
501 inputBufferCache_->ReturnBufferToServer(index, elem);
502 std::shared_ptr<AVBuffer> &buffer = elem.buffer;
503 std::shared_ptr<AVSharedMemory> &memory = elem.memory;
504 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, false, "Get buffer is nullptr");
505 CHECK_AND_RETURN_RET_LOG(memory != nullptr, false, "Get memory is nullptr");
506 CHECK_AND_RETURN_RET_LOG(buffer->memory_ != nullptr, false, "Get buffer memory is nullptr");
507
508 if (converter_ != nullptr) {
509 buffer->memory_->SetSize(info.size);
510 converter_->WriteToBuffer(buffer, memory);
511 }
512 return data.WriteInt64(info.presentationTimeUs) && data.WriteInt32(info.offset) &&
513 data.WriteInt32(buffer->memory_->GetSize()) && data.WriteUint32(static_cast<uint32_t>(flag)) &&
514 buffer->meta_->ToParcel(data);
515 }
516
WriteInputBufferToParcel(uint32_t index,MessageParcel & data)517 bool CodecListenerStub::WriteInputBufferToParcel(uint32_t index, MessageParcel &data)
518 {
519 BufferElem elem;
520 inputBufferCache_->ReturnBufferToServer(index, elem);
521 std::shared_ptr<AVBuffer> &buffer = elem.buffer;
522 CHECK_AND_RETURN_RET_LOG(buffer != nullptr, false, "Get buffer is nullptr");
523 CHECK_AND_RETURN_RET_LOG(buffer->memory_ != nullptr, false, "Get buffer memory is nullptr");
524 CHECK_AND_RETURN_RET_LOG(buffer->meta_ != nullptr, false, "Get buffer meta is nullptr");
525
526 return data.WriteInt64(buffer->pts_) && data.WriteInt32(buffer->memory_->GetOffset()) &&
527 data.WriteInt32(buffer->memory_->GetSize()) && data.WriteUint32(buffer->flag_) &&
528 buffer->meta_->ToParcel(data);
529 }
530
WriteInputParameterToParcel(uint32_t index,MessageParcel & data)531 bool CodecListenerStub::WriteInputParameterToParcel(uint32_t index, MessageParcel &data)
532 {
533 BufferElem elem;
534 inputBufferCache_->ReturnBufferToServer(index, elem);
535 auto ¶m = elem.parameter;
536 CHECK_AND_RETURN_RET_LOG(elem.buffer != nullptr, false, "Get buffer is nullptr");
537 CHECK_AND_RETURN_RET_LOG(param != nullptr, false, "Get format is nullptr");
538 EXPECT_AND_LOGD(!(param->GetMeta()->Empty()), "index:%{public}u,pts:%{public}" PRId64 ",paramter:%{public}s", index,
539 elem.buffer->pts_, param->Stringify().c_str());
540
541 return param->GetMeta()->ToParcel(data);
542 }
543
WriteOutputBufferToParcel(uint32_t index,MessageParcel & data)544 bool CodecListenerStub::WriteOutputBufferToParcel(uint32_t index, MessageParcel &data)
545 {
546 (void)data;
547 BufferElem elem;
548 outputBufferCache_->ReturnBufferToServer(index, elem);
549 return true;
550 }
551
CheckGeneration(uint64_t messageGeneration) const552 bool CodecListenerStub::CheckGeneration(uint64_t messageGeneration) const
553 {
554 return messageGeneration >= GetGeneration();
555 }
556
SetMutex(std::shared_ptr<std::recursive_mutex> & mutex)557 void CodecListenerStub::SetMutex(std::shared_ptr<std::recursive_mutex> &mutex)
558 {
559 syncMutex_ = mutex;
560 }
561
SetConverter(std::shared_ptr<BufferConverter> & converter)562 void CodecListenerStub::SetConverter(std::shared_ptr<BufferConverter> &converter)
563 {
564 converter_ = converter;
565 inputBufferCache_->SetConverter(converter);
566 outputBufferCache_->SetConverter(converter);
567 }
568
SetNeedListen(const bool needListen)569 void CodecListenerStub::SetNeedListen(const bool needListen)
570 {
571 needListen_ = needListen;
572 }
573
InitLabel(const uint64_t uid)574 void CodecListenerStub::InitLabel(const uint64_t uid)
575 {
576 tag_ = "ListenerStub[";
577 tag_ += std::to_string(uid) + "]";
578 auto &label = const_cast<OHOS::HiviewDFX::HiLogLabel &>(LABEL);
579 label.tag = tag_.c_str();
580 inputBufferCache_->InitLabel(uid);
581 outputBufferCache_->InitLabel(uid);
582 }
583 } // namespace MediaAVCodec
584 } // namespace OHOS
585