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