• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #include <gtest/gtest.h>
17 #include <string>
18 #include <vector>
19 #include <fcntl.h>
20 #include <fstream>
21 #include "avmuxer_sample.h"
22 #include "buffer/avbuffer.h"
23 #include "buffer/avbuffer_queue_producer.h"
24 #include "nocopyable.h"
25 #include "avmuxer.h"
26 #include "native_avbuffer.h"
27 #include "avcodec_audio_channel_layout.h"
28 #ifdef AVMUXER_UNITTEST_CAPI
29 #include "native_avmuxer.h"
30 #include "native_avformat.h"
31 #endif
32 
33 using namespace testing::ext;
34 using namespace OHOS::Media;
35 namespace OHOS {
36 namespace MediaAVCodec {
37 const std::string TEST_FILE_PATH = "/data/test/media/";
38 
39 class AVMuxerFlacUnitTest : public testing::Test {
40 public:
41     static void SetUpTestCase(void);
42     static void TearDownTestCase(void);
43     void SetUp(void);
44     void TearDown(void);
45     int32_t WriteSample(int32_t trackId, std::shared_ptr<std::ifstream> file, bool &eosFlag, uint32_t flag);
46 
47 protected:
48     std::shared_ptr<AVMuxerSample> avmuxer_ {nullptr};
49     std::shared_ptr<std::ifstream> inputFile_ = nullptr;
50     int32_t fd_ {-1};
51 };
52 
SetUpTestCase()53 void AVMuxerFlacUnitTest::SetUpTestCase()
54 {}
55 
TearDownTestCase()56 void AVMuxerFlacUnitTest::TearDownTestCase()
57 {}
58 
SetUp()59 void AVMuxerFlacUnitTest::SetUp()
60 {
61     avmuxer_ = std::make_shared<AVMuxerSample>();
62 }
63 
TearDown()64 void AVMuxerFlacUnitTest::TearDown()
65 {
66     if (fd_ >= 0) {
67         close(fd_);
68         fd_ = -1;
69     }
70 
71     if (inputFile_ != nullptr) {
72         if (inputFile_->is_open()) {
73             inputFile_->close();
74         }
75     }
76 
77     if (avmuxer_ != nullptr) {
78         avmuxer_->Destroy();
79         avmuxer_ = nullptr;
80     }
81 }
82 
WriteSample(int32_t trackId,std::shared_ptr<std::ifstream> file,bool & eosFlag,uint32_t flag)83 int32_t AVMuxerFlacUnitTest::WriteSample(int32_t trackId, std::shared_ptr<std::ifstream> file,
84                                          bool &eosFlag, uint32_t flag)
85 {
86     OH_AVCodecBufferAttr info;
87 
88     if (file->eof()) {
89         eosFlag = true;
90         return 0;
91     }
92     file->read(reinterpret_cast<char*>(&info.pts), sizeof(info.pts));
93 
94     if (file->eof()) {
95         eosFlag = true;
96         return 0;
97     }
98     file->read(reinterpret_cast<char*>(&info.flags), sizeof(info.flags));
99 
100     if (file->eof()) {
101         eosFlag = true;
102         return 0;
103     }
104     file->read(reinterpret_cast<char*>(&info.size), sizeof(info.size));
105 
106     if (file->eof()) {
107         eosFlag = true;
108         return 0;
109     }
110 
111     OH_AVBuffer *buffer = nullptr;
112     if (info.size == 0) {
113         buffer = OH_AVBuffer_Create(1);
114     } else {
115         buffer = OH_AVBuffer_Create(info.size);
116         file->read(reinterpret_cast<char*>(OH_AVBuffer_GetAddr(buffer)), info.size);
117     }
118 
119     OH_AVBuffer_SetBufferAttr(buffer, &info);
120     int32_t ret = avmuxer_->WriteSampleBuffer(trackId, buffer);
121     OH_AVBuffer_Destroy(buffer);
122     return ret;
123 }
124 
125 /**
126  * @tc.name: Muxer_FLAC_001
127  * @tc.desc: supported muxer flac
128  * @tc.type: FUNC
129  */
130 HWTEST_F(AVMuxerFlacUnitTest, Muxer_FLAC_001, TestSize.Level0)
131 {
132     int32_t trackId = -1;
133     std::string outputFile = TEST_FILE_PATH + std::string("Muxer_FLAC_48000_1.flac");
134     OH_AVOutputFormat outputFormat = AV_OUTPUT_FORMAT_FLAC;
135 
136     fd_ = open(outputFile.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
137     bool isCreated = avmuxer_->CreateMuxer(fd_, outputFormat);
138     ASSERT_TRUE(isCreated);
139 
140     std::shared_ptr<FormatMock> audioParams = FormatMockFactory::CreateFormat();
141     audioParams->PutStringValue(OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_FLAC);
142     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 48000); // 48000 sample rate
143     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 1); // 1 channels
144     audioParams->PutIntValue(OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S16LE);
145     int32_t ret = avmuxer_->AddTrack(trackId, audioParams);
146     ASSERT_EQ(ret, 0);
147     ASSERT_GE(trackId, 0);
148     ASSERT_EQ(avmuxer_->Start(), 0);
149 
150     inputFile_ = std::make_shared<std::ifstream>("/data/test/media/flac_48000_1_s16le.dat", std::ios::binary);
151 
152     int32_t extSize = 0;
153     inputFile_->read(reinterpret_cast<char*>(&extSize), sizeof(extSize));
154     ASSERT_EQ(extSize, 34);  // 34 -> flac codecConfig len
155     if (extSize > 0) {
156         std::vector<uint8_t> buffer(extSize);
157         inputFile_->read(reinterpret_cast<char*>(buffer.data()), extSize);
158         audioParams->PutBuffer(OH_MD_KEY_CODEC_CONFIG, buffer.data(), buffer.size());
159     }
160 
161     bool eosFlag = false;
162     uint32_t flag = AVCODEC_BUFFER_FLAGS_SYNC_FRAME;
163     ret = WriteSample(trackId, inputFile_, eosFlag, flag);
164     while (!eosFlag && (ret == 0)) {
165         ret = WriteSample(trackId, inputFile_, eosFlag, flag);
166     }
167     ASSERT_EQ(ret, 0);
168     ASSERT_EQ(avmuxer_->Stop(), 0);
169 }
170 
171 /**
172  * @tc.name: Muxer_FLAC_002
173  * @tc.desc: supported muxer flac with no codec config
174  * @tc.type: FUNC
175  */
176 HWTEST_F(AVMuxerFlacUnitTest, Muxer_FLAC_002, TestSize.Level0)
177 {
178     int32_t trackId = -1;
179     std::string outputFile = TEST_FILE_PATH + std::string("Muxer_FLAC_48000_1.flac");
180     OH_AVOutputFormat outputFormat = AV_OUTPUT_FORMAT_FLAC;
181 
182     fd_ = open(outputFile.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
183     bool isCreated = avmuxer_->CreateMuxer(fd_, outputFormat);
184     ASSERT_TRUE(isCreated);
185 
186     std::shared_ptr<FormatMock> audioParams = FormatMockFactory::CreateFormat();
187     audioParams->PutStringValue(OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_FLAC);
188     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 48000); // 48000 sample rate
189     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 1); // 1 channels
190     audioParams->PutIntValue(OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S16LE);
191     int32_t ret = avmuxer_->AddTrack(trackId, audioParams);
192     ASSERT_EQ(ret, 0);
193     ASSERT_GE(trackId, 0);
194     ASSERT_EQ(avmuxer_->Start(), 0);
195 
196     inputFile_ = std::make_shared<std::ifstream>("/data/test/media/flac_48000_1_s16le.dat", std::ios::binary);
197 
198     int32_t extSize = 0;
199     inputFile_->read(reinterpret_cast<char*>(&extSize), sizeof(extSize));
200     ASSERT_EQ(extSize, 34);  // 34 -> flac codecConfig len
201     if (extSize > 0) {
202         std::vector<uint8_t> buffer(extSize);
203         inputFile_->read(reinterpret_cast<char*>(buffer.data()), extSize);
204     }
205 
206     bool eosFlag = false;
207     uint32_t flag = AVCODEC_BUFFER_FLAGS_SYNC_FRAME;
208     ret = WriteSample(trackId, inputFile_, eosFlag, flag);
209     while (!eosFlag && (ret == 0)) {
210         ret = WriteSample(trackId, inputFile_, eosFlag, flag);
211     }
212     ASSERT_EQ(ret, 0);
213     ASSERT_EQ(avmuxer_->Stop(), 0);
214 }
215 
216 /**
217  * @tc.name: AddTrack_001
218  * @tc.desc: test muxer flac add track
219  * @tc.type: FUNC
220  */
221 HWTEST_F(AVMuxerFlacUnitTest, AddTrack_001, TestSize.Level0)
222 {
223     int32_t trackId = -1;
224     std::string outputFile = TEST_FILE_PATH + std::string("Muxer_FLAC_48000_1.flac");
225     OH_AVOutputFormat outputFormat = AV_OUTPUT_FORMAT_FLAC;
226 
227     fd_ = open(outputFile.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
228     bool isCreated = avmuxer_->CreateMuxer(fd_, outputFormat);
229     ASSERT_TRUE(isCreated);
230 
231     std::shared_ptr<FormatMock> audioParams = FormatMockFactory::CreateFormat();
232     audioParams->PutStringValue(OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_FLAC);
233     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 48000); // 48000 sample rate
234     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 9); // 9 channels
235     audioParams->PutIntValue(OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S16LE);
236     int32_t ret = avmuxer_->AddTrack(trackId, audioParams);
237     EXPECT_NE(ret, 0);
238     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 0); // 9 channels
239     ret = avmuxer_->AddTrack(trackId, audioParams);
240     EXPECT_NE(ret, 0);
241     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 2); // 2 channels
242     ret = avmuxer_->AddTrack(trackId, audioParams);
243     EXPECT_EQ(ret, 0);
244 }
245 
246 /**
247  * @tc.name: AddTrack_002
248  * @tc.desc: test muxer flac add track
249  * @tc.type: FUNC
250  */
251 HWTEST_F(AVMuxerFlacUnitTest, AddTrack_002, TestSize.Level0)
252 {
253     int32_t trackId = -1;
254     std::string outputFile = TEST_FILE_PATH + std::string("Muxer_FLAC_48000_1.flac");
255     OH_AVOutputFormat outputFormat = AV_OUTPUT_FORMAT_FLAC;
256 
257     fd_ = open(outputFile.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
258     bool isCreated = avmuxer_->CreateMuxer(fd_, outputFormat);
259     ASSERT_TRUE(isCreated);
260 
261     std::shared_ptr<FormatMock> audioParams = FormatMockFactory::CreateFormat();
262     audioParams->PutStringValue(OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_FLAC);
263     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, -1); // -1 sample rate
264     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 1); // 1 channels
265     audioParams->PutIntValue(OH_MD_KEY_AUDIO_SAMPLE_FORMAT, SAMPLE_S16LE);
266     int32_t ret = avmuxer_->AddTrack(trackId, audioParams);
267     EXPECT_NE(ret, 0);
268     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 0); // 48000 sample rate
269     ret = avmuxer_->AddTrack(trackId, audioParams);
270     EXPECT_NE(ret, 0);
271     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 96000); // 96000 sample rate
272     ret = avmuxer_->AddTrack(trackId, audioParams);
273     EXPECT_EQ(ret, 0);
274     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 192000); // 192000 sample rate
275     ret = avmuxer_->AddTrack(trackId, audioParams);
276     EXPECT_EQ(ret, 0);
277     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 384000); // 384000 sample rate
278     ret = avmuxer_->AddTrack(trackId, audioParams);
279     EXPECT_EQ(ret, 0);
280     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 768000); // 768000 sample rate
281     ret = avmuxer_->AddTrack(trackId, audioParams);
282     EXPECT_EQ(ret, 0);
283 }
284 
285 /**
286  * @tc.name: AddTrack_003
287  * @tc.desc: test muxer flac add track
288  * @tc.type: FUNC
289  */
290 HWTEST_F(AVMuxerFlacUnitTest, AddTrack_003, TestSize.Level0)
291 {
292     int32_t trackId = -1;
293     std::string outputFile = TEST_FILE_PATH + std::string("Muxer_FLAC_48000_1.flac");
294     OH_AVOutputFormat outputFormat = AV_OUTPUT_FORMAT_FLAC;
295 
296     fd_ = open(outputFile.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
297     bool isCreated = avmuxer_->CreateMuxer(fd_, outputFormat);
298     ASSERT_TRUE(isCreated);
299 
300     std::shared_ptr<FormatMock> audioParams = FormatMockFactory::CreateFormat();
301     audioParams->PutStringValue(OH_MD_KEY_CODEC_MIME, OH_AVCODEC_MIMETYPE_AUDIO_FLAC);
302     audioParams->PutIntValue(OH_MD_KEY_AUD_SAMPLE_RATE, 48000); // 48000 sample rate
303     audioParams->PutIntValue(OH_MD_KEY_AUD_CHANNEL_COUNT, 1); // 1 channels
304     audioParams->PutIntValue(OH_MD_KEY_AUDIO_SAMPLE_FORMAT, static_cast<int32_t>(0xff));
305     int32_t ret = avmuxer_->AddTrack(trackId, audioParams);
306     EXPECT_NE(ret, 0);
307     audioParams->PutIntValue(OH_MD_KEY_AUDIO_SAMPLE_FORMAT, static_cast<int32_t>(-1));
308     ret = avmuxer_->AddTrack(trackId, audioParams);
309     EXPECT_NE(ret, 0);
310 }
311 } // namespace MediaAVCodec
312 } // namespace OHOS