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 "media_data_source_proxy.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "media_dfx.h"
20 #include "avdatasrcmemory.h"
21 #include "avsharedmemory_ipc.h"
22 #include "meta/any.h"
23 
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "MediaDataSourceProxy"};
26 }
27 
28 namespace OHOS {
29 namespace Media {
30 namespace {
31 constexpr int32_t READ_AT_ERR_CODE = INT32_MIN;
32 }
33 
34 class MediaDataSourceProxy::BufferCache : public NoCopyable {
35 public:
BufferCache()36     BufferCache()
37     {
38         caches_ = nullptr;
39     }
~BufferCache()40     ~BufferCache()
41     {
42         caches_ = nullptr;
43     }
44 
WriteToParcel(const std::shared_ptr<AVSharedMemory> & memory,MessageParcel & parcel)45     int32_t WriteToParcel(const std::shared_ptr<AVSharedMemory> &memory, MessageParcel &parcel)
46     {
47         CHECK_AND_RETURN_RET_LOG(memory != nullptr, MSERR_NO_MEMORY, "memory is nullptr");
48         CacheFlag flag;
49         if (caches_ != nullptr && caches_ == memory.get() && uniqueSharedMemoryID_ == memory->GetSharedMemoryID()) {
50             MEDIA_LOGI("HIT_CACHE");
51             flag = CacheFlag::HIT_CACHE;
52             parcel.WriteUint8(static_cast<uint8_t>(flag));
53             return MSERR_OK;
54         } else {
55             MEDIA_LOGI("UPDATE_CACHE");
56             flag = CacheFlag::UPDATE_CACHE;
57             caches_ = memory.get();
58             uniqueSharedMemoryID_ = memory->GetSharedMemoryID();
59             parcel.WriteUint8(static_cast<uint8_t>(flag));
60             return WriteAVSharedMemoryToParcel(memory, parcel);
61         }
62     }
63 
64 private:
65     uint64_t uniqueSharedMemoryID_ = 0;
66     AVSharedMemory *caches_;
67 };
68 
MediaDataCallback(const sptr<IStandardMediaDataSource> & ipcProxy)69 MediaDataCallback::MediaDataCallback(const sptr<IStandardMediaDataSource> &ipcProxy)
70     : callbackProxy_(ipcProxy)
71 {
72     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
73 }
74 
~MediaDataCallback()75 MediaDataCallback::~MediaDataCallback()
76 {
77     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
78 }
79 
80 
ReadAt(const std::shared_ptr<AVSharedMemory> & mem,uint32_t length,int64_t pos)81 int32_t MediaDataCallback::ReadAt(const std::shared_ptr<AVSharedMemory> &mem, uint32_t length, int64_t pos)
82 {
83     MEDIA_LOGD("ReadAt in");
84     CHECK_AND_RETURN_RET_LOG(callbackProxy_ != nullptr, SOURCE_ERROR_IO, "callbackProxy_ is nullptr");
85     CHECK_AND_RETURN_RET_LOG(mem != nullptr, MSERR_NO_MEMORY, "memory is nullptr");
86     return callbackProxy_->ReadAt(mem, length, pos, false);
87 }
88 
ReadAt(int64_t pos,uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)89 int32_t MediaDataCallback::ReadAt(int64_t pos, uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
90 {
91     MEDIA_LOGD("ReadAt in");
92     CHECK_AND_RETURN_RET_LOG(callbackProxy_ != nullptr, SOURCE_ERROR_IO, "callbackProxy_ is nullptr");
93     CHECK_AND_RETURN_RET_LOG(mem != nullptr, MSERR_NO_MEMORY, "memory is nullptr");
94     return callbackProxy_->ReadAt(mem, length, pos, true);
95 }
96 
ReadAt(uint32_t length,const std::shared_ptr<AVSharedMemory> & mem)97 int32_t MediaDataCallback::ReadAt(uint32_t length, const std::shared_ptr<AVSharedMemory> &mem)
98 {
99     MEDIA_LOGD("ReadAt in");
100     CHECK_AND_RETURN_RET_LOG(callbackProxy_ != nullptr, SOURCE_ERROR_IO, "callbackProxy_ is nullptr");
101     CHECK_AND_RETURN_RET_LOG(mem != nullptr, MSERR_NO_MEMORY, "memory is nullptr");
102     return callbackProxy_->ReadAt(mem, length, 0, true);
103 }
104 
GetSize(int64_t & size)105 int32_t MediaDataCallback::GetSize(int64_t &size)
106 {
107     CHECK_AND_RETURN_RET_LOG(callbackProxy_ != nullptr, MSERR_INVALID_OPERATION, "callbackProxy_ is nullptr");
108     return callbackProxy_->GetSize(size);
109 }
110 
MediaDataSourceProxy(const sptr<IRemoteObject> & impl)111 MediaDataSourceProxy::MediaDataSourceProxy(const sptr<IRemoteObject> &impl)
112     : IRemoteProxy<IStandardMediaDataSource>(impl)
113 {
114     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
115 }
116 
~MediaDataSourceProxy()117 MediaDataSourceProxy::~MediaDataSourceProxy()
118 {
119     MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
120 }
121 
ReadAt(const std::shared_ptr<AVSharedMemory> & mem,uint32_t length,int64_t pos,bool isHistreamer)122 int32_t MediaDataSourceProxy::ReadAt(const std::shared_ptr<AVSharedMemory> &mem, uint32_t length, int64_t pos,
123     bool isHistreamer)
124 {
125     MEDIA_LOGD("ReadAt in");
126     CHECK_AND_RETURN_RET_LOG(mem != nullptr, MSERR_NO_MEMORY, "mem is nullptr");
127     MediaTrace trace("DataSrc::ReadAt");
128     MessageParcel data;
129     MessageParcel reply;
130     MessageOption option(MessageOption::TF_SYNC);
131 
132     bool token = data.WriteInterfaceToken(MediaDataSourceProxy::GetDescriptor());
133     CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!");
134 
135     if (BufferCache_ == nullptr) {
136         BufferCache_ = std::make_unique<BufferCache>();
137     }
138     CHECK_AND_RETURN_RET_LOG(BufferCache_ != nullptr, MSERR_NO_MEMORY, "Failed to create BufferCache_!");
139 
140     uint32_t offset = 0;
141     if (!isHistreamer) {
142         offset = std::static_pointer_cast<AVDataSrcMemory>(mem)->GetOffset();
143     }
144     MEDIA_LOGD("offset is %{public}u", offset);
145     BufferCache_->WriteToParcel(mem, data);
146     data.WriteUint32(offset);
147     data.WriteUint32(length);
148     data.WriteInt64(pos);
149     int error = Remote()->SendRequest(static_cast<uint32_t>(ListenerMsg::READ_AT), data, reply, option);
150     CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, READ_AT_ERR_CODE, "ReadAt failed, error: %{public}d", error);
151     return reply.ReadInt32();
152 }
153 
GetSize(int64_t & size)154 int32_t MediaDataSourceProxy::GetSize(int64_t &size)
155 {
156     MessageParcel data;
157     MessageParcel reply;
158     MessageOption option(MessageOption::TF_SYNC);
159 
160     bool token = data.WriteInterfaceToken(MediaDataSourceProxy::GetDescriptor());
161     CHECK_AND_RETURN_RET_LOG(token, MSERR_INVALID_OPERATION, "Failed to write descriptor!");
162 
163     int error = Remote()->SendRequest(static_cast<uint32_t>(ListenerMsg::GET_SIZE), data, reply, option);
164     CHECK_AND_RETURN_RET_LOG(error == MSERR_OK, -1, "GetSize failed, error: %{public}d", error);
165 
166     size = reply.ReadInt64();
167     return reply.ReadInt32();
168 }
169 } // namespace Media
170 } // namespace OHOS