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_proxy.h"
17 #include "avcodec_listener_stub.h"
18 #include "avsharedmemory_ipc.h"
19 #include "media_errors.h"
20 #include "media_log.h"
21 #include "media_parcel.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecServiceProxy"};
25 }
26
27 namespace OHOS {
28 namespace Media {
29 class AVCodecServiceProxy::AVCodecBufferCache : public NoCopyable {
30 public:
31 AVCodecBufferCache() = default;
32 ~AVCodecBufferCache() = default;
33
ReadFromParcel(uint32_t index,MessageParcel & parcel,std::shared_ptr<AVSharedMemory> & memory)34 int32_t ReadFromParcel(uint32_t index, MessageParcel &parcel, std::shared_ptr<AVSharedMemory> &memory)
35 {
36 auto iter = caches_.find(index);
37 CacheFlag flag = static_cast<CacheFlag>(parcel.ReadUint8());
38 if (flag == CacheFlag::HIT_CACHE) {
39 if (iter == caches_.end()) {
40 MEDIA_LOGE("mark hit cache, but can find the index's cache, index: %{public}u", index);
41 return MSERR_INVALID_VAL;
42 }
43 memory = iter->second;
44 return MSERR_OK;
45 }
46
47 if (flag == CacheFlag::UPDATE_CACHE) {
48 memory = ReadAVSharedMemoryFromParcel(parcel);
49 CHECK_AND_RETURN_RET(memory != nullptr, MSERR_INVALID_VAL);
50 if (iter == caches_.end()) {
51 MEDIA_LOGI("add cache, index: %{public}u", index);
52 caches_.emplace(index, memory);
53 } else {
54 iter->second = memory;
55 MEDIA_LOGI("update cache, index: %{public}u", index);
56 }
57 return MSERR_OK;
58 }
59
60 // invalidate cache flag
61 if (iter != caches_.end()) {
62 iter->second = nullptr;
63 caches_.erase(iter);
64 }
65 memory = nullptr;
66 MEDIA_LOGE("invalidate cache for index: %{public}u, flag: %{public}hhu", index, flag);
67 return MSERR_INVALID_VAL;
68 }
69
70 private:
71 enum CacheFlag : uint8_t {
72 HIT_CACHE = 1,
73 UPDATE_CACHE,
74 INVALIDATE_CACHE,
75 };
76
77 std::unordered_map<uint32_t, std::shared_ptr<AVSharedMemory>> caches_;
78 };
79
AVCodecServiceProxy(const sptr<IRemoteObject> & impl)80 AVCodecServiceProxy::AVCodecServiceProxy(const sptr<IRemoteObject> &impl)
81 : IRemoteProxy<IStandardAVCodecService>(impl)
82 {
83 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
84 }
85
~AVCodecServiceProxy()86 AVCodecServiceProxy::~AVCodecServiceProxy()
87 {
88 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
89 }
90
SetListenerObject(const sptr<IRemoteObject> & object)91 int32_t AVCodecServiceProxy::SetListenerObject(const sptr<IRemoteObject> &object)
92 {
93 MessageParcel data;
94 MessageParcel reply;
95 MessageOption option;
96
97 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
98 MEDIA_LOGE("Failed to write descriptor");
99 return MSERR_UNKNOWN;
100 }
101
102 (void)data.WriteRemoteObject(object);
103 int32_t ret = Remote()->SendRequest(SET_LISTENER_OBJ, data, reply, option);
104 if (ret != MSERR_OK) {
105 MEDIA_LOGE("Set listener obj failed, error: %{public}d", ret);
106 return ret;
107 }
108 return reply.ReadInt32();
109 }
110
InitParameter(AVCodecType type,bool isMimeType,const std::string & name)111 int32_t AVCodecServiceProxy::InitParameter(AVCodecType type, bool isMimeType, const std::string &name)
112 {
113 MessageParcel data;
114 MessageParcel reply;
115 MessageOption option;
116
117 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
118 MEDIA_LOGE("Failed to write descriptor");
119 return MSERR_UNKNOWN;
120 }
121
122 data.WriteInt32(static_cast<int32_t>(type));
123 data.WriteBool(isMimeType);
124 data.WriteString(name);
125 int32_t ret = Remote()->SendRequest(INIT_PARAMETER, data, reply, option);
126 if (ret != MSERR_OK) {
127 MEDIA_LOGE("Init parameter failed, error: %{public}d", ret);
128 return ret;
129 }
130 return reply.ReadInt32();
131 }
132
Configure(const Format & format)133 int32_t AVCodecServiceProxy::Configure(const Format &format)
134 {
135 MessageParcel data;
136 MessageParcel reply;
137 MessageOption option;
138
139 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
140 MEDIA_LOGE("Failed to write descriptor");
141 return MSERR_UNKNOWN;
142 }
143
144 (void)MediaParcel::Marshalling(data, format);
145 int32_t ret = Remote()->SendRequest(CONFIGURE, data, reply, option);
146 if (ret != MSERR_OK) {
147 MEDIA_LOGE("Set listener obj failed, error: %{public}d", ret);
148 return ret;
149 }
150 return reply.ReadInt32();
151 }
152
Prepare()153 int32_t AVCodecServiceProxy::Prepare()
154 {
155 if (inputBufferCache_ == nullptr) {
156 inputBufferCache_ = std::make_unique<AVCodecBufferCache>();
157 }
158
159 if (outputBufferCache_ == nullptr) {
160 outputBufferCache_ = std::make_unique<AVCodecBufferCache>();
161 }
162
163 MessageParcel data;
164 MessageParcel reply;
165 MessageOption option;
166
167 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
168 MEDIA_LOGE("Failed to write descriptor");
169 return MSERR_UNKNOWN;
170 }
171
172 int32_t ret = Remote()->SendRequest(PREPARE, data, reply, option);
173 if (ret != MSERR_OK) {
174 MEDIA_LOGE("Prepare failed, error: %{public}d", ret);
175 return ret;
176 }
177 return reply.ReadInt32();
178 }
179
Start()180 int32_t AVCodecServiceProxy::Start()
181 {
182 MessageParcel data;
183 MessageParcel reply;
184 MessageOption option;
185
186 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
187 MEDIA_LOGE("Failed to write descriptor");
188 return MSERR_UNKNOWN;
189 }
190
191 int32_t ret = Remote()->SendRequest(START, data, reply, option);
192 if (ret != MSERR_OK) {
193 MEDIA_LOGE("Start failed, error: %{public}d", ret);
194 return ret;
195 }
196 return reply.ReadInt32();
197 }
198
Stop()199 int32_t AVCodecServiceProxy::Stop()
200 {
201 MessageParcel data;
202 MessageParcel reply;
203 MessageOption option;
204
205 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
206 MEDIA_LOGE("Failed to write descriptor");
207 return MSERR_UNKNOWN;
208 }
209
210 int32_t ret = Remote()->SendRequest(STOP, data, reply, option);
211 if (ret != MSERR_OK) {
212 MEDIA_LOGE("Stop failed, error: %{public}d", ret);
213 return ret;
214 }
215 return reply.ReadInt32();
216 }
217
Flush()218 int32_t AVCodecServiceProxy::Flush()
219 {
220 MessageParcel data;
221 MessageParcel reply;
222 MessageOption option;
223
224 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
225 MEDIA_LOGE("Failed to write descriptor");
226 return MSERR_UNKNOWN;
227 }
228
229 int32_t ret = Remote()->SendRequest(FLUSH, data, reply, option);
230 if (ret != MSERR_OK) {
231 MEDIA_LOGE("Flush failed, error: %{public}d", ret);
232 return ret;
233 }
234 return reply.ReadInt32();
235 }
236
NotifyEos()237 int32_t AVCodecServiceProxy::NotifyEos()
238 {
239 MessageParcel data;
240 MessageParcel reply;
241 MessageOption option;
242
243 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
244 MEDIA_LOGE("Failed to write descriptor");
245 return MSERR_UNKNOWN;
246 }
247
248 int32_t ret = Remote()->SendRequest(NOTIFY_EOS, data, reply, option);
249 if (ret != MSERR_OK) {
250 MEDIA_LOGE("NotifyEos failed, error: %{public}d", ret);
251 return ret;
252 }
253 return reply.ReadInt32();
254 }
255
Reset()256 int32_t AVCodecServiceProxy::Reset()
257 {
258 inputBufferCache_ = nullptr;
259 outputBufferCache_ = nullptr;
260
261 MessageParcel data;
262 MessageParcel reply;
263 MessageOption option;
264
265 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
266 MEDIA_LOGE("Failed to write descriptor");
267 return MSERR_UNKNOWN;
268 }
269
270 int32_t ret = Remote()->SendRequest(RESET, data, reply, option);
271 if (ret != MSERR_OK) {
272 MEDIA_LOGE("Reset failed, error: %{public}d", ret);
273 return ret;
274 }
275 return reply.ReadInt32();
276 }
277
Release()278 int32_t AVCodecServiceProxy::Release()
279 {
280 inputBufferCache_ = nullptr;
281 outputBufferCache_ = nullptr;
282
283 MessageParcel data;
284 MessageParcel reply;
285 MessageOption option;
286
287 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
288 MEDIA_LOGE("Failed to write descriptor");
289 return MSERR_UNKNOWN;
290 }
291
292 int32_t ret = Remote()->SendRequest(RELEASE, data, reply, option);
293 if (ret != MSERR_OK) {
294 MEDIA_LOGE("Release failed, error: %{public}d", ret);
295 return ret;
296 }
297 return reply.ReadInt32();
298 }
299
CreateInputSurface()300 sptr<OHOS::Surface> AVCodecServiceProxy::CreateInputSurface()
301 {
302 MessageParcel data;
303 MessageParcel reply;
304 MessageOption option;
305
306 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
307 MEDIA_LOGE("Failed to write descriptor");
308 return nullptr;
309 }
310
311 int32_t ret = Remote()->SendRequest(CREATE_INPUT_SURFACE, data, reply, option);
312 if (ret != MSERR_OK) {
313 MEDIA_LOGE("CreateInputSurface failed, error: %{public}d", ret);
314 return nullptr;
315 }
316
317 sptr<IRemoteObject> object = reply.ReadRemoteObject();
318 if (object == nullptr) {
319 MEDIA_LOGE("failed to read surface object");
320 return nullptr;
321 }
322
323 sptr<IBufferProducer> producer = iface_cast<IBufferProducer>(object);
324 if (producer == nullptr) {
325 MEDIA_LOGE("failed to convert object to producer");
326 return nullptr;
327 }
328
329 return OHOS::Surface::CreateSurfaceAsProducer(producer);
330 }
331
SetOutputSurface(sptr<OHOS::Surface> surface)332 int32_t AVCodecServiceProxy::SetOutputSurface(sptr<OHOS::Surface> surface)
333 {
334 MessageParcel data;
335 MessageParcel reply;
336 MessageOption option;
337
338 CHECK_AND_RETURN_RET_LOG(surface != nullptr, MSERR_NO_MEMORY, "surface is nullptr");
339 sptr<IBufferProducer> producer = surface->GetProducer();
340 CHECK_AND_RETURN_RET_LOG(producer != nullptr, MSERR_NO_MEMORY, "producer is nullptr");
341
342 sptr<IRemoteObject> object = producer->AsObject();
343 CHECK_AND_RETURN_RET_LOG(object != nullptr, MSERR_NO_MEMORY, "object is nullptr");
344
345 const std::string surfaceFormat = "SURFACE_FORMAT";
346 std::string format = surface->GetUserData(surfaceFormat);
347 MEDIA_LOGI("surfaceFormat is %{public}s!", format.c_str());
348
349 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
350 MEDIA_LOGE("Failed to write descriptor");
351 return MSERR_UNKNOWN;
352 }
353
354 (void)data.WriteRemoteObject(object);
355 data.WriteString(format);
356 int32_t error = Remote()->SendRequest(SET_OUTPUT_SURFACE, data, reply, option);
357 if (error != MSERR_OK) {
358 MEDIA_LOGE("SetOutputSurface failed, error: %{public}d", error);
359 return error;
360 }
361 return reply.ReadInt32();
362 }
363
GetInputBuffer(uint32_t index)364 std::shared_ptr<AVSharedMemory> AVCodecServiceProxy::GetInputBuffer(uint32_t index)
365 {
366 MessageParcel data;
367 MessageParcel reply;
368 MessageOption option;
369
370 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
371 MEDIA_LOGE("Failed to write descriptor");
372 return nullptr;
373 }
374
375 data.WriteUint32(index);
376 int32_t ret = Remote()->SendRequest(GET_INPUT_BUFFER, data, reply, option);
377 if (ret != MSERR_OK) {
378 MEDIA_LOGE("GetInputBuffer failed, error: %{public}d", ret);
379 return nullptr;
380 }
381
382 std::shared_ptr<AVSharedMemory> memory = nullptr;
383 if (inputBufferCache_ != nullptr) {
384 ret = inputBufferCache_->ReadFromParcel(index, reply, memory);
385 CHECK_AND_RETURN_RET(ret == MSERR_OK, nullptr);
386 }
387 if (memory == nullptr) {
388 MEDIA_LOGE("Failed to GetInputBuffer");
389 return nullptr;
390 }
391 return memory;
392 }
393
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)394 int32_t AVCodecServiceProxy::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
395 {
396 MessageParcel data;
397 MessageParcel reply;
398 MessageOption option;
399
400 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
401 MEDIA_LOGE("Failed to write descriptor");
402 return MSERR_UNKNOWN;
403 }
404
405 data.WriteUint32(index);
406 data.WriteInt64(info.presentationTimeUs);
407 data.WriteInt32(info.size);
408 data.WriteInt32(info.offset);
409 data.WriteInt32(static_cast<int32_t>(flag));
410 int32_t ret = Remote()->SendRequest(QUEUE_INPUT_BUFFER, data, reply, option);
411 if (ret != MSERR_OK) {
412 MEDIA_LOGE("QueueInputBuffer failed, error: %{public}d", ret);
413 return ret;
414 }
415 return reply.ReadInt32();
416 }
417
GetOutputBuffer(uint32_t index)418 std::shared_ptr<AVSharedMemory> AVCodecServiceProxy::GetOutputBuffer(uint32_t index)
419 {
420 MessageParcel data;
421 MessageParcel reply;
422 MessageOption option;
423
424 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
425 MEDIA_LOGE("Failed to write descriptor");
426 return nullptr;
427 }
428
429 data.WriteUint32(index);
430 int32_t ret = Remote()->SendRequest(GET_OUTPUT_BUFFER, data, reply, option);
431 if (ret != MSERR_OK) {
432 MEDIA_LOGE("GetOutputBuffer failed, error: %{public}d", ret);
433 return nullptr;
434 }
435
436 std::shared_ptr<AVSharedMemory> memory = nullptr;
437 if (outputBufferCache_ != nullptr) {
438 ret = outputBufferCache_->ReadFromParcel(index, reply, memory);
439 CHECK_AND_RETURN_RET(ret == MSERR_OK, nullptr);
440 }
441 if (memory == nullptr) {
442 MEDIA_LOGE("Failed to GetOutputBuffer");
443 return nullptr;
444 }
445 return memory;
446 }
447
GetOutputFormat(Format & format)448 int32_t AVCodecServiceProxy::GetOutputFormat(Format &format)
449 {
450 MessageParcel data;
451 MessageParcel reply;
452 MessageOption option;
453
454 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
455 MEDIA_LOGE("Failed to write descriptor");
456 return MSERR_UNKNOWN;
457 }
458
459 int32_t ret = Remote()->SendRequest(GET_OUTPUT_FORMAT, data, reply, option);
460 if (ret != MSERR_OK) {
461 MEDIA_LOGE("GetOutputFormat failed, error: %{public}d", ret);
462 return ret;
463 }
464
465 (void)MediaParcel::Unmarshalling(reply, format);
466 return MSERR_OK;
467 }
468
ReleaseOutputBuffer(uint32_t index,bool render)469 int32_t AVCodecServiceProxy::ReleaseOutputBuffer(uint32_t index, bool render)
470 {
471 MessageParcel data;
472 MessageParcel reply;
473 MessageOption option;
474
475 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
476 MEDIA_LOGE("Failed to write descriptor");
477 return MSERR_UNKNOWN;
478 }
479
480 data.WriteUint32(index);
481 data.WriteBool(render);
482 int32_t ret = Remote()->SendRequest(RELEASE_OUTPUT_BUFFER, data, reply, option);
483 if (ret != MSERR_OK) {
484 MEDIA_LOGE("ReleaseOutputBuffer failed, error: %{public}d", ret);
485 return ret;
486 }
487 return reply.ReadInt32();
488 }
489
SetParameter(const Format & format)490 int32_t AVCodecServiceProxy::SetParameter(const Format &format)
491 {
492 MessageParcel data;
493 MessageParcel reply;
494 MessageOption option;
495
496 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
497 MEDIA_LOGE("Failed to write descriptor");
498 return MSERR_UNKNOWN;
499 }
500
501 (void)MediaParcel::Marshalling(data, format);
502 int32_t ret = Remote()->SendRequest(SET_PARAMETER, data, reply, option);
503 if (ret != MSERR_OK) {
504 MEDIA_LOGE("SetParameter failed, error: %{public}d", ret);
505 return ret;
506 }
507 return reply.ReadInt32();
508 }
509
DestroyStub()510 int32_t AVCodecServiceProxy::DestroyStub()
511 {
512 inputBufferCache_ = nullptr;
513 outputBufferCache_ = nullptr;
514
515 MessageParcel data;
516 MessageParcel reply;
517 MessageOption option;
518
519 if (!data.WriteInterfaceToken(AVCodecServiceProxy::GetDescriptor())) {
520 MEDIA_LOGE("Failed to write descriptor");
521 return MSERR_UNKNOWN;
522 }
523
524 int32_t ret = Remote()->SendRequest(DESTROY, data, reply, option);
525 if (ret != MSERR_OK) {
526 MEDIA_LOGE("destroy failed, error: %{public}d", ret);
527 return ret;
528 }
529
530 return reply.ReadInt32();
531 }
532 } // namespace Media
533 } // namespace OHOS
534