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 &param = 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