• 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 "demuxermp4auxl_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 
27 const int32_t WIDTH = 3840;
28 const int32_t HEIGHT = 2160;
29 
~DemuxerMp4AuxlSample()30 DemuxerMp4AuxlSample::~DemuxerMp4AuxlSample()
31 {
32     if (fd > 0) {
33         close(fd);
34         fd = 0;
35     }
36     if (source != nullptr) {
37         OH_AVSource_Destroy(source);
38         source = nullptr;
39     }
40     if (demuxer != nullptr) {
41         OH_AVDemuxer_Destroy(demuxer);
42         demuxer = nullptr;
43     }
44     if (sourceFormat != nullptr) {
45         OH_AVFormat_Destroy(sourceFormat);
46         sourceFormat = nullptr;
47     }
48 }
49 
GetFileSize(const char * fileName)50 static int64_t GetFileSize(const char *fileName)
51 {
52     int64_t fileSize = 0;
53     if (fileName != nullptr) {
54         struct stat fileStatus {};
55         if (stat(fileName, &fileStatus) == 0) {
56             fileSize = static_cast<int64_t>(fileStatus.st_size);
57         }
58     }
59     return fileSize;
60 }
61 
CreateDemuxer()62 int DemuxerMp4AuxlSample::CreateDemuxer()
63 {
64     fd = open(filePath, O_RDONLY);
65     int64_t size = GetFileSize(filePath);
66     source = OH_AVSource_CreateWithFD(fd, 0, size);
67     if (!source) {
68         close(fd);
69         fd = 0;
70         return -1;
71     }
72     demuxer = OH_AVDemuxer_CreateWithSource(source);
73     if (!demuxer) {
74         OH_AVSource_Destroy(source);
75         source = nullptr;
76         close(fd);
77         fd = 0;
78         return -1;
79     }
80     return 0;
81 }
82 
GetFormat(OH_AVFormat * format)83 void DemuxerMp4AuxlSample::GetFormat(OH_AVFormat* format)
84 {
85     int trackType = 0;
86     OH_AVFormat_GetIntValue(format, OH_MD_KEY_TRACK_TYPE, &trackType);
87     int64_t duration = 0;
88     OH_AVFormat_GetLongValue(format, OH_MD_KEY_DURATION, &duration);
89     float currentHeight = 0;
90     OH_AVFormat_GetFloatValue(format, OH_MD_KEY_HEIGHT, &currentHeight);
91     double frameRate;
92     OH_AVFormat_GetDoubleValue(format, OH_MD_KEY_FRAME_RATE, &frameRate);
93     const char* language = nullptr;
94     OH_AVFormat_GetStringValue(format, OH_MD_KEY_LANGUAGE, &language);
95     uint8_t *codecConfig = nullptr;
96     size_t bufferSize;
97     OH_AVFormat_GetBuffer(format, OH_MD_KEY_CODEC_CONFIG, &codecConfig, &bufferSize);
98     const char* trackDesc = nullptr;
99     OH_AVFormat_GetStringValue(format, OH_MD_KEY_TRACK_DESCRIPTION, &trackDesc);
100     const char* referenceType = nullptr;
101     OH_AVFormat_GetStringValue(format, OH_MD_KEY_TRACK_REFERENCE_TYPE, &referenceType);
102     int32_t* referenceIds = nullptr;
103     size_t referenceIdsSize = 0;
104     OH_AVFormat_GetIntBuffer(format, OH_MD_KEY_REFERENCE_TRACK_IDS, &referenceIds, &referenceIdsSize);
105 }
106 
RunNormalDemuxer(uint32_t createSize,int64_t time)107 void DemuxerMp4AuxlSample::RunNormalDemuxer(uint32_t createSize, int64_t time)
108 {
109     bool gReadEnd = false;
110     int ret = CreateDemuxer();
111     if (ret < 0) {
112         return;
113     }
114     sourceFormat = OH_AVSource_GetSourceFormat(source);
115     if (sourceFormat == nullptr) {
116         return;
117     }
118     int32_t trackCount;
119     OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &trackCount);
120     for (int32_t index = 0; index < trackCount; index++) {
121         OH_AVDemuxer_SelectTrackByID(demuxer, index);
122     }
123 
124     OH_AVBuffer *buffer = OH_AVBuffer_Create(WIDTH * HEIGHT);
125     while (!gReadEnd && trackCount > 0) {
126         for (int32_t index = 0; index < trackCount; index++) {
127             OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
128             if (trackFormat == nullptr) {
129                 gReadEnd = true;
130                 break;
131             }
132             GetFormat(trackFormat);
133             if (trackFormat) {
134                 OH_AVFormat_Destroy(trackFormat);
135                 trackFormat = nullptr;
136             }
137             ret = OH_AVDemuxer_ReadSampleBuffer(demuxer, index, buffer);
138             if (ret != 0) {
139                 gReadEnd = true;
140                 break;
141             }
142             OH_AVCodecBufferAttr attr;
143             OH_AVBuffer_GetBufferAttr(buffer, &attr);
144             if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
145                 gReadEnd = true;
146                 break;
147             }
148         }
149     }
150     if (buffer != nullptr) {
151         OH_AVBuffer_Destroy(buffer);
152         buffer = nullptr;
153     }
154     OH_AVDemuxer_SeekToTime(demuxer, time, SEEK_MODE_CLOSEST_SYNC);
155     OH_AVDemuxer_SeekToTime(demuxer, time, SEEK_MODE_PREVIOUS_SYNC);
156     OH_AVDemuxer_SeekToTime(demuxer, time, SEEK_MODE_NEXT_SYNC);
157 }