• 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_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