1 /*
2 * Copyright (c) 2024 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 #include "demuxer_sample.h"
16 #include "media_description.h"
17 #include <cstddef>
18 #include <cstdint>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <sys/stat.h>
22 #include <iostream>
23 #include "securec.h"
24
25 using namespace OHOS;
26 using namespace OHOS::Media;
27 using namespace std;
28
29 #define DRM_UUID_LEN 16
30
31 #define MAX_PSSH_DATA_LEN 2048
32
33 typedef struct DRM_PsshInfo {
34 uint8_t uuid[DRM_UUID_LEN];
35 int32_t dataLen;
36 uint8_t data[MAX_PSSH_DATA_LEN];
37 } DRM_PsshInfo;
38
39 #define MAX_PSSH_INFO_COUNT 8
40
41 typedef struct DRM_MediaKeySystemInfo {
42 uint32_t psshCount;
43 DRM_PsshInfo psshInfo[MAX_PSSH_INFO_COUNT];
44 } DRM_MediaKeySystemInfo;
45
46 static const std::string USER_META_KEY_TEST = "com.openharmony.test";
47
~DemuxerSample()48 DemuxerSample::~DemuxerSample()
49 {
50 if (fd > 0) {
51 close(fd);
52 fd = 0;
53 }
54 if (source != nullptr) {
55 OH_AVSource_Destroy(source);
56 source = nullptr;
57 }
58 if (uriSource != nullptr) {
59 OH_AVSource_Destroy(uriSource);
60 uriSource = nullptr;
61 }
62 if (demuxer != nullptr) {
63 OH_AVDemuxer_Destroy(demuxer);
64 demuxer = nullptr;
65 }
66 if (sourceFormat != nullptr) {
67 OH_AVFormat_Destroy(sourceFormat);
68 sourceFormat = nullptr;
69 }
70 if (memory != nullptr) {
71 OH_AVMemory_Destroy(memory);
72 memory = nullptr;
73 }
74 if (buffer != nullptr) {
75 OH_AVBuffer_Destroy(buffer);
76 buffer = nullptr;
77 }
78 if (format != nullptr) {
79 OH_AVFormat_Destroy(format);
80 format = nullptr;
81 }
82 if (audioFormat != nullptr) {
83 OH_AVFormat_Destroy(audioFormat);
84 audioFormat = nullptr;
85 }
86 if (videoFormat != nullptr) {
87 OH_AVFormat_Destroy(videoFormat);
88 videoFormat = nullptr;
89 }
90 }
91
GetFileSize(const char * fileName)92 static int64_t GetFileSize(const char *fileName)
93 {
94 int64_t fileSize = 0;
95 if (fileName != nullptr) {
96 struct stat fileStatus {};
97 if (stat(fileName, &fileStatus) == 0) {
98 fileSize = static_cast<int64_t>(fileStatus.st_size);
99 }
100 }
101 return fileSize;
102 }
103
SetFileValue(OH_AVCodecBufferAttr attr,bool & gReadEnd,int & keyCount)104 static void SetFileValue(OH_AVCodecBufferAttr attr, bool &gReadEnd, int &keyCount)
105 {
106 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
107 gReadEnd = true;
108 } else {
109 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_SYNC_FRAME) {
110 keyCount++;
111 }
112 }
113 }
114
DrmMediaKeySystemInfoCallback(DRM_MediaKeySystemInfo * mediaKeySystemInfo)115 void DrmMediaKeySystemInfoCallback(DRM_MediaKeySystemInfo *mediaKeySystemInfo)
116 {}
117
DemuxerMediaKeySystemInfoCallback(OH_AVDemuxer * demuxer,DRM_MediaKeySystemInfo * mediaKeySystemInfo)118 void DemuxerMediaKeySystemInfoCallback(OH_AVDemuxer *demuxer, DRM_MediaKeySystemInfo *mediaKeySystemInfo)
119 {}
120
CreateDemuxer()121 int DemuxerSample::CreateDemuxer()
122 {
123 fd = open(filePath, O_RDONLY);
124 int64_t size = GetFileSize(filePath);
125 source = OH_AVSource_CreateWithFD(fd, 0, size);
126 if (!source) {
127 close(fd);
128 fd = 0;
129 return -1;
130 }
131 OH_AVFormat *metadataFormat = OH_AVSource_GetCustomMetadataFormat(source);
132 OH_AVFormat_Destroy(metadataFormat);
133 demuxer = OH_AVDemuxer_CreateWithSource(source);
134 if (!demuxer) {
135 OH_AVSource_Destroy(source);
136 source = nullptr;
137 close(fd);
138 fd = 0;
139 return -1;
140 }
141 OH_AVDemuxer_SetMediaKeySystemInfoCallback(demuxer, DrmMediaKeySystemInfoCallback);
142 OH_AVDemuxer_SetDemuxerMediaKeySystemInfoCallback(demuxer, DemuxerMediaKeySystemInfoCallback);
143 return 0;
144 }
145
GetAndSetFormat(const char * setLanguage,Params params)146 void DemuxerSample::GetAndSetFormat(const char *setLanguage, Params params)
147 {
148 const char *stringVal;
149 OH_AVFormat_GetStringValue(sourceFormat, OH_MD_KEY_COMMENT, &stringVal);
150 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_CLOSEST_SYNC);
151 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_PREVIOUS_SYNC);
152 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_NEXT_SYNC);
153 for (int32_t index = 0; index < gTrackCount; index++) {
154 OH_AVDemuxer_UnselectTrackByID(demuxer, index);
155 }
156 int64_t duration = 0;
157 OH_AVFormat_GetLongValue(sourceFormat, OH_MD_KEY_DURATION, &duration);
158 float currentHeight = 0;
159 OH_AVFormat_GetFloatValue(sourceFormat, OH_MD_KEY_HEIGHT, ¤tHeight);
160 double frameRate;
161 OH_AVFormat_GetDoubleValue(sourceFormat, OH_MD_KEY_FRAME_RATE, &frameRate);
162 const char* language = nullptr;
163 OH_AVFormat_GetStringValue(sourceFormat, OH_MD_KEY_LANGUAGE, &language);
164 const char* aigc = nullptr;
165 OH_AVFormat_GetStringValue(sourceFormat, MediaAVCodec::MediaDescriptionKey::MD_KEY_AIGC.data(), &aigc);
166 uint8_t *codecConfig = nullptr;
167 size_t bufferSize;
168 OH_AVFormat_GetBuffer(sourceFormat, OH_MD_KEY_CODEC_CONFIG, &codecConfig, &bufferSize);
169 language = OH_AVFormat_DumpInfo(sourceFormat);
170 format = OH_AVFormat_Create();
171 OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRACK_TYPE, params.setTrackType);
172 OH_AVFormat_SetLongValue(format, OH_MD_KEY_DURATION, params.setDuration);
173 OH_AVFormat_SetFloatValue(format, OH_MD_KEY_HEIGHT, params.setHeight);
174 OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, params.setFrameRate);
175 OH_AVFormat_SetStringValue(format, OH_MD_KEY_LANGUAGE, setLanguage);
176 char configBuffer[params.setCodecConfigSize];
177 OH_AVFormat_SetBuffer(format, OH_MD_KEY_CODEC_CONFIG, (uint8_t *)configBuffer, params.setCodecConfigSize);
178 OH_AVFormat_Copy(format, sourceFormat);
179 audioFormat = OH_AVFormat_CreateAudioFormat(OH_AVCODEC_MIMETYPE_AUDIO_AAC, params.sampleRate, params.channelCount);
180 videoFormat = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC,
181 params.setVideoWidth, params.setVideoHeight);
182
183 userFormat = OH_AVSource_GetCustomMetadataFormat(source);
184 if (userFormat == nullptr) {
185 return;
186 }
187 uint8_t *metaBuffer = nullptr;
188 size_t bufferLen = 0;
189 OH_AVFormat_GetBuffer(userFormat, USER_META_KEY_TEST.c_str(), &metaBuffer, &bufferLen);
190 }
191
RunNormalDemuxer(uint32_t createSize,const char * uri,const char * setLanguage,Params params)192 void DemuxerSample::RunNormalDemuxer(uint32_t createSize, const char *uri, const char *setLanguage, Params params)
193 {
194 gReadEnd = false;
195 DRM_MediaKeySystemInfo mediaKeySystemInfo;
196 int ret = CreateDemuxer();
197 if (ret < 0) {
198 return;
199 }
200 sourceFormat = OH_AVSource_GetSourceFormat(source);
201 if (sourceFormat == nullptr) {
202 return;
203 }
204 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &gTrackCount);
205 for (int32_t index = 0; index < gTrackCount; index++) {
206 OH_AVDemuxer_SelectTrackByID(demuxer, index);
207 }
208 memory = OH_AVMemory_Create(createSize);
209 while (!gReadEnd && gTrackCount > 0) {
210 for (int32_t index = 0; index < gTrackCount; index++) {
211 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
212 if (trackFormat == nullptr) {
213 gReadEnd = true;
214 break;
215 }
216 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &gTrackType);
217 if (trackFormat) {
218 OH_AVFormat_Destroy(trackFormat);
219 trackFormat = nullptr;
220 }
221 const char *trackRefType = nullptr;
222 const char *trackdescription = nullptr;
223 int32_t *trackIds = nullptr;
224 size_t bufferSize;
225 OH_AVFormat_GetStringValue(trackFormat, OH_MD_KEY_TRACK_REFERENCE_TYPE, &trackRefType);
226 OH_AVFormat_GetStringValue(trackFormat, OH_MD_KEY_TRACK_DESCRIPTION, &trackdescription);
227 OH_AVFormat_GetIntBuffer(trackFormat, OH_MD_KEY_REFERENCE_TRACK_IDS, &trackIds, &bufferSize);
228 ret = OH_AVDemuxer_ReadSample(demuxer, index, memory, &attr);
229 if (ret != 0) {
230 gReadEnd = true;
231 break;
232 }
233 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
234 gReadEnd = true;
235 break;
236 }
237 }
238 }
239 GetAndSetFormat(setLanguage, params);
240 uriSource = OH_AVSource_CreateWithURI(const_cast<char *>(uri));
241 OH_AVDemuxer_GetMediaKeySystemInfo(demuxer, &mediaKeySystemInfo);
242 }
243
RunNormalDemuxerApi11(uint32_t createSize,const char * uri,const char * setLanguage,Params params)244 void DemuxerSample::RunNormalDemuxerApi11(uint32_t createSize, const char *uri, const char *setLanguage, Params params)
245 {
246 gReadEnd = false;
247 DRM_MediaKeySystemInfo mediaKeySystemInfo;
248 int keyCount = 0;
249 int ret = CreateDemuxer();
250 if (ret < 0) {
251 return;
252 }
253 sourceFormat = OH_AVSource_GetSourceFormat(source);
254 if (sourceFormat == nullptr) {
255 return;
256 }
257 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &gTrackCount);
258 for (int32_t index = 0; index < gTrackCount; index++) {
259 OH_AVDemuxer_SelectTrackByID(demuxer, index);
260 }
261 buffer = OH_AVBuffer_Create(createSize);
262 while (!gReadEnd && gTrackCount > 0) {
263 for (int32_t index = 0; index < gTrackCount; index++) {
264 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
265 if (trackFormat == nullptr) {
266 gReadEnd = true;
267 break;
268 }
269 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &gTrackType);
270 if (trackFormat) {
271 OH_AVFormat_Destroy(trackFormat);
272 trackFormat = nullptr;
273 }
274 const char *trackRefType = nullptr;
275 const char *trackdescription = nullptr;
276 int32_t *trackIds = nullptr;
277 size_t bufferSize;
278 OH_AVFormat_GetStringValue(trackFormat, OH_MD_KEY_TRACK_REFERENCE_TYPE, &trackRefType);
279 OH_AVFormat_GetStringValue(trackFormat, OH_MD_KEY_TRACK_DESCRIPTION, &trackdescription);
280 OH_AVFormat_GetIntBuffer(trackFormat, OH_MD_KEY_REFERENCE_TRACK_IDS, &trackIds, &bufferSize);
281 ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, index, buffer);
282 if (ret != 0) {
283 gReadEnd = true;
284 break;
285 }
286 OH_AVBuffer_GetBufferAttr(buffer, &attr);
287 SetFileValue(attr, gReadEnd, keyCount);
288 }
289 }
290 GetAndSetFormat(setLanguage, params);
291 uriSource = OH_AVSource_CreateWithURI(const_cast<char *>(uri));
292 OH_AVDemuxer_GetMediaKeySystemInfo(demuxer, &mediaKeySystemInfo);
293 }