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_client.h"
17 #include <cmath>
18 #include "avcodec_errors.h"
19 #include "codec_service_proxy.h"
20 #include "meta/meta_key.h"
21 
22 using namespace OHOS::Media;
23 namespace OHOS {
24 namespace MediaAVCodec {
Create(const sptr<IStandardCodecService> & ipcProxy,std::shared_ptr<ICodecService> & codec)25 int32_t CodecClient::Create(const sptr<IStandardCodecService> &ipcProxy, std::shared_ptr<ICodecService> &codec)
26 {
27     OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "CodecClient"};
28     CHECK_AND_RETURN_RET_LOG(ipcProxy != nullptr, AVCS_ERR_INVALID_VAL, "Ipc proxy is nullptr.");
29 
30     codec = std::make_shared<CodecClient>(ipcProxy);
31     CHECK_AND_RETURN_RET_LOG(codec != nullptr && std::static_pointer_cast<CodecClient>(codec)->syncMutex_ != nullptr,
32         AVCS_ERR_UNKNOWN, "Codec client is nullptr");
33 
34     int32_t ret = std::static_pointer_cast<CodecClient>(codec)->CreateListenerObject();
35     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Codec client create failed");
36 
37     AVCODEC_LOGI("Succeed");
38     return AVCS_ERR_OK;
39 }
40 
CodecClient(const sptr<IStandardCodecService> & ipcProxy)41 CodecClient::CodecClient(const sptr<IStandardCodecService> &ipcProxy)
42     : codecProxy_(ipcProxy), syncMutex_(std::make_shared<std::recursive_mutex>())
43 {
44     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
45 }
46 
~CodecClient()47 CodecClient::~CodecClient()
48 {
49     std::scoped_lock lock(mutex_, *syncMutex_);
50     if (codecProxy_ != nullptr) {
51         (void)codecProxy_->DestroyStub();
52         SetNeedListen(false);
53     }
54     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
55 }
56 
AVCodecServerDied()57 void CodecClient::AVCodecServerDied()
58 {
59     {
60         std::scoped_lock lock(mutex_, *syncMutex_);
61         codecProxy_ = nullptr;
62         listenerStub_ = nullptr;
63     }
64     OnError(AVCODEC_ERROR_INTERNAL, AVCS_ERR_SERVICE_DIED);
65 }
66 
CreateListenerObject()67 int32_t CodecClient::CreateListenerObject()
68 {
69     std::lock_guard<std::shared_mutex> lock(mutex_);
70     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
71 
72     listenerStub_ = new (std::nothrow) CodecListenerStub();
73     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec listener stub create failed");
74     listenerStub_->SetMutex(syncMutex_);
75 
76     sptr<IRemoteObject> object = listenerStub_->AsObject();
77     CHECK_AND_RETURN_RET_LOG(object != nullptr, AVCS_ERR_NO_MEMORY, "Listener object is nullptr.");
78 
79     int32_t ret = codecProxy_->SetListenerObject(object);
80     if (ret == AVCS_ERR_OK) {
81         UpdateGeneration();
82         AVCODEC_LOGI("Succeed");
83     }
84     static_cast<CodecServiceProxy *>(codecProxy_.GetRefPtr())->SetListener(listenerStub_);
85     return ret;
86 }
87 
InitLabel(AVCodecType type)88 void CodecClient::InitLabel(AVCodecType type)
89 {
90     static std::mutex g_mutex;
91     static uint64_t g_uid = 0;
92     {
93         std::lock_guard<std::mutex> lock(g_mutex);
94         uid_ = ++g_uid;
95     }
96     auto &label = const_cast<OHOS::HiviewDFX::HiLogLabel &>(LABEL);
97     switch (type) {
98         case AVCODEC_TYPE_VIDEO_ENCODER:
99             tag_ = "EncClient[";
100             break;
101         case AVCODEC_TYPE_VIDEO_DECODER:
102             tag_ = "DecClient[";
103             break;
104         default:
105             tag_ = "CodecClient[";
106             break;
107     }
108     tag_ += std::to_string(uid_) + "]";
109     label.tag = tag_.c_str();
110     if (codecProxy_ != nullptr) {
111         static_cast<CodecServiceProxy *>(codecProxy_.GetRefPtr())->InitLabel(uid_);
112     }
113     if (listenerStub_ != nullptr) {
114         listenerStub_->InitLabel(uid_);
115     }
116     type_ = type;
117 }
118 
Init(AVCodecType type,bool isMimeType,const std::string & name,Meta & callerInfo,API_VERSION apiVersion)119 int32_t CodecClient::Init(AVCodecType type, bool isMimeType, const std::string &name,
120                           Meta &callerInfo, API_VERSION apiVersion)
121 {
122     (void)apiVersion;
123     using namespace OHOS::Media;
124     InitLabel(type);
125     callerInfo.SetData(Tag::AV_CODEC_CALLER_PID, getprocpid());
126     callerInfo.SetData(Tag::AV_CODEC_CALLER_UID, getuid());
127     callerInfo.SetData(Tag::AV_CODEC_CALLER_PROCESS_NAME, std::string(program_invocation_name));
128 
129     std::lock_guard<std::shared_mutex> lock(mutex_);
130     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
131     converter_ = BufferConverter::Create(type);
132     CHECK_AND_RETURN_RET_LOG(converter_ != nullptr, AVCS_ERR_NO_MEMORY, "failed to create converter");
133     if (listenerStub_ != nullptr) {
134         listenerStub_->SetConverter(converter_);
135     }
136 
137     int32_t ret = codecProxy_->Init(type, isMimeType, name, callerInfo);
138     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
139     return ret;
140 }
141 
Configure(const Format & format)142 int32_t CodecClient::Configure(const Format &format)
143 {
144     std::lock_guard<std::shared_mutex> lock(mutex_);
145     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
146 
147     int32_t isSetParameterCb = (codecMode_ & CODEC_SET_PARAMETER_CALLBACK) != 0;
148     const_cast<Format &>(format).PutIntValue(Tag::VIDEO_ENCODER_ENABLE_SURFACE_INPUT_CALLBACK, isSetParameterCb);
149 
150     int32_t ret = codecProxy_->Configure(format);
151     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
152     if (!hasOnceConfigured_) {
153         hasOnceConfigured_ = ret == AVCS_ERR_OK;
154     }
155     return ret;
156 }
157 
Prepare()158 int32_t CodecClient::Prepare()
159 {
160     std::lock_guard<std::shared_mutex> lock(mutex_);
161     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
162 
163     int32_t ret = codecProxy_->Prepare();
164     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
165 
166     return ret;
167 }
168 
SetCustomBuffer(std::shared_ptr<AVBuffer> buffer)169 int32_t CodecClient::SetCustomBuffer(std::shared_ptr<AVBuffer> buffer)
170 {
171     std::lock_guard<std::shared_mutex> lock(mutex_);
172     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
173     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AVCS_ERR_INVALID_VAL, "buffer is nullptr");
174 
175     int32_t ret = codecProxy_->SetCustomBuffer(buffer);
176     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
177     return ret;
178 }
179 
Start()180 int32_t CodecClient::Start()
181 {
182     std::lock_guard<std::shared_mutex> lock(mutex_);
183     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
184     CHECK_AND_RETURN_RET_LOG(codecMode_ != CODEC_SET_PARAMETER_CALLBACK, AVCS_ERR_INVALID_STATE,
185                              "Not get input surface.");
186 
187     SetNeedListen(true);
188     int32_t ret = codecProxy_->Start();
189     if (ret == AVCS_ERR_OK) {
190         needUpdateGeneration_ = true;
191         AVCODEC_LOGI("Succeed");
192     } else {
193         SetNeedListen(needUpdateGeneration_); // is in running state = needUpdateGeneration_
194     }
195     return ret;
196 }
197 
Stop()198 int32_t CodecClient::Stop()
199 {
200     int32_t ret;
201     {
202         std::scoped_lock lock(mutex_, *syncMutex_);
203         CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
204         ret = codecProxy_->Stop();
205         SetNeedListen(false);
206     }
207     if (ret == AVCS_ERR_OK) {
208         UpdateGeneration();
209         AVCODEC_LOGI("Succeed");
210     }
211     return ret;
212 }
213 
Flush()214 int32_t CodecClient::Flush()
215 {
216     int32_t ret;
217     {
218         std::scoped_lock lock(mutex_, *syncMutex_);
219         CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
220         ret = codecProxy_->Flush();
221         SetNeedListen(false);
222     }
223     if (ret == AVCS_ERR_OK) {
224         UpdateGeneration();
225         AVCODEC_LOGI("Succeed");
226     }
227     return ret;
228 }
229 
NotifyEos()230 int32_t CodecClient::NotifyEos()
231 {
232     std::lock_guard<std::shared_mutex> lock(mutex_);
233     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
234 
235     int32_t ret = codecProxy_->NotifyEos();
236     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
237     return ret;
238 }
239 
Reset()240 int32_t CodecClient::Reset()
241 {
242     int32_t ret;
243     {
244         std::scoped_lock lock(mutex_, *syncMutex_);
245         CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
246         ret = codecProxy_->Reset();
247         SetNeedListen(false);
248     }
249     if (ret == AVCS_ERR_OK) {
250         hasOnceConfigured_ = false;
251         if (converter_ != nullptr) {
252             converter_->NeedToResetFormatOnce();
253         }
254         UpdateGeneration();
255         AVCODEC_LOGI("Succeed");
256     }
257     return ret;
258 }
259 
Release()260 int32_t CodecClient::Release()
261 {
262     std::scoped_lock lock(mutex_, *syncMutex_);
263     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
264 
265     int32_t ret = codecProxy_->Release();
266     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
267     (void)codecProxy_->DestroyStub();
268     SetNeedListen(false);
269     codecProxy_ = nullptr;
270     listenerStub_ = nullptr;
271     return ret;
272 }
273 
CreateInputSurface()274 sptr<OHOS::Surface> CodecClient::CreateInputSurface()
275 {
276     std::lock_guard<std::shared_mutex> lock(mutex_);
277     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, nullptr, "Server not exist");
278 
279     auto ret = codecProxy_->CreateInputSurface();
280     EXPECT_AND_LOGI(ret != nullptr, "Succeed");
281     codecMode_ |= CODEC_SURFACE_MODE;
282     return ret;
283 }
284 
SetOutputSurface(sptr<Surface> surface)285 int32_t CodecClient::SetOutputSurface(sptr<Surface> surface)
286 {
287     std::lock_guard<std::shared_mutex> lock(mutex_);
288     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
289 
290     int32_t ret = codecProxy_->SetOutputSurface(surface);
291     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
292     codecMode_ = CODEC_SURFACE_MODE;
293     return ret;
294 }
295 
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)296 int32_t CodecClient::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
297 {
298     std::shared_lock<std::shared_mutex> lock(mutex_);
299     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
300     CHECK_AND_RETURN_RET_LOG(callbackMode_ == MEMORY_CALLBACK, AVCS_ERR_INVALID_STATE,
301                              "The callback of AVSharedMemory is invalid!");
302     int32_t ret = codecProxy_->QueueInputBuffer(index, info, flag);
303     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed. index:%{public}u", index);
304     return ret;
305 }
306 
QueueInputBuffer(uint32_t index)307 int32_t CodecClient::QueueInputBuffer(uint32_t index)
308 {
309     std::shared_lock<std::shared_mutex> lock(mutex_);
310     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
311     CHECK_AND_RETURN_RET_LOG(callbackMode_ == BUFFER_CALLBACK, AVCS_ERR_INVALID_STATE,
312                              "The callback of AVBuffer is invalid!");
313 
314     int32_t ret = codecProxy_->QueueInputBuffer(index);
315     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed. index:%{public}u", index);
316     return ret;
317 }
318 
QueueInputParameter(uint32_t index)319 int32_t CodecClient::QueueInputParameter(uint32_t index)
320 {
321     std::shared_lock<std::shared_mutex> lock(mutex_);
322     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
323     CHECK_AND_RETURN_RET_LOG(codecMode_ == CODEC_SURFACE_MODE_WITH_SETPARAMETER, AVCS_ERR_INVALID_STATE,
324                              "Is in invalid state!");
325 
326     int32_t ret = codecProxy_->QueueInputParameter(index);
327     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed. index:%{public}u", index);
328     return ret;
329 }
330 
GetOutputFormat(Format & format)331 int32_t CodecClient::GetOutputFormat(Format &format)
332 {
333     std::lock_guard<std::shared_mutex> lock(mutex_);
334     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
335 
336     int32_t ret = codecProxy_->GetOutputFormat(format);
337     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed");
338     if (callbackMode_ == MEMORY_CALLBACK && converter_ != nullptr) {
339         converter_->SetFormat(format);
340         converter_->GetFormat(format);
341     } else {
342         UpdateFormat(format);
343     }
344     return ret;
345 }
346 
347 #ifdef SUPPORT_DRM
SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)348 int32_t CodecClient::SetDecryptConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession, const bool svpFlag)
349 {
350     std::lock_guard<std::shared_mutex> lock(mutex_);
351     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Server not exist");
352     CHECK_AND_RETURN_RET_LOG(keySession != nullptr, AVCS_ERR_INVALID_OPERATION, "Server not exist");
353 
354     int32_t ret = codecProxy_->SetDecryptConfig(keySession, svpFlag);
355     EXPECT_AND_LOGI(ret == AVCS_ERR_OK, "Succeed");
356     return ret;
357 }
358 #endif
359 
ReleaseOutputBuffer(uint32_t index,bool render)360 int32_t CodecClient::ReleaseOutputBuffer(uint32_t index, bool render)
361 {
362     std::shared_lock<std::shared_mutex> lock(mutex_);
363     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
364     CHECK_AND_RETURN_RET_LOG(callbackMode_ != INVALID_CALLBACK, AVCS_ERR_INVALID_STATE, "The callback is invalid!");
365 
366     int32_t ret = codecProxy_->ReleaseOutputBuffer(index, render);
367     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed. index:%{public}u", index);
368     return ret;
369 }
370 
RenderOutputBufferAtTime(uint32_t index,int64_t renderTimestampNs)371 int32_t CodecClient::RenderOutputBufferAtTime(uint32_t index, int64_t renderTimestampNs)
372 {
373     std::shared_lock<std::shared_mutex> lock(mutex_);
374     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
375     CHECK_AND_RETURN_RET_LOG(callbackMode_ != INVALID_CALLBACK, AVCS_ERR_INVALID_STATE, "The callback is invalid!");
376     CHECK_AND_RETURN_RET_LOG(renderTimestampNs >= 0, AVCS_ERR_INVALID_VAL,
377                              "The renderTimestamp:%{public}" PRId64 " value error", renderTimestampNs);
378 
379     int32_t ret = codecProxy_->RenderOutputBufferAtTime(index, renderTimestampNs);
380     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed. index:%{public}u, renderTimestamp:%{public}" PRId64, index,
381                     renderTimestampNs);
382     return ret;
383 }
384 
SetParameter(const Format & format)385 int32_t CodecClient::SetParameter(const Format &format)
386 {
387     std::lock_guard<std::shared_mutex> lock(mutex_);
388     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
389 
390     int32_t ret = codecProxy_->SetParameter(format);
391     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed");
392     return ret;
393 }
394 
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)395 int32_t CodecClient::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
396 {
397     std::lock_guard<std::shared_mutex> lock(mutex_);
398     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_NO_MEMORY, "Callback is nullptr.");
399     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Listener stub is nullptr.");
400     CHECK_AND_RETURN_RET_LOG(callbackMode_ == MEMORY_CALLBACK || callbackMode_ == INVALID_CALLBACK,
401                              AVCS_ERR_INVALID_STATE, "The callback of AVBuffer is already set!");
402     callbackMode_ = MEMORY_CALLBACK;
403 
404     callback_ = callback;
405     const std::shared_ptr<AVCodecCallback> &stubCallback = shared_from_this();
406     listenerStub_->SetCallback(stubCallback);
407     AVCODEC_LOGI("AVSharedMemory callback");
408     return AVCS_ERR_OK;
409 }
410 
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)411 int32_t CodecClient::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
412 {
413     std::lock_guard<std::shared_mutex> lock(mutex_);
414     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_NO_MEMORY, "Callback is nullptr.");
415     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Listener stub is nullptr.");
416     CHECK_AND_RETURN_RET_LOG(callbackMode_ == BUFFER_CALLBACK || callbackMode_ == INVALID_CALLBACK,
417                              AVCS_ERR_INVALID_STATE, "The callback of AVSharedMemory is already set!");
418     callbackMode_ = BUFFER_CALLBACK;
419 
420     videoCallback_ = callback;
421     const std::shared_ptr<MediaCodecCallback> &stubCallback = shared_from_this();
422     listenerStub_->SetCallback(stubCallback);
423     AVCODEC_LOGI("AVBuffer callback");
424     return AVCS_ERR_OK;
425 }
426 
SetCallback(const std::shared_ptr<MediaCodecParameterCallback> & callback)427 int32_t CodecClient::SetCallback(const std::shared_ptr<MediaCodecParameterCallback> &callback)
428 {
429     std::lock_guard<std::shared_mutex> lock(mutex_);
430     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_NO_MEMORY, "Callback is nullptr.");
431     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Listener stub is nullptr.");
432     CHECK_AND_RETURN_RET_LOG(!hasOnceConfigured_, AVCS_ERR_INVALID_STATE, "Need to configure encoder!");
433     CHECK_AND_RETURN_RET_LOG(paramWithAttrCallback_ == nullptr, AVCS_ERR_INVALID_STATE,
434                              "Already set parameter with atrribute callback!");
435     codecMode_ |= CODEC_SET_PARAMETER_CALLBACK;
436 
437     paramCallback_ = callback;
438     const std::shared_ptr<MediaCodecParameterCallback> &stubCallback = shared_from_this();
439     listenerStub_->SetCallback(stubCallback);
440     AVCODEC_LOGI("Parameter callback");
441     return AVCS_ERR_OK;
442 }
443 
SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> & callback)444 int32_t CodecClient::SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> &callback)
445 {
446     std::lock_guard<std::shared_mutex> lock(mutex_);
447     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_NO_MEMORY, "Callback is nullptr.");
448     CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Listener stub is nullptr.");
449     CHECK_AND_RETURN_RET_LOG(!hasOnceConfigured_, AVCS_ERR_INVALID_STATE, "Need to configure encoder!");
450     CHECK_AND_RETURN_RET_LOG(paramCallback_ == nullptr, AVCS_ERR_INVALID_STATE, "Already set parameter callback!");
451     codecMode_ |= CODEC_SET_PARAMETER_CALLBACK;
452 
453     paramWithAttrCallback_ = callback;
454     const std::shared_ptr<MediaCodecParameterWithAttrCallback> &stubCallback = shared_from_this();
455     listenerStub_->SetCallback(stubCallback);
456     AVCODEC_LOGI("Parameter callback");
457     return AVCS_ERR_OK;
458 }
459 
GetInputFormat(Format & format)460 int32_t CodecClient::GetInputFormat(Format &format)
461 {
462     std::lock_guard<std::shared_mutex> lock(mutex_);
463     CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Server not exist");
464 
465     int32_t ret = codecProxy_->GetInputFormat(format);
466     EXPECT_AND_LOGD(ret == AVCS_ERR_OK, "Succeed");
467     if (callbackMode_ == MEMORY_CALLBACK && converter_ != nullptr) {
468         converter_->SetFormat(format);
469         converter_->GetFormat(format);
470     } else {
471         UpdateFormat(format);
472     }
473     return ret;
474 }
475 
UpdateGeneration()476 void CodecClient::UpdateGeneration()
477 {
478     if (listenerStub_ != nullptr && needUpdateGeneration_) {
479         listenerStub_->UpdateGeneration();
480         needUpdateGeneration_ = false;
481     }
482 }
483 
UpdateFormat(Format & format)484 void CodecClient::UpdateFormat(Format &format)
485 {
486     if (format.ContainKey(Tag::VIDEO_STRIDE) || format.ContainKey(Tag::VIDEO_SLICE_HEIGHT)) {
487         int32_t width = 0;
488         int32_t height = 0;
489         switch (type_) {
490             case AVCODEC_TYPE_VIDEO_ENCODER:
491                 format.GetIntValue(Tag::VIDEO_WIDTH, width);
492                 format.GetIntValue(Tag::VIDEO_HEIGHT, height);
493                 break;
494             case AVCODEC_TYPE_VIDEO_DECODER:
495                 format.GetIntValue(Tag::VIDEO_PIC_WIDTH, width);
496                 format.GetIntValue(Tag::VIDEO_PIC_HEIGHT, height);
497                 break;
498             default:
499                 return;
500         }
501         int32_t wStride = 0;
502         int32_t hStride = 0;
503         format.GetIntValue(Tag::VIDEO_STRIDE, wStride);
504         format.GetIntValue(Tag::VIDEO_SLICE_HEIGHT, hStride);
505         format.PutIntValue(Tag::VIDEO_STRIDE, std::max(width, wStride));
506         format.PutIntValue(Tag::VIDEO_SLICE_HEIGHT, std::max(height, hStride));
507     }
508 }
509 
SetNeedListen(const bool needListen)510 void CodecClient::SetNeedListen(const bool needListen)
511 {
512     if (listenerStub_ != nullptr) {
513         listenerStub_->SetNeedListen(needListen);
514     }
515 }
516 
OnError(AVCodecErrorType errorType,int32_t errorCode)517 void CodecClient::OnError(AVCodecErrorType errorType, int32_t errorCode)
518 {
519     if (callback_ != nullptr) {
520         callback_->OnError(errorType, errorCode);
521     } else if (videoCallback_ != nullptr) {
522         videoCallback_->OnError(errorType, errorCode);
523     }
524 }
525 
OnOutputFormatChanged(const Format & format)526 void CodecClient::OnOutputFormatChanged(const Format &format)
527 {
528     if (callback_ != nullptr) {
529         if (converter_ != nullptr) {
530             converter_->SetFormat(format);
531             converter_->GetFormat(const_cast<Format &>(format));
532         }
533         callback_->OnOutputFormatChanged(format);
534     } else if (videoCallback_ != nullptr) {
535         UpdateFormat(const_cast<Format &>(format));
536         videoCallback_->OnOutputFormatChanged(format);
537     }
538 }
539 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)540 void CodecClient::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
541 {
542     AVCODEC_LOGD("index:%{public}u", index);
543     callback_->OnInputBufferAvailable(index, buffer);
544 }
545 
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)546 void CodecClient::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
547                                           std::shared_ptr<AVSharedMemory> buffer)
548 {
549     AVCODEC_LOGD("index:%{public}u", index);
550     callback_->OnOutputBufferAvailable(index, info, flag, buffer);
551 }
552 
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)553 void CodecClient::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
554 {
555     AVCODEC_LOGD("index:%{public}u", index);
556     videoCallback_->OnInputBufferAvailable(index, buffer);
557 }
558 
OnOutputBufferAvailable(uint32_t index,std::shared_ptr<AVBuffer> buffer)559 void CodecClient::OnOutputBufferAvailable(uint32_t index, std::shared_ptr<AVBuffer> buffer)
560 {
561     AVCODEC_LOGD("index:%{public}u", index);
562     videoCallback_->OnOutputBufferAvailable(index, buffer);
563 }
564 
OnInputParameterAvailable(uint32_t index,std::shared_ptr<Format> parameter)565 void CodecClient::OnInputParameterAvailable(uint32_t index, std::shared_ptr<Format> parameter)
566 {
567     AVCODEC_LOGD("index:%{public}u", index);
568     paramCallback_->OnInputParameterAvailable(index, parameter);
569 }
570 
OnInputParameterWithAttrAvailable(uint32_t index,std::shared_ptr<Format> attribute,std::shared_ptr<Format> parameter)571 void CodecClient::OnInputParameterWithAttrAvailable(uint32_t index, std::shared_ptr<Format> attribute,
572                                                     std::shared_ptr<Format> parameter)
573 {
574     AVCODEC_LOGD("index:%{public}u", index);
575     paramWithAttrCallback_->OnInputParameterWithAttrAvailable(index, attribute, parameter);
576 }
577 } // namespace MediaAVCodec
578 } // namespace OHOS
579