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