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 <cstddef>
17 #include <cstdint>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <sys/stat.h>
21 #include <iostream>
22 #include "securec.h"
23
24 using namespace OHOS;
25 using namespace OHOS::Media;
26 using namespace std;
27
~DemuxerSample()28 DemuxerSample::~DemuxerSample()
29 {
30 if (fd > 0) {
31 close(fd);
32 fd = 0;
33 }
34 if (source != nullptr) {
35 OH_AVSource_Destroy(source);
36 source = nullptr;
37 }
38 if (uriSource != nullptr) {
39 OH_AVSource_Destroy(uriSource);
40 uriSource = nullptr;
41 }
42 if (demuxer != nullptr) {
43 OH_AVDemuxer_Destroy(demuxer);
44 demuxer = nullptr;
45 }
46 if (sourceFormat != nullptr) {
47 OH_AVFormat_Destroy(sourceFormat);
48 sourceFormat = nullptr;
49 }
50 if (memory != nullptr) {
51 OH_AVMemory_Destroy(memory);
52 memory = nullptr;
53 }
54 if (buffer != nullptr) {
55 OH_AVBuffer_Destroy(buffer);
56 buffer = nullptr;
57 }
58 if (format != nullptr) {
59 OH_AVFormat_Destroy(format);
60 format = nullptr;
61 }
62 if (audioFormat != nullptr) {
63 OH_AVFormat_Destroy(audioFormat);
64 audioFormat = nullptr;
65 }
66 if (videoFormat != nullptr) {
67 OH_AVFormat_Destroy(videoFormat);
68 videoFormat = nullptr;
69 }
70 }
71
GetFileSize(const char * fileName)72 static int64_t GetFileSize(const char *fileName)
73 {
74 int64_t fileSize = 0;
75 if (fileName != nullptr) {
76 struct stat fileStatus {};
77 if (stat(fileName, &fileStatus) == 0) {
78 fileSize = static_cast<int64_t>(fileStatus.st_size);
79 }
80 }
81 return fileSize;
82 }
83
SetFileValue(OH_AVCodecBufferAttr attr,bool & gReadEnd,int & keyCount)84 static void SetFileValue(OH_AVCodecBufferAttr attr, bool &gReadEnd, int &keyCount)
85 {
86 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
87 gReadEnd = true;
88 } else {
89 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_SYNC_FRAME) {
90 keyCount++;
91 }
92 }
93 }
94
CreateDemuxer()95 int DemuxerSample::CreateDemuxer()
96 {
97 fd = open(filePath, O_RDONLY);
98 int64_t size = GetFileSize(filePath);
99 source = OH_AVSource_CreateWithFD(fd, 0, size);
100 if (!source) {
101 close(fd);
102 fd = 0;
103 return -1;
104 }
105 demuxer = OH_AVDemuxer_CreateWithSource(source);
106 if (!demuxer) {
107 OH_AVSource_Destroy(source);
108 source = nullptr;
109 close(fd);
110 fd = 0;
111 return -1;
112 }
113 return 0;
114 }
115
GetAndSetFormat(const char * setLanguage,Params params)116 void DemuxerSample::GetAndSetFormat(const char *setLanguage, Params params)
117 {
118 int64_t duration = 0;
119 OH_AVFormat_GetLongValue(sourceFormat, OH_MD_KEY_DURATION, &duration);
120 float currentHeight = 0;
121 OH_AVFormat_GetFloatValue(sourceFormat, OH_MD_KEY_HEIGHT, ¤tHeight);
122 double frameRate;
123 OH_AVFormat_GetDoubleValue(sourceFormat, OH_MD_KEY_FRAME_RATE, &frameRate);
124 const char* language = nullptr;
125 OH_AVFormat_GetStringValue(sourceFormat, OH_MD_KEY_LANGUAGE, &language);
126 uint8_t *codecConfig = nullptr;
127 size_t bufferSize;
128 OH_AVFormat_GetBuffer(sourceFormat, OH_MD_KEY_CODEC_CONFIG, &codecConfig, &bufferSize);
129 language = OH_AVFormat_DumpInfo(sourceFormat);
130 format = OH_AVFormat_Create();
131 OH_AVFormat_SetIntValue(format, OH_MD_KEY_TRACK_TYPE, params.setTrackType);
132 OH_AVFormat_SetLongValue(format, OH_MD_KEY_DURATION, params.setDuration);
133 OH_AVFormat_SetFloatValue(format, OH_MD_KEY_HEIGHT, params.setHeight);
134 OH_AVFormat_SetDoubleValue(format, OH_MD_KEY_FRAME_RATE, params.setFrameRate);
135 OH_AVFormat_SetStringValue(format, OH_MD_KEY_LANGUAGE, setLanguage);
136 char configBuffer[params.setCodecConfigSize];
137 OH_AVFormat_SetBuffer(format, OH_MD_KEY_CODEC_CONFIG, (uint8_t *)configBuffer, params.setCodecConfigSize);
138 OH_AVFormat_Copy(format, sourceFormat);
139 audioFormat = OH_AVFormat_CreateAudioFormat(OH_AVCODEC_MIMETYPE_AUDIO_AAC, params.sampleRate, params.channelCount);
140 videoFormat = OH_AVFormat_CreateVideoFormat(OH_AVCODEC_MIMETYPE_VIDEO_AVC,
141 params.setVideoWidth, params.setVideoHeight);
142 }
143
RunNormalDemuxer(uint32_t createSize,const char * uri,const char * setLanguage,Params params)144 void DemuxerSample::RunNormalDemuxer(uint32_t createSize, const char *uri, const char *setLanguage, Params params)
145 {
146 gReadEnd = false;
147 int ret = CreateDemuxer();
148 if (ret < 0) {
149 return;
150 }
151 sourceFormat = OH_AVSource_GetSourceFormat(source);
152 if (sourceFormat == nullptr) {
153 return;
154 }
155 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &gTrackCount);
156 for (int32_t index = 0; index < gTrackCount; index++) {
157 OH_AVDemuxer_SelectTrackByID(demuxer, index);
158 }
159 memory = OH_AVMemory_Create(createSize);
160 while (!gReadEnd && gTrackCount > 0) {
161 for (int32_t index = 0; index < gTrackCount; index++) {
162 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
163 if (trackFormat == nullptr) {
164 gReadEnd = true;
165 break;
166 }
167 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &gTrackType);
168 if (trackFormat) {
169 OH_AVFormat_Destroy(trackFormat);
170 trackFormat = nullptr;
171 }
172 ret = OH_AVDemuxer_ReadSample(demuxer, index, memory, &attr);
173 if (ret != 0) {
174 gReadEnd = true;
175 break;
176 }
177 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
178 gReadEnd = true;
179 break;
180 }
181 }
182 }
183 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_CLOSEST_SYNC);
184 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_PREVIOUS_SYNC);
185 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_NEXT_SYNC);
186 for (int32_t index = 0; index < gTrackCount; index++) {
187 OH_AVDemuxer_UnselectTrackByID(demuxer, index);
188 }
189 GetAndSetFormat(setLanguage, params);
190 uriSource = OH_AVSource_CreateWithURI(const_cast<char *>(uri));
191 }
192
RunNormalDemuxerApi11(uint32_t createSize,const char * uri,const char * setLanguage,Params params)193 void DemuxerSample::RunNormalDemuxerApi11(uint32_t createSize, const char *uri, const char *setLanguage, Params params)
194 {
195 gReadEnd = false;
196 int keyCount = 0;
197 int ret = CreateDemuxer();
198 if (ret < 0) {
199 return;
200 }
201 sourceFormat = OH_AVSource_GetSourceFormat(source);
202 if (sourceFormat == nullptr) {
203 return;
204 }
205 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &gTrackCount);
206 for (int32_t index = 0; index < gTrackCount; index++) {
207 OH_AVDemuxer_SelectTrackByID(demuxer, index);
208 }
209 buffer = OH_AVBuffer_Create(createSize);
210 while (!gReadEnd && gTrackCount > 0) {
211 for (int32_t index = 0; index < gTrackCount; index++) {
212 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
213 if (trackFormat == nullptr) {
214 gReadEnd = true;
215 break;
216 }
217 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &gTrackType);
218 if (trackFormat) {
219 OH_AVFormat_Destroy(trackFormat);
220 trackFormat = nullptr;
221 }
222 ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, index, buffer);
223 if (ret != 0) {
224 gReadEnd = true;
225 break;
226 }
227 OH_AVBuffer_GetBufferAttr(buffer, &attr);
228 SetFileValue(attr, gReadEnd, keyCount);
229 }
230 }
231 cout << "---keyCount---" << keyCount << endl;
232 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_CLOSEST_SYNC);
233 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_PREVIOUS_SYNC);
234 OH_AVDemuxer_SeekToTime(demuxer, params.time, SEEK_MODE_NEXT_SYNC);
235 for (int32_t index = 0; index < gTrackCount; index++) {
236 OH_AVDemuxer_UnselectTrackByID(demuxer, index);
237 }
238 GetAndSetFormat(setLanguage, params);
239 uriSource = OH_AVSource_CreateWithURI(const_cast<char *>(uri));
240 }