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