1 /*
2 * Copyright (C) 2023 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 "native_avdemuxer.h"
17 #include <memory>
18 #include "av_common.h"
19 #include "avcodec_errors.h"
20 #include "avcodec_log.h"
21 #include "avdemuxer.h"
22 #include "common/native_mfmagic.h"
23 #include "native_avmagic.h"
24 #include "native_mfmagic.h"
25 #include "native_object.h"
26 #include "native_drm_common.h"
27 namespace {
28 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_DEMUXER, "NativeAVDemuxer"};
29 }
30
31 using namespace OHOS::MediaAVCodec;
32
33 namespace NativeDrmTools {
ProcessApplicationDrmInfo(DRM_MediaKeySystemInfo * info,const std::multimap<std::string,std::vector<uint8_t>> & drmInfoMap)34 static int32_t ProcessApplicationDrmInfo(DRM_MediaKeySystemInfo *info,
35 const std::multimap<std::string, std::vector<uint8_t>> &drmInfoMap)
36 {
37 uint32_t count = drmInfoMap.size();
38 if (count <= 0 || count > MAX_PSSH_INFO_COUNT) {
39 return AV_ERR_INVALID_VAL;
40 }
41 CHECK_AND_RETURN_RET_LOG(info != nullptr, AV_ERR_INVALID_VAL, "Info is nullptr");
42
43 info->psshCount = count;
44 uint32_t index = 0;
45 for (auto &item : drmInfoMap) {
46 const uint32_t step = 2;
47 errno_t ret = memset_s(info->psshInfo[index].uuid, DRM_UUID_LEN, 0x00, DRM_UUID_LEN);
48 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_INVALID_VAL, "Memset uuid failed");
49 for (uint32_t i = 0; i < item.first.size(); i += step) {
50 std::string byteString = item.first.substr(i, step);
51 unsigned char uuidByte = (unsigned char)strtol(byteString.c_str(), NULL, DRM_UUID_LEN);
52 info->psshInfo[index].uuid[i / step] = uuidByte;
53 }
54
55 info->psshInfo[index].dataLen = static_cast<int32_t>(item.second.size());
56
57 ret = memset_s(info->psshInfo[index].data, MAX_PSSH_DATA_LEN, 0x00, MAX_PSSH_DATA_LEN);
58 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_INVALID_VAL, "Memset pssh failed");
59 CHECK_AND_RETURN_RET_LOG(item.second.size() <= MAX_PSSH_DATA_LEN, AV_ERR_INVALID_VAL, "Pssh is too large");
60 ret = memcpy_s(info->psshInfo[index].data, item.second.size(), static_cast<const void *>(item.second.data()),
61 item.second.size());
62 CHECK_AND_RETURN_RET_LOG(ret == EOK, AV_ERR_INVALID_VAL, "Pssh is too large");
63
64 index++;
65 }
66 return AV_ERR_OK;
67 }
68 } // namespace NativeDrmTools
69
70 class NativeDemuxerCallback;
71 struct DemuxerObject : public OH_AVDemuxer {
DemuxerObjectDemuxerObject72 explicit DemuxerObject(const std::shared_ptr<AVDemuxer> &demuxer)
73 : OH_AVDemuxer(AVMagic::AVCODEC_MAGIC_AVDEMUXER), demuxer_(demuxer) {}
74 ~DemuxerObject() = default;
75
76 const std::shared_ptr<AVDemuxer> demuxer_;
77 std::shared_ptr<NativeDemuxerCallback> callback_;
78 };
79
80 class NativeDemuxerCallback : public AVDemuxerCallback {
81 public:
NativeDemuxerCallback(OH_AVDemuxer * demuxer,DRM_MediaKeySystemInfoCallback cb)82 explicit NativeDemuxerCallback(OH_AVDemuxer *demuxer,
83 DRM_MediaKeySystemInfoCallback cb) : demuxer_(demuxer), callback_(cb), callbackObj_(nullptr)
84 {
85 }
86
NativeDemuxerCallback(OH_AVDemuxer * demuxer,Demuxer_MediaKeySystemInfoCallback cbObj)87 explicit NativeDemuxerCallback(OH_AVDemuxer *demuxer,
88 Demuxer_MediaKeySystemInfoCallback cbObj) : demuxer_(demuxer), callback_(nullptr), callbackObj_(cbObj)
89 {
90 }
91
92 virtual ~NativeDemuxerCallback() = default;
93
OnDrmInfoChanged(const std::multimap<std::string,std::vector<uint8_t>> & drmInfo)94 void OnDrmInfoChanged(const std::multimap<std::string, std::vector<uint8_t>> &drmInfo) override
95 {
96 AVCODEC_LOGI("NativeDemuxerCallback OnDrmInfoChanged is on call");
97 std::unique_lock<std::shared_mutex> lock(mutex_);
98 CHECK_AND_RETURN_LOG(demuxer_ != nullptr, "AVDemuxer is nullptr");
99
100 DRM_MediaKeySystemInfo info;
101 int32_t ret = NativeDrmTools::ProcessApplicationDrmInfo(&info, drmInfo);
102 CHECK_AND_RETURN_LOG(ret == AV_ERR_OK, "ProcessApplicationDrmInfo failed");
103
104 CHECK_AND_RETURN_LOG(callback_ != nullptr || callbackObj_ != nullptr, "Hasn't register any drm callback");
105 if (callback_ != nullptr) {
106 callback_(&info);
107 }
108 if (callbackObj_ != nullptr) {
109 callbackObj_(demuxer_, &info);
110 }
111 }
112
113 private:
114 std::shared_mutex mutex_;
115 struct OH_AVDemuxer *demuxer_;
116 DRM_MediaKeySystemInfoCallback callback_;
117 Demuxer_MediaKeySystemInfoCallback callbackObj_;
118 };
119
OH_AVDemuxer_CreateWithSource(OH_AVSource * source)120 struct OH_AVDemuxer *OH_AVDemuxer_CreateWithSource(OH_AVSource *source)
121 {
122 CHECK_AND_RETURN_RET_LOG(source != nullptr, nullptr, "Input source is nullptr");
123
124 struct AVSourceObject *sourceObj = reinterpret_cast<AVSourceObject *>(source);
125 CHECK_AND_RETURN_RET_LOG(sourceObj != nullptr, nullptr, "Create sourceObject is nullptr");
126
127 std::shared_ptr<AVDemuxer> demuxer = AVDemuxerFactory::CreateWithSource(sourceObj->source_);
128 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, nullptr, "New avdemuxer failed");
129
130 struct DemuxerObject *object = new(std::nothrow) DemuxerObject(demuxer);
131 CHECK_AND_RETURN_RET_LOG(object != nullptr, nullptr, "New demuxerObject failed");
132
133 return object;
134 }
135
OH_AVDemuxer_Destroy(OH_AVDemuxer * demuxer)136 OH_AVErrCode OH_AVDemuxer_Destroy(OH_AVDemuxer *demuxer)
137 {
138 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
139 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
140
141 delete demuxer;
142 return AV_ERR_OK;
143 }
144
OH_AVDemuxer_SelectTrackByID(OH_AVDemuxer * demuxer,uint32_t trackIndex)145 OH_AVErrCode OH_AVDemuxer_SelectTrackByID(OH_AVDemuxer *demuxer, uint32_t trackIndex)
146 {
147 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
148 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
149
150 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
151 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
152 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
153
154 int32_t ret = demuxerObj->demuxer_->SelectTrackByID(trackIndex);
155 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
156 "AVDemuxer select track failed");
157
158 return AV_ERR_OK;
159 }
160
OH_AVDemuxer_UnselectTrackByID(OH_AVDemuxer * demuxer,uint32_t trackIndex)161 OH_AVErrCode OH_AVDemuxer_UnselectTrackByID(OH_AVDemuxer *demuxer, uint32_t trackIndex)
162 {
163 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
164 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
165
166 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
167 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
168 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
169
170 int32_t ret = demuxerObj->demuxer_->UnselectTrackByID(trackIndex);
171 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
172 "AVDemuxer unselect track failed");
173
174 return AV_ERR_OK;
175 }
176
OH_AVDemuxer_ReadSample(OH_AVDemuxer * demuxer,uint32_t trackIndex,OH_AVMemory * sample,OH_AVCodecBufferAttr * info)177 OH_AVErrCode OH_AVDemuxer_ReadSample(OH_AVDemuxer *demuxer, uint32_t trackIndex,
178 OH_AVMemory *sample, OH_AVCodecBufferAttr *info)
179 {
180 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
181 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
182
183 CHECK_AND_RETURN_RET_LOG(sample != nullptr && sample->memory_ != nullptr, AV_ERR_INVALID_VAL, "Sample is nullptr");
184 CHECK_AND_RETURN_RET_LOG(info != nullptr, AV_ERR_INVALID_VAL, "Info is nullptr");
185
186 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
187 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
188 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
189
190 struct AVCodecBufferInfo bufferInfoInner;
191 uint32_t bufferFlag = (uint32_t)(AVCodecBufferFlag::AVCODEC_BUFFER_FLAG_NONE);
192 int32_t ret = demuxerObj->demuxer_->ReadSample(trackIndex, sample->memory_, bufferInfoInner, bufferFlag);
193 info->pts = bufferInfoInner.presentationTimeUs;
194 info->size = bufferInfoInner.size;
195 info->offset = bufferInfoInner.offset;
196 info->flags = bufferFlag;
197
198 CHECK_AND_RETURN_RET_LOG(ret != AVCS_ERR_NO_MEMORY, AV_ERR_NO_MEMORY, "Sample size is too small");
199 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
200 "AVDemuxer read failed");
201
202 return AV_ERR_OK;
203 }
204
OH_AVDemuxer_ReadSampleBuffer(OH_AVDemuxer * demuxer,uint32_t trackIndex,OH_AVBuffer * sample)205 OH_AVErrCode OH_AVDemuxer_ReadSampleBuffer(OH_AVDemuxer *demuxer, uint32_t trackIndex, OH_AVBuffer *sample)
206 {
207 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
208 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
209
210 CHECK_AND_RETURN_RET_LOG(sample != nullptr && sample->buffer_ != nullptr, AV_ERR_INVALID_VAL, "Sample is nullptr");
211
212 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
213 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
214 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
215
216 int32_t ret = demuxerObj->demuxer_->ReadSampleBuffer(trackIndex, sample->buffer_);
217 CHECK_AND_RETURN_RET_LOG(ret != AVCS_ERR_NO_MEMORY, AV_ERR_NO_MEMORY, "Sample size is too small");
218 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
219 "AVDemuxer read failed");
220
221 return AV_ERR_OK;
222 }
223
OH_AVDemuxer_SeekToTime(OH_AVDemuxer * demuxer,int64_t millisecond,OH_AVSeekMode mode)224 OH_AVErrCode OH_AVDemuxer_SeekToTime(OH_AVDemuxer *demuxer, int64_t millisecond, OH_AVSeekMode mode)
225 {
226 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
227 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
228
229 CHECK_AND_RETURN_RET_LOG(millisecond >= 0, AV_ERR_INVALID_VAL, "Millisecond is negative");
230
231 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
232 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
233 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
234
235 int32_t ret = demuxerObj->demuxer_->SeekToTime(millisecond, static_cast<OHOS::Media::SeekMode>(mode));
236 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
237 "AVDemuxer seek failed");
238
239 return AV_ERR_OK;
240 }
241
OH_AVDemuxer_SetMediaKeySystemInfoCallback(OH_AVDemuxer * demuxer,DRM_MediaKeySystemInfoCallback callback)242 OH_AVErrCode OH_AVDemuxer_SetMediaKeySystemInfoCallback(OH_AVDemuxer *demuxer,
243 DRM_MediaKeySystemInfoCallback callback)
244 {
245 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
246 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
247
248 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
249 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
250 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
251
252 demuxerObj->callback_ = std::make_shared<NativeDemuxerCallback>(demuxer, callback);
253 int32_t ret = demuxerObj->demuxer_->SetCallback(demuxerObj->callback_);
254 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
255 "AVDemuxer set callback failed");
256 return AV_ERR_OK;
257 }
258
OH_AVDemuxer_SetDemuxerMediaKeySystemInfoCallback(OH_AVDemuxer * demuxer,Demuxer_MediaKeySystemInfoCallback callback)259 OH_AVErrCode OH_AVDemuxer_SetDemuxerMediaKeySystemInfoCallback(OH_AVDemuxer *demuxer,
260 Demuxer_MediaKeySystemInfoCallback callback)
261 {
262 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
263 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
264
265 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
266 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
267 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
268
269 demuxerObj->callback_ = std::make_shared<NativeDemuxerCallback>(demuxer, callback);
270 int32_t ret = demuxerObj->demuxer_->SetCallback(demuxerObj->callback_);
271 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
272 "AVDemuxer set callback failed");
273 return AV_ERR_OK;
274 }
275
OH_AVDemuxer_GetMediaKeySystemInfo(OH_AVDemuxer * demuxer,DRM_MediaKeySystemInfo * mediaKeySystemInfo)276 OH_AVErrCode OH_AVDemuxer_GetMediaKeySystemInfo(OH_AVDemuxer *demuxer, DRM_MediaKeySystemInfo *mediaKeySystemInfo)
277 {
278 CHECK_AND_RETURN_RET_LOG(demuxer != nullptr, AV_ERR_INVALID_VAL, "Input demuxer is nullptr");
279 CHECK_AND_RETURN_RET_LOG(demuxer->magic_ == AVMagic::AVCODEC_MAGIC_AVDEMUXER, AV_ERR_INVALID_VAL, "Magic error");
280
281 struct DemuxerObject *demuxerObj = reinterpret_cast<DemuxerObject *>(demuxer);
282 CHECK_AND_RETURN_RET_LOG(demuxerObj != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
283 CHECK_AND_RETURN_RET_LOG(demuxerObj->demuxer_ != nullptr, AV_ERR_INVALID_VAL, "Get demuxerObject failed");
284
285 std::multimap<std::string, std::vector<uint8_t>> drmInfos;
286 int32_t ret = demuxerObj->demuxer_->GetMediaKeySystemInfo(drmInfos);
287 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
288 "AVDemuxer GetMediaKeySystemInfo failed");
289 CHECK_AND_RETURN_RET_LOG(!drmInfos.empty(), AV_ERR_OK, "DrmInfo is null");
290
291 ret = NativeDrmTools::ProcessApplicationDrmInfo(mediaKeySystemInfo, drmInfos);
292 CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AV_ERR_INVALID_VAL, "ProcessApplicationDrmInfo failed");
293
294 return AV_ERR_OK;
295 }