1 /*
2 * Copyright (c) 2025 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 "demuxer_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
~DemuxerSample()27 DemuxerSample::~DemuxerSample()
28 {
29 if (fd > 0) {
30 close(fd);
31 fd = 0;
32 }
33 if (source != nullptr) {
34 OH_AVSource_Destroy(source);
35 source = nullptr;
36 }
37 if (uriSource != nullptr) {
38 OH_AVSource_Destroy(uriSource);
39 uriSource = nullptr;
40 }
41 if (demuxer != nullptr) {
42 OH_AVDemuxer_Destroy(demuxer);
43 demuxer = nullptr;
44 }
45 if (sourceFormat != nullptr) {
46 OH_AVFormat_Destroy(sourceFormat);
47 sourceFormat = nullptr;
48 }
49 if (memory != nullptr) {
50 OH_AVMemory_Destroy(memory);
51 memory = nullptr;
52 }
53 if (buffer != nullptr) {
54 OH_AVBuffer_Destroy(buffer);
55 buffer = nullptr;
56 }
57 if (format != nullptr) {
58 OH_AVFormat_Destroy(format);
59 format = nullptr;
60 }
61 if (audioFormat != nullptr) {
62 OH_AVFormat_Destroy(audioFormat);
63 audioFormat = nullptr;
64 }
65 if (videoFormat != nullptr) {
66 OH_AVFormat_Destroy(videoFormat);
67 videoFormat = nullptr;
68 }
69 }
70
GetFileSize(const char * fileName)71 static int64_t GetFileSize(const char *fileName)
72 {
73 int64_t fileSize = 0;
74 if (fileName != nullptr) {
75 struct stat fileStatus {};
76 if (stat(fileName, &fileStatus) == 0) {
77 fileSize = static_cast<int64_t>(fileStatus.st_size);
78 }
79 }
80 return fileSize;
81 }
82
CreateDemuxer()83 int DemuxerSample::CreateDemuxer()
84 {
85 fd = open(filePath, O_RDONLY);
86 int64_t size = GetFileSize(filePath);
87 source = OH_AVSource_CreateWithFD(fd, 0, size);
88 if (!source) {
89 close(fd);
90 fd = 0;
91 return -1;
92 }
93 demuxer = OH_AVDemuxer_CreateWithSource(source);
94 if (!demuxer) {
95 OH_AVSource_Destroy(source);
96 source = nullptr;
97 close(fd);
98 fd = 0;
99 return -1;
100 }
101 return 0;
102 }
103
RunNormalDemuxer()104 void DemuxerSample::RunNormalDemuxer()
105 {
106 gReadEnd = false;
107 int ret = CreateDemuxer();
108 if (ret < 0) {
109 return;
110 }
111 sourceFormat = OH_AVSource_GetSourceFormat(source);
112 if (sourceFormat == nullptr) {
113 return;
114 }
115 OH_AVFormat_GetIntValue(sourceFormat, OH_MD_KEY_TRACK_COUNT, &gTrackCount);
116 for (int32_t index = 0; index < gTrackCount; index++) {
117 OH_AVDemuxer_SelectTrackByID(demuxer, index);
118 }
119 memory = OH_AVMemory_Create(gHeight * gWidth);
120 while (!gReadEnd && gTrackCount > 0) {
121 for (int32_t index = 0; index < gTrackCount; index++) {
122 OH_AVFormat *trackFormat = OH_AVSource_GetTrackFormat(source, index);
123 if (trackFormat == nullptr) {
124 gReadEnd = true;
125 break;
126 }
127 OH_AVFormat_GetIntValue(trackFormat, OH_MD_KEY_TRACK_TYPE, &gTrackType);
128 if (gTrackType == MEDIA_TYPE_AUD) {
129 OH_AVFormat_GetIntValue(trackFormat, "audio.soundbed.channels.number", &gTrackCount);
130 OH_AVFormat_GetIntValue(trackFormat, "audio.hoa.order", &gTrackCount);
131 OH_AVFormat_GetIntValue(trackFormat, "audio_object_number_key", &gTrackCount);
132 }
133 if (trackFormat) {
134 OH_AVFormat_Destroy(trackFormat);
135 trackFormat = nullptr;
136 }
137 ret = OH_AVDemuxer_ReadSample(demuxer, index, memory, &attr);
138 if (ret != 0) {
139 gReadEnd = true;
140 break;
141 }
142 if (attr.flags & OH_AVCodecBufferFlags::AVCODEC_BUFFER_FLAGS_EOS) {
143 gReadEnd = true;
144 break;
145 }
146 }
147 }
148 for (int32_t index = 0; index < gTrackCount; index++) {
149 OH_AVDemuxer_UnselectTrackByID(demuxer, index);
150 }
151 }