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