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 "avcodec_log.h"
18 #include "avcodec_errors.h"
19
20 namespace {
21 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "CodecClient"};
22 }
23
24 namespace OHOS {
25 namespace MediaAVCodec {
Create(const sptr<IStandardCodecService> & ipcProxy)26 std::shared_ptr<CodecClient> CodecClient::Create(const sptr<IStandardCodecService> &ipcProxy)
27 {
28 CHECK_AND_RETURN_RET_LOG(ipcProxy != nullptr, nullptr, "Ipc proxy is nullptr.");
29
30 std::shared_ptr<CodecClient> codec = std::make_shared<CodecClient>(ipcProxy);
31
32 int32_t ret = codec->CreateListenerObject();
33 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Codec client create failed");
34
35 AVCODEC_LOGI("Codec client create successful");
36 return codec;
37 }
38
CodecClient(const sptr<IStandardCodecService> & ipcProxy)39 CodecClient::CodecClient(const sptr<IStandardCodecService> &ipcProxy)
40 : codecProxy_(ipcProxy)
41 {
42 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
43 }
44
~CodecClient()45 CodecClient::~CodecClient()
46 {
47 std::lock_guard<std::shared_mutex> lock(mutex_);
48
49 if (codecProxy_ != nullptr) {
50 (void)codecProxy_->DestroyStub();
51 }
52 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
53 }
54
AVCodecServerDied()55 void CodecClient::AVCodecServerDied()
56 {
57 std::lock_guard<std::shared_mutex> lock(mutex_);
58 codecProxy_ = nullptr;
59 listenerStub_ = nullptr;
60
61 if (callback_ != nullptr) {
62 callback_->OnError(AVCODEC_ERROR_INTERNAL, AVCS_ERR_SERVICE_DIED);
63 } else {
64 AVCODEC_LOGD("Callback OnError is nullptr");
65 }
66 }
67
CreateListenerObject()68 int32_t CodecClient::CreateListenerObject()
69 {
70 std::lock_guard<std::shared_mutex> lock(mutex_);
71 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
72
73 listenerStub_ = new(std::nothrow) CodecListenerStub();
74 CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec listener stub create failed");
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("Codec client set listener object successful");
83 }
84 return ret;
85 }
86
Init(AVCodecType type,bool isMimeType,const std::string & name)87 int32_t CodecClient::Init(AVCodecType type, bool isMimeType, const std::string &name)
88 {
89 std::lock_guard<std::shared_mutex> lock(mutex_);
90 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
91
92 int32_t ret = codecProxy_->Init(type, isMimeType, name);
93 if (ret == AVCS_ERR_OK) {
94 AVCODEC_LOGI("Codec client init successful");
95 }
96 return ret;
97 }
98
Configure(const Format & format)99 int32_t CodecClient::Configure(const Format &format)
100 {
101 std::lock_guard<std::shared_mutex> lock(mutex_);
102 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
103
104 int32_t ret = codecProxy_->Configure(format);
105 if (ret == AVCS_ERR_OK) {
106 AVCODEC_LOGI("Codec client configure successful");
107 }
108 return ret;
109 }
110
Start()111 int32_t CodecClient::Start()
112 {
113 std::lock_guard<std::shared_mutex> lock(mutex_);
114 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
115
116 int32_t ret = codecProxy_->Start();
117 if (ret == AVCS_ERR_OK) {
118 needUpdateGeneration = true;
119 AVCODEC_LOGI("Codec client start successful");
120 }
121 return ret;
122 }
123
Stop()124 int32_t CodecClient::Stop()
125 {
126 int32_t ret;
127 {
128 std::lock_guard<std::shared_mutex> lock(mutex_);
129 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
130 ret = codecProxy_->Stop();
131 }
132 if (ret == AVCS_ERR_OK) {
133 UpdateGeneration();
134 WaitCallbackDone();
135 AVCODEC_LOGI("Codec client stop successful");
136 }
137 return ret;
138 }
139
Flush()140 int32_t CodecClient::Flush()
141 {
142 int32_t ret;
143 {
144 std::lock_guard<std::shared_mutex> lock(mutex_);
145 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
146 ret = codecProxy_->Flush();
147 }
148 if (ret == AVCS_ERR_OK) {
149 UpdateGeneration();
150 WaitCallbackDone();
151 AVCODEC_LOGI("Codec client flush successful");
152 }
153 return ret;
154 }
155
NotifyEos()156 int32_t CodecClient::NotifyEos()
157 {
158 std::lock_guard<std::shared_mutex> lock(mutex_);
159 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
160
161 int32_t ret = codecProxy_->NotifyEos();
162 if (ret == AVCS_ERR_OK) {
163 AVCODEC_LOGI("Codec client notify eos successful");
164 }
165 return ret;
166 }
167
Reset()168 int32_t CodecClient::Reset()
169 {
170 int32_t ret;
171 {
172 std::lock_guard<std::shared_mutex> lock(mutex_);
173 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
174 ret = codecProxy_->Reset();
175 }
176 if (ret == AVCS_ERR_OK) {
177 UpdateGeneration();
178 WaitCallbackDone();
179 AVCODEC_LOGI("Codec client reset successful");
180 }
181 return ret;
182 }
183
Release()184 int32_t CodecClient::Release()
185 {
186 std::lock_guard<std::shared_mutex> lock(mutex_);
187 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
188
189 int32_t ret = codecProxy_->Release();
190 (void)codecProxy_->DestroyStub();
191 codecProxy_ = nullptr;
192 if (ret == AVCS_ERR_OK) {
193 AVCODEC_LOGI("Codec client release successful");
194 }
195 return ret;
196 }
197
CreateInputSurface()198 sptr<OHOS::Surface> CodecClient::CreateInputSurface()
199 {
200 std::lock_guard<std::shared_mutex> lock(mutex_);
201 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, nullptr, "Codec service does not exist.");
202
203 auto ret = codecProxy_->CreateInputSurface();
204 if (ret == nullptr) {
205 AVCODEC_LOGI("Codec client create input surface successful");
206 }
207 return ret;
208 }
209
SetOutputSurface(sptr<Surface> surface)210 int32_t CodecClient::SetOutputSurface(sptr<Surface> surface)
211 {
212 std::lock_guard<std::shared_mutex> lock(mutex_);
213 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
214
215 int32_t ret = codecProxy_->SetOutputSurface(surface);
216 if (ret == AVCS_ERR_OK) {
217 AVCODEC_LOGI("Codec client set output surface successful");
218 }
219 return ret;
220 }
221
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)222 int32_t CodecClient::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
223 {
224 std::shared_lock<std::shared_mutex> lock(mutex_);
225 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
226
227 int32_t ret = codecProxy_->QueueInputBuffer(index, info, flag);
228 if (ret == AVCS_ERR_OK) {
229 AVCODEC_LOGD("Codec client queue input buffer successful");
230 }
231 return ret;
232 }
233
GetOutputFormat(Format & format)234 int32_t CodecClient::GetOutputFormat(Format &format)
235 {
236 std::lock_guard<std::shared_mutex> lock(mutex_);
237 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
238
239 int32_t ret = codecProxy_->GetOutputFormat(format);
240 if (ret == AVCS_ERR_OK) {
241 AVCODEC_LOGD("Codec client get output format successful");
242 }
243 return ret;
244 }
245
ReleaseOutputBuffer(uint32_t index,bool render)246 int32_t CodecClient::ReleaseOutputBuffer(uint32_t index, bool render)
247 {
248 std::shared_lock<std::shared_mutex> lock(mutex_);
249 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
250
251 int32_t ret = codecProxy_->ReleaseOutputBuffer(index, render);
252 if (ret == AVCS_ERR_OK) {
253 AVCODEC_LOGD("Codec client release output buffer successful");
254 }
255 return ret;
256 }
257
SetParameter(const Format & format)258 int32_t CodecClient::SetParameter(const Format &format)
259 {
260 std::lock_guard<std::shared_mutex> lock(mutex_);
261 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
262
263 int32_t ret = codecProxy_->SetParameter(format);
264 if (ret == AVCS_ERR_OK) {
265 AVCODEC_LOGI("Codec client set parameter successful");
266 }
267 return ret;
268 }
269
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)270 int32_t CodecClient::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
271 {
272 std::lock_guard<std::shared_mutex> lock(mutex_);
273 CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_NO_MEMORY, "Callback is nullptr.");
274 CHECK_AND_RETURN_RET_LOG(listenerStub_ != nullptr, AVCS_ERR_NO_MEMORY, "Listener stub is nullptr.");
275
276 callback_ = callback;
277 listenerStub_->SetCallback(callback);
278 AVCODEC_LOGI("Codec client set callback successful");
279 return AVCS_ERR_OK;
280 }
281
GetInputFormat(Format & format)282 int32_t CodecClient::GetInputFormat(Format &format)
283 {
284 std::lock_guard<std::shared_mutex> lock(mutex_);
285 CHECK_AND_RETURN_RET_LOG(codecProxy_ != nullptr, AVCS_ERR_NO_MEMORY, "Codec service does not exist.");
286
287 int32_t ret = codecProxy_->GetInputFormat(format);
288 if (ret == AVCS_ERR_OK) {
289 AVCODEC_LOGI("Codec client get input format successful");
290 }
291 return ret;
292 }
293
UpdateGeneration()294 void CodecClient::UpdateGeneration()
295 {
296 if (listenerStub_ != nullptr && needUpdateGeneration) {
297 listenerStub_->UpdateGeneration();
298 needUpdateGeneration = false;
299 }
300 }
301
WaitCallbackDone()302 void CodecClient::WaitCallbackDone()
303 {
304 if (listenerStub_ != nullptr) {
305 listenerStub_->WaitCallbackDone();
306 }
307 }
308 } // namespace MediaAVCodec
309 } // namespace OHOS
310