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 "parser_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 "native_avcodec_base.h"
23
24 using namespace OHOS;
25 using namespace OHOS::Media;
26 using namespace std;
27 using namespace OHOS::MediaAVCodec;
28
~ParserSample()29 ParserSample::~ParserSample()
30 {
31 if (fd > 0) {
32 close(fd);
33 fd = 0;
34 }
35 if (source != nullptr) {
36 source = nullptr;
37 }
38 if (demuxer != nullptr) {
39 demuxer = nullptr;
40 }
41 if (avBuffer != nullptr) {
42 avBuffer = nullptr;
43 }
44 }
45
GetFileSize(const char * fileName)46 static int64_t GetFileSize(const char *fileName)
47 {
48 int64_t fileSize = 0;
49 if (fileName != nullptr) {
50 struct stat fileStatus {};
51 if (stat(fileName, &fileStatus) == 0) {
52 fileSize = static_cast<int64_t>(fileStatus.st_size);
53 }
54 }
55 return fileSize;
56 }
57
CreateDemuxer(uint32_t buffersize,int64_t ptsForPtsIndex,int64_t frameIndex)58 int ParserSample::CreateDemuxer(uint32_t buffersize, int64_t ptsForPtsIndex, int64_t frameIndex)
59 {
60 Format sourceFormat;
61 Format trackFormat;
62 uint64_t presentationTimeUs = 0;
63 uint32_t indexForPtsIndex = 0;
64 fd = open(filePath, O_RDONLY);
65 source = AVSourceFactory::CreateWithFD(fd, 0, GetFileSize(filePath));
66 if (!source) {
67 close(fd);
68 fd = 0;
69 return -1;
70 }
71 demuxer = AVDemuxerFactory::CreateWithSource(source);
72 if (!demuxer) {
73 source = nullptr;
74 close(fd);
75 fd = 0;
76 return -1;
77 }
78 int32_t ret = source->GetSourceFormat(sourceFormat);
79 if (ret != 0) {
80 return -1;
81 }
82 if (!sourceFormat.GetIntValue(OH_MD_KEY_TRACK_COUNT, gTrackCount)) {
83 return -1;
84 }
85 for (int32_t index = 0; index < gTrackCount; index++) {
86 demuxer->SelectTrackByID(index);
87 demuxer->GetRelativePresentationTimeUsByIndex(index, frameIndex, presentationTimeUs);
88 demuxer->GetIndexByRelativePresentationTimeUs(index, ptsForPtsIndex, indexForPtsIndex);
89 }
90 std::shared_ptr<AVAllocator> allocator = AVAllocatorFactory::CreateSharedAllocator(MemoryFlag::MEMORY_READ_WRITE);
91 avBuffer = OHOS::Media::AVBuffer::CreateAVBuffer(allocator, buffersize);
92 return 0;
93 }
94
RunReferenceParser(int64_t pts,int64_t ptsForPtsIndex,int64_t frameIndex,uint32_t createSize)95 void ParserSample::RunReferenceParser(int64_t pts, int64_t ptsForPtsIndex, int64_t frameIndex, uint32_t createSize)
96 {
97 int ret = CreateDemuxer(createSize, ptsForPtsIndex, frameIndex);
98 if (ret < 0) {
99 return;
100 }
101 ret = demuxer->StartReferenceParser(pts);
102 if (ret != 0) {
103 return;
104 }
105 ret = demuxer->ReadSampleBuffer(createSize, avBuffer);
106 if (ret != 0) {
107 return;
108 }
109 FrameLayerInfo frameLayerInfo;
110 ret = demuxer->GetFrameLayerInfo(avBuffer, frameLayerInfo);
111 if (ret != 0) {
112 return;
113 }
114 GopLayerInfo gopLayerInfo;
115 ret = demuxer->GetGopLayerInfo(frameLayerInfo.gopId, gopLayerInfo);
116 if (ret != 0) {
117 printf("GetGopLayerInfo fail\n");
118 }
119 }