• 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 <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, &currentHeight);
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 }