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
16 #include <cinttypes>
17 #include <cstdio>
18 #include <fcntl.h>
19 #include <iostream>
20 #include <malloc.h>
21 #include <string>
22 #include <thread>
23 #include <sys/stat.h>
24 #include <fstream>
25 #include <ctime>
26 #include "native_avbuffer.h"
27 #include "inner_demuxer_parser_sample.h"
28 #include "native_avcodec_base.h"
29 #include "meta/format.h"
30 #include "avcodec_errors.h"
31 #include "avcodec_common.h"
32 #include "native_avformat.h"
33 #include "av_common.h"
34 #include "layer_info_all_i_avc.h"
35 #include "layer_info_all_i__hevc.h"
36 #include "layer_info_ipb_avc.h"
37 #include "layer_info_ipb_hevc.h"
38 #include "layer_info_one_i_avc.h"
39 #include "layer_info_one_i_hevc.h"
40 #include "layer_info_sdtp_avc.h"
41 #include "layer_info_sdtp_hevc.h"
42 #include "layer_info_four_layer_avc.h"
43 #include "layer_info_four_layer_hevc.h"
44 #include "layer_info_ltr_avc.h"
45 #include "layer_info_ltr_hevc.h"
46 #include "layer_info_three_layer_avc.h"
47 #include "layer_info_three_layer_hevc.h"
48 #include "layer_info_two_layer_avc.h"
49 #include "layer_info_two_layer_hevc.h"
50 #include "layer_info_sdtp_extended_hevc.h"
51 #include "layer_info_hdr_1_hevc.h"
52 #include "layer_info_hdr_2_hevc.h"
53 #include <random>
54
55 using namespace std;
56 using namespace OHOS::MediaAVCodec;
57 using namespace OHOS::Media;
58
59 using json = nlohmann::json;
60
from_json(const nlohmann::json & j,JsonGopInfo & gop)61 void from_json(const nlohmann::json &j, JsonGopInfo &gop)
62 {
63 j.at("gopId").get_to(gop.gopId);
64 j.at("gopSize").get_to(gop.gopSize);
65 j.at("startFrameId").get_to(gop.startFrameId);
66 }
67
from_json(const nlohmann::json & j,JsonFrameLayerInfo & frame)68 void from_json(const nlohmann::json &j, JsonFrameLayerInfo &frame)
69 {
70 j.at("frameId").get_to(frame.frameId);
71 j.at("dts").get_to(frame.dts);
72 j.at("layer").get_to(frame.layer);
73 j.at("discardable").get_to(frame.discardable);
74 }
75
76 namespace OHOS {
77 namespace MediaAVCodec {
78 std::random_device rd;
InnerDemuxerParserSample(const std::string & filePath)79 InnerDemuxerParserSample::InnerDemuxerParserSample(const std::string &filePath)
80 {
81 fd = open(filePath.c_str(), O_RDONLY);
82 this->avsource_ = AVSourceFactory::CreateWithFD(fd, 0, GetFileSize(filePath));
83 if (!avsource_) {
84 printf("Source is null\n");
85 return;
86 }
87 this->demuxer_ = AVDemuxerFactory::CreateWithSource(avsource_);
88 if (!demuxer_) {
89 printf("AVDemuxerFactory::CreateWithSource is failed\n");
90 return;
91 }
92 int32_t ret = this->avsource_->GetSourceFormat(source_format_);
93 if (ret != 0) {
94 printf("GetSourceFormat is failed\n");
95 }
96 source_format_.GetIntValue(OH_MD_KEY_TRACK_COUNT, trackCount);
97 source_format_.GetLongValue(OH_MD_KEY_DURATION, duration);
98 printf("====>total tracks:%d duration:%" PRId64 "\n", trackCount, duration);
99 int32_t trackType = 0;
100 for (int32_t i = 0; i < trackCount; i++) {
101 ret = this->avsource_->GetTrackFormat(track_format_, i);
102 if (ret != 0) {
103 printf("GetTrackFormat is failed\n");
104 }
105 track_format_.GetIntValue(OH_MD_KEY_TRACK_TYPE, trackType);
106 if (trackType == MEDIA_TYPE_VID) {
107 ret = this->demuxer_->SelectTrackByID(i);
108 if (ret != 0) {
109 printf("SelectTrackByID is failed\n");
110 }
111 videoTrackIdx = i;
112 }
113 }
114 }
115
~InnerDemuxerParserSample()116 InnerDemuxerParserSample::~InnerDemuxerParserSample()
117 {
118 if (fd > 0) {
119 close(fd);
120 fd = 0;
121 }
122 if (avsource_ != nullptr) {
123 avsource_ = nullptr;
124 }
125 if (demuxer_ != nullptr) {
126 demuxer_ = nullptr;
127 }
128 }
129
InitParameter(MP4Scene scene)130 void InnerDemuxerParserSample::InitParameter(MP4Scene scene)
131 {
132 InitMP4Scene(scene);
133 uint32_t buffersize = 1024 * 1024;
134 std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
135 avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
136 gopVec_ = gopJson_.get<std::vector<JsonGopInfo>>();
137 frameVec_ = frameLayerJson_.get<std::vector<JsonFrameLayerInfo>>();
138 for (auto gop : gopVec_) {
139 int32_t frameId = gop.startFrameId;
140 uint32_t layerMax = 0;
141 std::map<uint8_t, uint32_t> layerNumFrame;
142 for (int32_t i = 0; i < gop.gopSize; i++) {
143 JsonFrameLayerInfo frame = frameVec_[frameId + i];
144 if (frame.layer > layerMax) {
145 layerMax = frame.layer;
146 }
147 auto it = layerNumFrame.find(frame.layer);
148 if (it != layerNumFrame.end()) {
149 layerNumFrame[frame.layer] = layerNumFrame[frame.layer] + 1;
150 } else {
151 layerNumFrame.emplace(frame.layer, 1);
152 }
153 frameMap_.emplace(frame.dts, frame);
154 }
155 gop.layerCount = layerMax + 1;
156 gop.layerFrameNum = layerNumFrame;
157 frameGopMap_.emplace(gop.gopId, gop);
158 }
159 }
160
InitMP4Scene(MP4Scene scene)161 void InnerDemuxerParserSample::InitMP4Scene(MP4Scene scene)
162 {
163 InitAVCScene(scene);
164 InitHEVCScene(scene);
165 }
166
InitAVCScene(MP4Scene scene)167 void InnerDemuxerParserSample::InitAVCScene(MP4Scene scene)
168 {
169 switch (scene) {
170 case MP4Scene::ONE_I_FRAME_AVC:
171 gopJson_ = GopInfoOneIAvc;
172 frameLayerJson_ = FrameLayerInfoOneIAvc;
173 break;
174 case MP4Scene::ALL_I_FRAME_AVC:
175 gopJson_ = GopInfoAllIAvc;
176 frameLayerJson_ = FrameLayerInfoAllIAvc;
177 break;
178 case MP4Scene::IPB_FRAME_AVC:
179 gopJson_ = GopInfoIpbAvc;
180 frameLayerJson_ = FrameLayerInfoIpbAvc;
181 break;
182 case MP4Scene::SDTP_FRAME_AVC:
183 gopJson_ = GopInfoStdpAvc;
184 frameLayerJson_ = FrameLayerInfoStdpAvc;
185 break;
186 case MP4Scene::OPENGOP_FRAME_AVC:
187 break;
188 case MP4Scene::LTR_FRAME_AVC:
189 gopJson_ = GopInfoLTRAvc;
190 frameLayerJson_ = FrameLayerInfoLTRAvc;
191 break;
192 case MP4Scene::TWO_LAYER_FRAME_AVC:
193 gopJson_ = GopInfoTwoLayerAvc;
194 frameLayerJson_ = FrameLayerInfoTwoLayerAvc;
195 break;
196 case MP4Scene::THREE_LAYER_FRAME_AVC:
197 gopJson_ = GopInfoThreeLayerAvc;
198 frameLayerJson_ = FrameLayerInfoThreeLayerAvc;
199 break;
200 case MP4Scene::FOUR_LAYER_FRAME_AVC:
201 gopJson_ = GopInfoFourLayerAvc;
202 frameLayerJson_ = FrameLayerInfoFourLayerAvc;
203 break;
204 default:
205 break;
206 }
207 }
208
InitHEVCScene(MP4Scene scene)209 void InnerDemuxerParserSample::InitHEVCScene(MP4Scene scene)
210 {
211 switch (scene) {
212 case MP4Scene::ONE_I_FRAME_HEVC:
213 gopJson_ = GopInfoOneIHevc;
214 frameLayerJson_ = FrameLayerInfoOneIHevc;
215 break;
216 case MP4Scene::ALL_I_FRAME_HEVC:
217 gopJson_ = GopInfoAllIHevc;
218 frameLayerJson_ = FrameLayerInfoAllIHevc;
219 break;
220 case MP4Scene::IPB_FRAME_HEVC:
221 gopJson_ = GopInfoIpbHevc;
222 frameLayerJson_ = FrameLayerInfoIpbHevc;
223 break;
224 case MP4Scene::SDTP_FRAME_HEVC:
225 gopJson_ = GopInfoStdpHevc;
226 frameLayerJson_ = FrameLayerInfoStdpHevc;
227 break;
228 case MP4Scene::LTR_FRAME_HEVC:
229 gopJson_ = GopInfoLTRHevc;
230 frameLayerJson_ = FrameLayerInfoLTRHevc;
231 break;
232 case MP4Scene::TWO_LAYER_FRAME_HEVC:
233 gopJson_ = GopInfoTwoLayerHevc;
234 frameLayerJson_ = FrameLayerInfoTwoLayerHevc;
235 break;
236 case MP4Scene::THREE_LAYER_FRAME_HEVC:
237 gopJson_ = GopInfoThreeLayerHevc;
238 frameLayerJson_ = FrameLayerInfoThreeLayerHevc;
239 break;
240 case MP4Scene::FOUR_LAYER_FRAME_HEVC:
241 gopJson_ = GopInfoFourLayerHevc;
242 frameLayerJson_ = FrameLayerInfoFourLayerHevc;
243 break;
244 case MP4Scene::SDTP_EXTENDED_HEVC:
245 gopJson_ = GopInfoStdpExtendedHevc;
246 frameLayerJson_ = FrameLayerInfoStdpExtendedHevc;
247 break;
248 case MP4Scene::HDR_1_HEVC:
249 gopJson_ = GopInfoHdr1Hevc;
250 frameLayerJson_ = FrameLayerInfoHdr1Hevc;
251 break;
252 case MP4Scene::HDR_2_HEVC:
253 gopJson_ = GopInfoHdr2Hevc;
254 frameLayerJson_ = FrameLayerInfoHdr2Hevc;
255 break;
256 default:
257 break;
258 }
259 }
260
GetFileSize(const std::string & filePath)261 size_t InnerDemuxerParserSample::GetFileSize(const std::string& filePath)
262 {
263 size_t fileSize = 0;
264 if (!filePath.empty()) {
265 struct stat fileStatus {};
266 if (stat(filePath.c_str(), &fileStatus) == 0) {
267 fileSize = static_cast<size_t>(fileStatus.st_size);
268 }
269 }
270 return fileSize;
271 }
272
RunSeekScene(WorkPts workPts)273 bool InnerDemuxerParserSample::RunSeekScene(WorkPts workPts)
274 {
275 int64_t pts = GetPtsFromWorkPts(workPts);
276 float durationNum = 0.0;
277 if (pts > duration / durationNum) {
278 cout << "pts > duration" << endl;
279 return true;
280 }
281 int32_t ret = 0;
282 ret = this->demuxer_->StartReferenceParser(pts);
283 cout << "StartReferenceParser pts:" << pts << endl;
284 if (ret != 0) {
285 cout << "StartReferenceParser fail ret:" << ret << endl;
286 return false;
287 }
288 bool checkResult = true;
289 ret = demuxer_->SeekToTime(pts, Media::SeekMode::SEEK_PREVIOUS_SYNC);
290 if (ret != 0) {
291 cout << "SeekToTime fail ret:" << ret << endl;
292 return false;
293 }
294 usleep(usleepTime);
295 FrameLayerInfo frameLayerInfo;
296 bool isEosFlag = true;
297 int32_t ptsNum = 1000;
298 while (isEosFlag) {
299 ret = this->demuxer_->ReadSampleBuffer(videoTrackIdx, avBuffer);
300 if (ret != 0) {
301 cout << "ReadSampleBuffer fail ret:" << ret << endl;
302 isEosFlag = false;
303 break;
304 }
305 if (avBuffer->pts_ >= pts * ptsNum || avBuffer->flag_ == AVCODEC_BUFFER_FLAG_EOS) {
306 cout << "read sample end" << endl;
307 isEosFlag = false;
308 break;
309 }
310 this->demuxer_->GetFrameLayerInfo(avBuffer, frameLayerInfo);
311 cout << "isDiscardable: " << frameLayerInfo.isDiscardable << ", gopId: " << frameLayerInfo.gopId
312 << ", layer: " << frameLayerInfo.layer << ", dts_: " << avBuffer->dts_ << endl;
313 checkResult = CheckFrameLayerResult(frameLayerInfo, avBuffer->dts_, false);
314 if (!checkResult) {
315 cout << "CheckFrameLayerResult is false!!" << endl;
316 break;
317 }
318 }
319 return checkResult;
320 }
321
RunSpeedScene(WorkPts workPts)322 bool InnerDemuxerParserSample::RunSpeedScene(WorkPts workPts)
323 {
324 int64_t pts = GetPtsFromWorkPts(workPts);
325 int32_t ret = 0;
326 ret = demuxer_->SeekToTime(pts, Media::SeekMode::SEEK_PREVIOUS_SYNC);
327 if (ret != 0) {
328 return false;
329 }
330 ret = this->demuxer_->StartReferenceParser(pts);
331 if (ret != 0) {
332 return false;
333 }
334 usleep(usleepTime);
335 FrameLayerInfo frameLayerInfo;
336 GopLayerInfo gopLayerInfo;
337 bool isEosFlag = true;
338 bool checkResult = true;
339 int num = 0;
340 while (isEosFlag) {
341 ret = this->demuxer_->ReadSampleBuffer(videoTrackIdx, avBuffer);
342 if (ret != 0) {
343 isEosFlag = false;
344 break;
345 }
346 if (avBuffer->flag_ & AVCODEC_BUFFER_FLAG_EOS) {
347 isEosFlag = false;
348 break;
349 }
350 if (avBuffer->pts_ >= pts * num) {
351 ret = this->demuxer_->GetFrameLayerInfo(avBuffer, frameLayerInfo);
352 if (ret != 0) {
353 checkResult = false;
354 break;
355 }
356 checkResult = CheckFrameLayerResult(frameLayerInfo, avBuffer->dts_, true);
357 if (!checkResult) {
358 break;
359 }
360 ret = this->demuxer_->GetGopLayerInfo(frameLayerInfo.gopId, gopLayerInfo);
361 if (ret != 0) {
362 checkResult = false;
363 break;
364 }
365 checkResult = CheckGopLayerResult(gopLayerInfo, frameLayerInfo.gopId);
366 if (!checkResult) {
367 break;
368 }
369 }
370 }
371 return checkResult;
372 }
373
CheckFrameLayerResult(FrameLayerInfo & info,int64_t dts,bool speedScene)374 bool InnerDemuxerParserSample::CheckFrameLayerResult(FrameLayerInfo &info, int64_t dts, bool speedScene)
375 {
376 JsonFrameLayerInfo frame = frameMap_[dts];
377 if ((frame.discardable && info.isDiscardable) || (!frame.discardable && !info.isDiscardable)) {
378 if (speedScene) {
379 if ((GetGopIdFromFrameId(frame.frameId) != info.gopId) || (frame.layer != info.layer)) {
380 return false;
381 }
382 }
383 return true;
384 }
385 return false;
386 }
387
CheckGopLayerResult(GopLayerInfo & info,int32_t gopId)388 bool InnerDemuxerParserSample::CheckGopLayerResult(GopLayerInfo &info, int32_t gopId)
389 {
390 JsonGopInfo frame = frameGopMap_[gopId];
391 bool conditionOne = (frame.gopSize != info.gopSize);
392 bool conditionTwo = (frame.layerCount != info.layerCount);
393 bool conditionThree = (!std::equal(frame.layerFrameNum.begin(),
394 frame.layerFrameNum.end(), info.layerFrameNum.begin()));
395 if (conditionOne || conditionTwo || conditionThree) {
396 return false;
397 }
398 return true;
399 }
400
GetGopIdFromFrameId(int32_t frameId)401 uint32_t InnerDemuxerParserSample::GetGopIdFromFrameId(int32_t frameId)
402 {
403 uint32_t gopId = 0;
404 for (auto gop : gopVec_) {
405 if ((frameId >= gop.startFrameId) && (frameId < gop.startFrameId + gop.gopSize)) {
406 gopId = gop.gopId;
407 break;
408 }
409 }
410 return gopId;
411 }
412
GetPtsFromWorkPts(WorkPts workPts)413 int64_t InnerDemuxerParserSample::GetPtsFromWorkPts(WorkPts workPts)
414 {
415 int64_t pts = 0;
416 float num = 1000.0;
417 switch (workPts) {
418 case WorkPts::START_PTS:
419 pts = 0;
420 break;
421 case WorkPts::END_PTS:
422 pts = duration / num;
423 break;
424 case WorkPts::RANDOM_PTS:
425 srand(time(NULL));
426 pts = rd() % duration / num;
427 break;
428 case WorkPts::SPECIFIED_PTS:
429 pts = specified_pts;
430 break;
431 default:
432 break;
433 }
434 cout << "GetPtsFromWorkPts pts:" << pts << endl;
435 return pts;
436 }
437 }
438 }