• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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