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