1 /*
2 * Copyright (c) 2020-2021 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 "player_demux.h"
16 #include <memory>
17 #include "format_type.h"
18 #include "media_log.h"
19 extern "C"
20 {
21 #include "format_interface.h"
22 }
23
24 using namespace std;
25
26 namespace OHOS {
27 namespace Media {
28 #define READ_FRAME_TIMEOUT 20
29
30 #define CHECK_NULL_RETURN(value, printfString) \
31 do { \
32 if (value == nullptr) { \
33 MEDIA_ERR_LOG(" %s ", printfString ? printfString : " "); \
34 return -1; \
35 } \
36 } while (0)
37
38 #define CHECK_FAILED_RETURN(value, target, ret, printfString) \
39 do { \
40 if (value != target) { \
41 MEDIA_ERR_LOG(" %s ", printfString ? printfString : " "); \
42 return ret; \
43 } \
44 } while (0)
45
PlayerDemuxer()46 PlayerDemuxer::PlayerDemuxer()
47 : inited_(false),
48 prepared_(false),
49 started_(false),
50 demuxer_(nullptr),
51 sourceType_(SOURCE_TYPE_BUT),
52 fd_(-1)
53 {
54 stream_.handle = nullptr;
55 stream_.ReadData = nullptr;
56 stream_.GetReadableSize = nullptr;
57 formatListener_.OnError = nullptr;
58 formatListener_.OnInfo = nullptr;
59 formatListener_.privateDataHandle = nullptr;
60 callBack_.onEventCallback = nullptr;
61 callBack_.priv = nullptr;
62 }
63
~PlayerDemuxer()64 PlayerDemuxer::~PlayerDemuxer()
65 {
66 if (demuxer_ != nullptr) {
67 FormatDemuxerDestroy(demuxer_);
68 demuxer_ = nullptr;
69 }
70 }
71
Init(void)72 int32_t PlayerDemuxer::Init(void)
73 {
74 formatListener_.OnError = ErrorEventPro;
75 formatListener_.OnInfo = InfoEventPro;
76 FormatInit();
77 inited_ = true;
78 return 0;
79 }
80
ErrorEventPro(void * handle,int32_t errorType,int32_t errorCode)81 int32_t PlayerDemuxer::ErrorEventPro(void *handle, int32_t errorType, int32_t errorCode)
82 {
83 return 0;
84 }
85
InfoEventPro(void * handle,int32_t type,int32_t extra)86 int32_t PlayerDemuxer::InfoEventPro(void *handle, int32_t type, int32_t extra)
87 {
88 return 0;
89 }
90
GetFormatDemuxer(void)91 int32_t PlayerDemuxer::GetFormatDemuxer(void)
92 {
93 int ret;
94 FormatSource source;
95
96 source.type = sourceType_;
97 if (sourceType_ == SOURCE_TYPE_FD) {
98 source.fd = fd_;
99 } else if (sourceType_ == SOURCE_TYPE_URI) {
100 if (strncpy_s(source.url, URL_LEN, filePath_.c_str(), filePath_.size()) != 0) {
101 return -1;
102 }
103 } else {
104 source.stream = &stream_;
105 }
106 ret = FormatDemuxerCreate(&source, &demuxer_);
107 if (ret != 0 || demuxer_ == nullptr) {
108 MEDIA_ERR_LOG("FormatDemuxerCreate failed");
109 return -1;
110 }
111 return 0;
112 }
113
SetSource(int fd)114 int32_t PlayerDemuxer::SetSource(int fd)
115 {
116 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
117 fd_ = fd;
118 sourceType_ = SOURCE_TYPE_FD;
119 CHECK_FAILED_RETURN(GetFormatDemuxer(), 0, -1, " ");
120 return 0;
121 }
122
SetSource(const char * url)123 int32_t PlayerDemuxer::SetSource(const char *url)
124 {
125 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
126 filePath_ = std::string(url);
127 sourceType_ = SOURCE_TYPE_URI;
128 CHECK_FAILED_RETURN(GetFormatDemuxer(), 0, -1, " ");
129 return 0;
130 }
131
SetSource(BufferStream & stream)132 int32_t PlayerDemuxer::SetSource(BufferStream &stream)
133 {
134 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
135 stream_ = stream;
136 sourceType_ = SOURCE_TYPE_STREAM;
137 CHECK_FAILED_RETURN(GetFormatDemuxer(), 0, -1, " ");
138 return 0;
139 }
140
SetCallBack(PlayEventCallback & callBack)141 int32_t PlayerDemuxer::SetCallBack(PlayEventCallback &callBack)
142 {
143 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
144 callBack_ = callBack;
145 return 0;
146 }
147
Prepare(void)148 int32_t PlayerDemuxer::Prepare(void)
149 {
150 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
151 CHECK_FAILED_RETURN(FormatDemuxerSetCallBack(demuxer_, &formatListener_), 0, -1, "set callback failed");
152 CHECK_FAILED_RETURN(FormatDemuxerPrepare(demuxer_), 0, -1, "prepare failed");
153 prepared_ = true;
154 return 0;
155 }
156
GetFileInfo(FormatFileInfo & fileInfo)157 int32_t PlayerDemuxer::GetFileInfo(FormatFileInfo &fileInfo)
158 {
159 uint32_t i;
160 FileInfo info;
161 int programId = -1;
162 int trackId[0x2] = {-1, -1};
163 int trackNum = 0x2;
164 ProgramInfo *programInfo = nullptr;
165 CHECK_FAILED_RETURN(prepared_, true, -1, "not prepared");
166 CHECK_FAILED_RETURN(FormatDemuxerGetFileInfo(demuxer_, &info), 0, -1, "");
167 CHECK_FAILED_RETURN(FormatDemuxerGetSelectedTrack(demuxer_, &programId, trackId, &trackNum), 0, -1, "");
168
169 if (programId == -1 || trackNum == 0 || trackId[0] == -1) {
170 MEDIA_ERR_LOG("FormatDemuxerGetSelectedTrack failed");
171 return -1;
172 }
173
174 fileInfo.s64FileSize = -1;
175 fileInfo.s64StartTime = 0;
176 fileInfo.u32Bitrate = info.bitrate;
177 if (info.programNum == 1) {
178 programInfo = &info.programInfo[0];
179 } else {
180 for (i = 0; i < info.programNum; i++) {
181 if (info.programInfo[i].programId == programId) {
182 programInfo = &info.programInfo[i];
183 break;
184 }
185 }
186 }
187 if (programInfo == nullptr) {
188 MEDIA_ERR_LOG("can not find the program");
189 return -1;
190 }
191 fileInfo.s64Duration = programInfo->durationMs;
192 fileInfo.s32UsedVideoStreamIndex = -1;
193 fileInfo.s32UsedAudioStreamIndex = -1;
194 for (i = 0; i < programInfo->trackNum; i++) {
195 if (programInfo->track[i].trackId == trackId[0] || programInfo->track[i].trackId == trackId[1]) {
196 if (programInfo->track[i].trackType == TRACK_TYPE_VIDEO) {
197 fileInfo.s32UsedVideoStreamIndex = programInfo->track[i].trackId;
198 fileInfo.u32Width = programInfo->track[i].vidTrack.width;
199 fileInfo.u32Height = programInfo->track[i].vidTrack.height;
200 fileInfo.enVideoType = programInfo->track[i].vidTrack.format;
201 } else if (programInfo->track[i].trackType == TRACK_TYPE_AUDIO) {
202 fileInfo.s32UsedAudioStreamIndex = programInfo->track[i].trackId;
203 fileInfo.u32AudioChannelCnt = programInfo->track[i].audTrack.channels;
204 fileInfo.u32SampleRate = programInfo->track[i].audTrack.sampleRate;
205 fileInfo.enAudioType = programInfo->track[i].audTrack.format;
206 }
207 }
208 }
209 int index = 0;
210 uint32_t j;
211 for (i = 0; i < info.programNum; i++) {
212 programInfo = &info.programInfo[i];
213 for (j = 0; j < programInfo->trackNum; j++) {
214 if (programInfo->track[j].trackType == TRACK_TYPE_VIDEO && index < HI_DEMUXER_RESOLUTION_CNT) {
215 fileInfo.stSteamResolution[index].s32VideoStreamIndex = programInfo->track[j].trackId;
216 fileInfo.stSteamResolution[index].u32Width = programInfo->track[j].vidTrack.width;
217 fileInfo.stSteamResolution[index].u32Height = programInfo->track[j].vidTrack.height;
218 fileInfo.stSteamResolution[index].enVideoType = programInfo->track[j].vidTrack.format;
219 index++;
220 }
221 }
222 }
223 for (; index < HI_DEMUXER_RESOLUTION_CNT; index++) {
224 fileInfo.stSteamResolution[index].s32VideoStreamIndex = -1;
225 fileInfo.stSteamResolution[index].u32Width = 0;
226 fileInfo.stSteamResolution[index].u32Height = 0;
227 }
228
229 fileInfo.formatName = info.formatName;
230 return 0;
231 }
232
SelectTrack(int32_t programId,int32_t trackId)233 int32_t PlayerDemuxer::SelectTrack(int32_t programId, int32_t trackId)
234 {
235 CHECK_FAILED_RETURN(prepared_, true, -1, "not prepared");
236 return FormatDemuxerSelectTrack(demuxer_, programId, trackId);
237 }
238
UnselectTrack(int32_t programId,int32_t trackId)239 int32_t PlayerDemuxer::UnselectTrack(int32_t programId, int32_t trackId)
240 {
241 CHECK_FAILED_RETURN(prepared_, true, -1, "not prepared");
242 return FormatDemuxerUnselectTrack(demuxer_, programId, trackId);
243 }
244
GetSelectedTrack(int32_t & programId,int32_t trackId[],int32_t & nums)245 int32_t PlayerDemuxer::GetSelectedTrack(int32_t &programId, int32_t trackId[], int32_t &nums)
246 {
247 CHECK_FAILED_RETURN(prepared_, true, -1, "not prepared");
248 return FormatDemuxerGetSelectedTrack(demuxer_, &programId, trackId, &nums);
249 }
250
Start()251 int32_t PlayerDemuxer::Start()
252 {
253 CHECK_FAILED_RETURN(prepared_, true, -1, "not prepared");
254 CHECK_FAILED_RETURN(FormatDemuxerStart(demuxer_), 0, -1, "");
255 started_ = true;
256 return 0;
257 }
258
ReadFrame(FormatFrame & frame)259 int32_t PlayerDemuxer::ReadFrame(FormatFrame &frame)
260 {
261 CHECK_FAILED_RETURN(started_, true, -1, "not started");
262 return FormatDemuxerReadFrame(demuxer_, &frame, READ_FRAME_TIMEOUT);
263 }
264
FreeFrame(FormatFrame & frame)265 int32_t PlayerDemuxer::FreeFrame(FormatFrame &frame)
266 {
267 CHECK_FAILED_RETURN(started_, true, -1, "not started");
268 return FormatDemuxerFreeFrame(demuxer_, &frame);
269 }
270
Seek(int32_t streamIndex,int64_t timeStampUs,FormatSeekMode mode)271 int32_t PlayerDemuxer::Seek(int32_t streamIndex, int64_t timeStampUs, FormatSeekMode mode)
272 {
273 CHECK_FAILED_RETURN(started_, true, -1, "not started");
274 return FormatDemuxerSeek(demuxer_, streamIndex, timeStampUs, mode);
275 }
276
Stop()277 int32_t PlayerDemuxer::Stop()
278 {
279 if (demuxer_ == nullptr) {
280 return 0;
281 }
282 return FormatDemuxerStop(demuxer_);
283 }
284
SetParam(int32_t trackId,const ParameterItem * metaData,int32_t metaDataCnt)285 int32_t PlayerDemuxer::SetParam(int32_t trackId, const ParameterItem *metaData, int32_t metaDataCnt)
286 {
287 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
288 return FormatDemuxerSetParameter(demuxer_, trackId, metaData, metaDataCnt);
289 }
290
GetParam(int32_t trackId,ParameterItem & metaData)291 int32_t PlayerDemuxer::GetParam(int32_t trackId, ParameterItem &metaData)
292 {
293 CHECK_FAILED_RETURN(inited_, true, -1, "not inited");
294 return FormatDemuxerGetParameter(demuxer_, trackId, &metaData);
295 }
296 } // namespace Media
297 } // namespace OHOS
298