• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &currentHeight);
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 }