1 /*
2 * Copyright (C) 2021 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 "avcodec_service_stub.h"
17 #include <unistd.h>
18 #include "avcodec_listener_proxy.h"
19 #include "avsharedmemory_ipc.h"
20 #include "media_errors.h"
21 #include "media_log.h"
22 #include "media_parcel.h"
23 #include "media_server_manager.h"
24
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecServiceStub"};
27 }
28
29 namespace OHOS {
30 namespace Media {
31 class AVCodecServiceStub::AVCodecBufferCache : public NoCopyable {
32 public:
33 AVCodecBufferCache() = default;
34 ~AVCodecBufferCache() = default;
35
WriteToParcel(uint32_t index,const std::shared_ptr<AVSharedMemory> & memory,MessageParcel & parcel)36 int32_t WriteToParcel(uint32_t index, const std::shared_ptr<AVSharedMemory> &memory, MessageParcel &parcel)
37 {
38 CacheFlag flag = CacheFlag::UPDATE_CACHE;
39
40 if (memory == nullptr || memory->GetBase() == nullptr) {
41 MEDIA_LOGE("invalid memory for index: %{public}u", index);
42 flag = CacheFlag::INVALIDATE_CACHE;
43 parcel.WriteUint8(flag);
44 auto iter = caches_.find(index);
45 if (iter != caches_.end()) {
46 iter->second = nullptr;
47 caches_.erase(iter);
48 }
49 return MSERR_OK;
50 }
51
52 auto iter = caches_.find(index);
53 if (iter != caches_.end() && iter->second == memory.get()) {
54 flag = CacheFlag::HIT_CACHE;
55 parcel.WriteUint8(flag);
56 return MSERR_OK;
57 }
58
59 if (iter == caches_.end()) {
60 MEDIA_LOGI("add cached codec buffer, index: %{public}u", index);
61 caches_.emplace(index, memory.get());
62 } else {
63 MEDIA_LOGI("update cached codec buffer, index: %{public}u", index);
64 iter->second = memory.get();
65 }
66
67 parcel.WriteUint8(flag);
68 return WriteAVSharedMemoryToParcel(memory, parcel);
69 }
70
71 private:
72 enum CacheFlag : uint8_t {
73 HIT_CACHE = 1,
74 UPDATE_CACHE,
75 INVALIDATE_CACHE,
76 };
77
78 std::unordered_map<uint32_t, AVSharedMemory *> caches_;
79 };
80
Create()81 sptr<AVCodecServiceStub> AVCodecServiceStub::Create()
82 {
83 sptr<AVCodecServiceStub> codecStub = new(std::nothrow) AVCodecServiceStub();
84 CHECK_AND_RETURN_RET_LOG(codecStub != nullptr, nullptr, "failed to new AVCodecServiceStub");
85
86 int32_t ret = codecStub->Init();
87 CHECK_AND_RETURN_RET_LOG(ret == MSERR_OK, nullptr, "failed to codec stub init");
88 return codecStub;
89 }
90
AVCodecServiceStub()91 AVCodecServiceStub::AVCodecServiceStub()
92 {
93 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
94 }
95
~AVCodecServiceStub()96 AVCodecServiceStub::~AVCodecServiceStub()
97 {
98 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
99 }
100
Init()101 int32_t AVCodecServiceStub::Init()
102 {
103 codecServer_ = AVCodecServer::Create();
104 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "failed to create AVCodecServer");
105
106 recFuncs_[SET_LISTENER_OBJ] = &AVCodecServiceStub::SetListenerObject;
107 recFuncs_[INIT_PARAMETER] = &AVCodecServiceStub::InitParameter;
108 recFuncs_[CONFIGURE] = &AVCodecServiceStub::Configure;
109 recFuncs_[PREPARE] = &AVCodecServiceStub::Prepare;
110 recFuncs_[START] = &AVCodecServiceStub::Start;
111 recFuncs_[STOP] = &AVCodecServiceStub::Stop;
112 recFuncs_[FLUSH] = &AVCodecServiceStub::Flush;
113 recFuncs_[RESET] = &AVCodecServiceStub::Reset;
114 recFuncs_[RELEASE] = &AVCodecServiceStub::Release;
115 recFuncs_[CREATE_INPUT_SURFACE] = &AVCodecServiceStub::CreateInputSurface;
116 recFuncs_[SET_OUTPUT_SURFACE] = &AVCodecServiceStub::SetOutputSurface;
117 recFuncs_[GET_INPUT_BUFFER] = &AVCodecServiceStub::GetInputBuffer;
118 recFuncs_[QUEUE_INPUT_BUFFER] = &AVCodecServiceStub::QueueInputBuffer;
119 recFuncs_[GET_OUTPUT_BUFFER] = &AVCodecServiceStub::GetOutputBuffer;
120 recFuncs_[RELEASE_OUTPUT_BUFFER] = &AVCodecServiceStub::ReleaseOutputBuffer;
121 recFuncs_[GET_OUTPUT_FORMAT] = &AVCodecServiceStub::GetOutputFormat;
122 recFuncs_[GET_AUDIO_CAPS] = &AVCodecServiceStub::GetAudioCaps;
123 recFuncs_[GET_VIDEO_CAPS] = &AVCodecServiceStub::GetVideoCaps;
124 recFuncs_[SET_PARAMETER] = &AVCodecServiceStub::SetParameter;
125 recFuncs_[DESTROY] = &AVCodecServiceStub::DestroyStub;
126 return MSERR_OK;
127 }
128
DestroyStub()129 int32_t AVCodecServiceStub::DestroyStub()
130 {
131 codecServer_ = nullptr;
132 outputBufferCache_ = nullptr;
133 inputBufferCache_ = nullptr;
134
135 MediaServerManager::GetInstance().DestroyStubObject(MediaServerManager::AVCODEC, AsObject());
136 return MSERR_OK;
137 }
138
OnRemoteRequest(uint32_t code,MessageParcel & data,MessageParcel & reply,MessageOption & option)139 int AVCodecServiceStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply,
140 MessageOption &option)
141 {
142 auto remoteDescriptor = data.ReadInterfaceToken();
143 if (AVCodecServiceStub::GetDescriptor() != remoteDescriptor) {
144 MEDIA_LOGE("Invalid descriptor");
145 return MSERR_INVALID_OPERATION;
146 }
147
148 auto itFunc = recFuncs_.find(code);
149 if (itFunc != recFuncs_.end()) {
150 auto memberFunc = itFunc->second;
151 if (memberFunc != nullptr) {
152 int32_t ret = (this->*memberFunc)(data, reply);
153 if (ret != MSERR_OK) {
154 MEDIA_LOGE("calling memberFunc is failed.");
155 }
156 return MSERR_OK;
157 }
158 }
159 MEDIA_LOGW("AVCodecServiceStub: no member func supporting, applying default process");
160
161 return IPCObjectStub::OnRemoteRequest(code, data, reply, option);
162 }
163
SetListenerObject(const sptr<IRemoteObject> & object)164 int32_t AVCodecServiceStub::SetListenerObject(const sptr<IRemoteObject> &object)
165 {
166 CHECK_AND_RETURN_RET_LOG(object != nullptr, MSERR_NO_MEMORY, "set listener object is nullptr");
167
168 sptr<IStandardAVCodecListener> listener = iface_cast<IStandardAVCodecListener>(object);
169 CHECK_AND_RETURN_RET_LOG(listener != nullptr, MSERR_NO_MEMORY, "failed to convert IStandardAVCodecListener");
170
171 std::shared_ptr<AVCodecCallback> callback = std::make_shared<AVCodecListenerCallback>(listener);
172 CHECK_AND_RETURN_RET_LOG(callback != nullptr, MSERR_NO_MEMORY, "failed to new AVCodecListenerCallback");
173
174 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
175 (void)codecServer_->SetCallback(callback);
176 return MSERR_OK;
177 }
178
InitParameter(AVCodecType type,bool isMimeType,const std::string & name)179 int32_t AVCodecServiceStub::InitParameter(AVCodecType type, bool isMimeType, const std::string &name)
180 {
181 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
182 return codecServer_->InitParameter(type, isMimeType, name);
183 }
184
Configure(const Format & format)185 int32_t AVCodecServiceStub::Configure(const Format &format)
186 {
187 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
188 return codecServer_->Configure(format);
189 }
190
Prepare()191 int32_t AVCodecServiceStub::Prepare()
192 {
193 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
194 if (outputBufferCache_ == nullptr) {
195 outputBufferCache_ = std::make_unique<AVCodecBufferCache>();
196 }
197 if (inputBufferCache_ == nullptr) {
198 inputBufferCache_ = std::make_unique<AVCodecBufferCache>();
199 }
200 return codecServer_->Prepare();
201 }
202
Start()203 int32_t AVCodecServiceStub::Start()
204 {
205 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
206 return codecServer_->Start();
207 }
208
Stop()209 int32_t AVCodecServiceStub::Stop()
210 {
211 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
212 return codecServer_->Stop();
213 }
214
Flush()215 int32_t AVCodecServiceStub::Flush()
216 {
217 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
218 return codecServer_->Flush();
219 }
220
Reset()221 int32_t AVCodecServiceStub::Reset()
222 {
223 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
224 inputBufferCache_ = nullptr;
225 outputBufferCache_ = nullptr;
226 return codecServer_->Reset();
227 }
228
Release()229 int32_t AVCodecServiceStub::Release()
230 {
231 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
232 inputBufferCache_ = nullptr;
233 outputBufferCache_ = nullptr;
234 return codecServer_->Release();
235 }
236
CreateInputSurface()237 sptr<OHOS::Surface> AVCodecServiceStub::CreateInputSurface()
238 {
239 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, nullptr, "avcodec server is nullptr");
240 return codecServer_->CreateInputSurface();
241 }
242
SetOutputSurface(sptr<OHOS::Surface> surface)243 int32_t AVCodecServiceStub::SetOutputSurface(sptr<OHOS::Surface> surface)
244 {
245 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
246 return codecServer_->SetOutputSurface(surface);
247 }
248
GetInputBuffer(uint32_t index)249 std::shared_ptr<AVSharedMemory> AVCodecServiceStub::GetInputBuffer(uint32_t index)
250 {
251 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, nullptr, "avcodec server is nullptr");
252 return codecServer_->GetInputBuffer(index);
253 }
254
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)255 int32_t AVCodecServiceStub::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
256 {
257 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
258 return codecServer_->QueueInputBuffer(index, info, flag);
259 }
260
GetOutputBuffer(uint32_t index)261 std::shared_ptr<AVSharedMemory> AVCodecServiceStub::GetOutputBuffer(uint32_t index)
262 {
263 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, nullptr, "avcodec server is nullptr");
264 return codecServer_->GetOutputBuffer(index);
265 }
266
GetOutputFormat(Format & format)267 int32_t AVCodecServiceStub::GetOutputFormat(Format &format)
268 {
269 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
270 return codecServer_->GetOutputFormat(format);
271 }
272
GetAudioCaps()273 std::shared_ptr<AudioCaps> AVCodecServiceStub::GetAudioCaps()
274 {
275 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, nullptr, "avcodec server is nullptr");
276 return codecServer_->GetAudioCaps();
277 }
278
GetVideoCaps()279 std::shared_ptr<VideoCaps> AVCodecServiceStub::GetVideoCaps()
280 {
281 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, nullptr, "avcodec server is nullptr");
282 return codecServer_->GetVideoCaps();
283 }
284
ReleaseOutputBuffer(uint32_t index,bool render)285 int32_t AVCodecServiceStub::ReleaseOutputBuffer(uint32_t index, bool render)
286 {
287 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
288 return codecServer_->ReleaseOutputBuffer(index, render);
289 }
290
SetParameter(const Format & format)291 int32_t AVCodecServiceStub::SetParameter(const Format &format)
292 {
293 CHECK_AND_RETURN_RET_LOG(codecServer_ != nullptr, MSERR_NO_MEMORY, "avcodec server is nullptr");
294 return codecServer_->SetParameter(format);
295 }
296
SetListenerObject(MessageParcel & data,MessageParcel & reply)297 int32_t AVCodecServiceStub::SetListenerObject(MessageParcel &data, MessageParcel &reply)
298 {
299 sptr<IRemoteObject> object = data.ReadRemoteObject();
300 reply.WriteInt32(SetListenerObject(object));
301 return MSERR_OK;
302 }
303
InitParameter(MessageParcel & data,MessageParcel & reply)304 int32_t AVCodecServiceStub::InitParameter(MessageParcel &data, MessageParcel &reply)
305 {
306 AVCodecType type = static_cast<AVCodecType>(data.ReadInt32());
307 bool isMimeType = data.ReadBool();
308 std::string name = data.ReadString();
309 reply.WriteInt32(InitParameter(type, isMimeType, name));
310 return MSERR_OK;
311 }
312
Configure(MessageParcel & data,MessageParcel & reply)313 int32_t AVCodecServiceStub::Configure(MessageParcel &data, MessageParcel &reply)
314 {
315 Format format;
316 (void)MediaParcel::Unmarshalling(data, format);
317 reply.WriteInt32(Configure(format));
318 return MSERR_OK;
319 }
320
Prepare(MessageParcel & data,MessageParcel & reply)321 int32_t AVCodecServiceStub::Prepare(MessageParcel &data, MessageParcel &reply)
322 {
323 (void)data;
324 reply.WriteInt32(Prepare());
325 return MSERR_OK;
326 }
327
Start(MessageParcel & data,MessageParcel & reply)328 int32_t AVCodecServiceStub::Start(MessageParcel &data, MessageParcel &reply)
329 {
330 (void)data;
331 reply.WriteInt32(Start());
332 return MSERR_OK;
333 }
334
Stop(MessageParcel & data,MessageParcel & reply)335 int32_t AVCodecServiceStub::Stop(MessageParcel &data, MessageParcel &reply)
336 {
337 (void)data;
338 reply.WriteInt32(Stop());
339 return MSERR_OK;
340 }
341
Flush(MessageParcel & data,MessageParcel & reply)342 int32_t AVCodecServiceStub::Flush(MessageParcel &data, MessageParcel &reply)
343 {
344 (void)data;
345 reply.WriteInt32(Flush());
346 return MSERR_OK;
347 }
348
Reset(MessageParcel & data,MessageParcel & reply)349 int32_t AVCodecServiceStub::Reset(MessageParcel &data, MessageParcel &reply)
350 {
351 (void)data;
352 reply.WriteInt32(Reset());
353 return MSERR_OK;
354 }
355
Release(MessageParcel & data,MessageParcel & reply)356 int32_t AVCodecServiceStub::Release(MessageParcel &data, MessageParcel &reply)
357 {
358 (void)data;
359 reply.WriteInt32(Release());
360 return MSERR_OK;
361 }
362
CreateInputSurface(MessageParcel & data,MessageParcel & reply)363 int32_t AVCodecServiceStub::CreateInputSurface(MessageParcel &data, MessageParcel &reply)
364 {
365 sptr<OHOS::Surface> surface = CreateInputSurface();
366 if (surface != nullptr && surface->GetProducer() != nullptr) {
367 sptr<IRemoteObject> object = surface->GetProducer()->AsObject();
368 (void)reply.WriteRemoteObject(object);
369 }
370 return MSERR_OK;
371 }
372
SetOutputSurface(MessageParcel & data,MessageParcel & reply)373 int32_t AVCodecServiceStub::SetOutputSurface(MessageParcel &data, MessageParcel &reply)
374 {
375 sptr<IRemoteObject> object = data.ReadRemoteObject();
376 CHECK_AND_RETURN_RET_LOG(object != nullptr, MSERR_NO_MEMORY, "object is nullptr");
377
378 sptr<IBufferProducer> producer = iface_cast<IBufferProducer>(object);
379 CHECK_AND_RETURN_RET_LOG(producer != nullptr, MSERR_NO_MEMORY, "failed to convert object to producer");
380
381 sptr<OHOS::Surface> surface = OHOS::Surface::CreateSurfaceAsProducer(producer);
382 CHECK_AND_RETURN_RET_LOG(surface != nullptr, MSERR_NO_MEMORY, "failed to create surface");
383
384 std::string format = data.ReadString();
385 MEDIA_LOGI("surfaceFormat is %{public}s!", format.c_str());
386 const std::string surfaceFormat = "SURFACE_FORMAT";
387 (void)surface->SetUserData(surfaceFormat, format);
388 reply.WriteInt32(SetOutputSurface(surface));
389 return MSERR_OK;
390 }
391
GetInputBuffer(MessageParcel & data,MessageParcel & reply)392 int32_t AVCodecServiceStub::GetInputBuffer(MessageParcel &data, MessageParcel &reply)
393 {
394 CHECK_AND_RETURN_RET(inputBufferCache_ != nullptr, MSERR_INVALID_OPERATION);
395
396 uint32_t index = data.ReadUint32();
397 auto buffer = GetInputBuffer(index);
398 return inputBufferCache_->WriteToParcel(index, buffer, reply);
399 }
400
QueueInputBuffer(MessageParcel & data,MessageParcel & reply)401 int32_t AVCodecServiceStub::QueueInputBuffer(MessageParcel &data, MessageParcel &reply)
402 {
403 uint32_t index = data.ReadUint32();
404 AVCodecBufferInfo info;
405 info.presentationTimeUs = data.ReadInt64();
406 info.size = data.ReadInt32();
407 info.offset = data.ReadInt32();
408 AVCodecBufferFlag flag = static_cast<AVCodecBufferFlag>(data.ReadInt32());
409 reply.WriteInt32(QueueInputBuffer(index, info, flag));
410 return MSERR_OK;
411 }
412
GetOutputBuffer(MessageParcel & data,MessageParcel & reply)413 int32_t AVCodecServiceStub::GetOutputBuffer(MessageParcel &data, MessageParcel &reply)
414 {
415 CHECK_AND_RETURN_RET(outputBufferCache_ != nullptr, MSERR_INVALID_OPERATION);
416
417 uint32_t index = data.ReadUint32();
418 auto buffer = GetOutputBuffer(index);
419 return outputBufferCache_->WriteToParcel(index, buffer, reply);
420 }
421
GetOutputFormat(MessageParcel & data,MessageParcel & reply)422 int32_t AVCodecServiceStub::GetOutputFormat(MessageParcel &data, MessageParcel &reply)
423 {
424 (void)data;
425 Format format;
426 (void)GetOutputFormat(format);
427 (void)MediaParcel::Marshalling(reply, format);
428 return MSERR_OK;
429 }
430
GetAudioCaps(MessageParcel & data,MessageParcel & reply)431 int32_t AVCodecServiceStub::GetAudioCaps(MessageParcel &data, MessageParcel &reply)
432 {
433 (void)data;
434 (void)reply;
435 return MSERR_OK;
436 }
437
GetVideoCaps(MessageParcel & data,MessageParcel & reply)438 int32_t AVCodecServiceStub::GetVideoCaps(MessageParcel &data, MessageParcel &reply)
439 {
440 (void)data;
441 (void)reply;
442 return MSERR_OK;
443 }
444
ReleaseOutputBuffer(MessageParcel & data,MessageParcel & reply)445 int32_t AVCodecServiceStub::ReleaseOutputBuffer(MessageParcel &data, MessageParcel &reply)
446 {
447 uint32_t index = data.ReadUint32();
448 bool render = data.ReadBool();
449 reply.WriteInt32(ReleaseOutputBuffer(index, render));
450 return MSERR_OK;
451 }
452
SetParameter(MessageParcel & data,MessageParcel & reply)453 int32_t AVCodecServiceStub::SetParameter(MessageParcel &data, MessageParcel &reply)
454 {
455 Format format;
456 (void)MediaParcel::Unmarshalling(data, format);
457 reply.WriteInt32(SetParameter(format));
458 return MSERR_OK;
459 }
460
DestroyStub(MessageParcel & data,MessageParcel & reply)461 int32_t AVCodecServiceStub::DestroyStub(MessageParcel &data, MessageParcel &reply)
462 {
463 (void)data;
464 reply.WriteInt32(DestroyStub());
465 return MSERR_OK;
466 }
467 } // namespace Media
468 } // namespace OHOS
469