• 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 "audio_muxer_demo.h"
17 #include <iostream>
18 #include <cstdio>
19 #include <unistd.h>
20 #include <dlfcn.h>
21 #include <sys/stat.h>
22 
23 #include "avcodec_common.h"
24 #include "avcodec_errors.h"
25 #include "media_description.h"
26 #include "native_avformat.h"
27 #include "demo_log.h"
28 #include "avcodec_codec_name.h"
29 #include "native_avbuffer.h"
30 #include "ffmpeg_converter.h"
31 
32 using namespace OHOS;
33 using namespace OHOS::MediaAVCodec;
34 using namespace OHOS::MediaAVCodec::AudioBufferDemo;
35 
36 constexpr int32_t WIDTH_720 = 720;
37 constexpr int32_t HEIGHT_480 = 480;
38 constexpr int32_t WIDTH_3840 = 3840;
39 constexpr int32_t HEIGHT_2160 = 2160;
40 constexpr int32_t COLOR_TRANSFER_2 = 2;
41 constexpr int32_t COLOR_TRANSFER_18 = 18;
42 constexpr int32_t FRAME_RATE_30 = 30;
43 constexpr int32_t FRAME_RATE_60 = 60;
44 constexpr int32_t FRAME_SIZE_1024 = 1024;
45 constexpr int32_t COLOR_PRIMARIES_2 = 2;
46 constexpr int32_t COLOR_PRIMARIES_9 = 9;
47 constexpr int32_t COLOR_MATRIXCIEFF_2 = 2;
48 constexpr int32_t COLOR_MATRIXCIEFF_9 = 9;
49 constexpr int32_t VIDEO_DELAY_2 = 2;
50 
51 constexpr int32_t CHANNELS_2 = 2;
52 
53 constexpr int32_t INFO_PTS_100 = 100;
54 constexpr int32_t INFO_SIZE_1024 = 1024;
55 
56 constexpr int32_t SAMPLE_RATE_8000 = 8000;
57 constexpr int32_t SAMPLE_RATE_16000 = 16000;
58 constexpr int32_t SAMPLE_RATE_44100 = 44100;
59 
60 constexpr const char* AAC_OUTPUT_FILE_PATH = "/data/test/media/muxer_AAC_outputfile.aac";
61 constexpr const char* AMRNB_OUTPUT_FILE_PATH = "/data/test/media/muxer_AMRNB_outputfile.amr";
62 constexpr const char* AMRWB_OUTPUT_FILE_PATH = "/data/test/media/muxer_AMRWB_outputfile.amr";
63 constexpr const char* M4A_OUTPUT_FILE_PATH = "/data/test/media/muxer_M4A_outputfile.m4a";
64 constexpr const char* MP3_OUTPUT_FILE_PATH = "/data/test/media/muxer_MP3_outputfile.mp3";
65 
AVMuxerDemo()66 AVMuxerDemo::AVMuxerDemo()
67 {
68 }
~AVMuxerDemo()69 AVMuxerDemo::~AVMuxerDemo()
70 {
71     if (avmuxer_) {
72         OH_AVMuxer_Destroy(avmuxer_);
73         avmuxer_ = nullptr;
74     }
75     if (avbuffer) {
76         OH_AVBuffer_Destroy(avbuffer);
77         avbuffer = nullptr;
78     }
79     if (outputFd_ > -1) {
80         close(outputFd_);
81         outputFd_ = -1;
82     }
83 }
84 
InitFile(const std::string & inputFile)85 bool AVMuxerDemo::InitFile(const std::string& inputFile)
86 {
87     if (inputFile.find("aac") != std::string::npos) {
88         audioType_ = AudioMuxerFormatType::TYPE_AAC;
89         output_path_ = AAC_OUTPUT_FILE_PATH;
90         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_AAC;
91     } else if (inputFile.find("h264") != std::string::npos) {
92         audioType_ = AudioMuxerFormatType::TYPE_H264;
93         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_MPEG_4;
94     } else if (inputFile.find("h265") != std::string::npos) {
95         audioType_ = AudioMuxerFormatType::TYPE_H265;
96         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_MPEG_4;
97     } else if (inputFile.find("mpeg4") != std::string::npos) {
98         audioType_ = AudioMuxerFormatType::TYPE_MPEG4;
99         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_MPEG_4;
100     } else if (inputFile.find("hdr") != std::string::npos) {
101         audioType_ = AudioMuxerFormatType::TYPE_HDR;
102         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_MPEG_4;
103     } else if (inputFile.find("jpg") != std::string::npos) {
104         audioType_ = AudioMuxerFormatType::TYPE_JPG;
105         output_path_ = M4A_OUTPUT_FILE_PATH;
106         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_MPEG_4;
107     } else if (inputFile.find("amrwb") != std::string::npos) {
108         audioType_ = AudioMuxerFormatType::TYPE_AMRWB;
109         output_path_ = AMRWB_OUTPUT_FILE_PATH;
110         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_AMR;
111     } else if (inputFile.find("amrnb") != std::string::npos) {
112         audioType_ = AudioMuxerFormatType::TYPE_AMRNB;
113         output_path_ = AMRNB_OUTPUT_FILE_PATH;
114         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_AMR;
115     } else if (inputFile.find("mpeg3") != std::string::npos) {
116         audioType_ = AudioMuxerFormatType::TYPE_MPEG3;
117         output_path_ = MP3_OUTPUT_FILE_PATH;
118         output_format_ = OH_AVOutputFormat::AV_OUTPUT_FORMAT_MP3;
119     }
120     return true;
121 }
RunCase(const uint8_t * data,size_t size)122 bool AVMuxerDemo::RunCase(const uint8_t *data, size_t size)
123 {
124     std::string codecdata(reinterpret_cast<const char *>(data), size);
125     inputdata = codecdata;
126     inputdatasize = size;
127     std::string outputFile(output_path_);
128 	//Create
129     avmuxer_ = Create();
130     DEMO_CHECK_AND_RETURN_RET_LOG(avmuxer_ != nullptr, false, "Fatal: Create fail");
131     DEMO_CHECK_AND_RETURN_RET_LOG(SetRotation(avmuxer_, 0) == AVCS_ERR_OK, false, "Fatal: SetRotation fail");
132     //获取param
133     AudioTrackParam param = InitFormatParam(audioType_);
134     int32_t trackIndex = -1;
135     //添加轨
136     int32_t res = 0;
137     if (param.isNeedCover) {
138         res = AddCoverTrack(avmuxer_, trackIndex, param);
139         DEMO_CHECK_AND_RETURN_RET_LOG(res == AVCS_ERR_OK, false, "Fatal: AddTrack fail");
140     } else {
141         res = AddTrack(avmuxer_, trackIndex, param);
142         DEMO_CHECK_AND_RETURN_RET_LOG(res == AVCS_ERR_OK, false, "Fatal: AddTrack fail");
143     }
144     //Start
145     DEMO_CHECK_AND_RETURN_RET_LOG(Start() == AVCS_ERR_OK, false, "Fatal: Start fail");
146     //写数据
147     if (param.isNeedCover) {
148         WriteTrackCover(avmuxer_, trackIndex);
149     } else {
150         WriteSingleTrackSampleAVBuffer(avmuxer_, trackIndex);
151     }
152     //Stop
153     DEMO_CHECK_AND_RETURN_RET_LOG(Stop() == AVCS_ERR_OK, false, "Fatal: Stop fail");
154     //Destroy
155     DEMO_CHECK_AND_RETURN_RET_LOG(Destroy() == AVCS_ERR_OK, false, "Fatal: Destroy fail");
156     return true;
157 }
158 
InitFormatParam(AudioMuxerFormatType type)159 AudioTrackParam AVMuxerDemo::InitFormatParam(AudioMuxerFormatType type)
160 {
161     AudioTrackParam param;
162     param.sampleRate = SAMPLE_RATE_44100;
163     param.channels = CHANNELS_2;
164     param.frameSize = FRAME_SIZE_1024;
165     param.width = WIDTH_720;
166     param.height = HEIGHT_480;
167     param.isNeedCover = false;
168     param.frameRate = FRAME_RATE_60;
169     param.videoDelay = 0;
170     param.colorPrimaries = COLOR_PRIMARIES_2;
171     param.colorTransfer = COLOR_TRANSFER_2;
172     param.colorMatrixCoeff = COLOR_MATRIXCIEFF_2;
173     param.colorRange = 0;
174     param.isHdrVivid = 0;
175     param.isNeedVideo = false;
176     if (audioType_ == AudioMuxerFormatType::TYPE_AAC) {
177         param.mimeType = OH_AVCODEC_MIMETYPE_AUDIO_AAC;
178     } else if (audioType_ == AudioMuxerFormatType::TYPE_H264) {
179         param.mimeType = OH_AVCODEC_MIMETYPE_VIDEO_AVC;
180     } else if (audioType_ == AudioMuxerFormatType::TYPE_H265) {
181         param.mimeType = OH_AVCODEC_MIMETYPE_VIDEO_HEVC;
182         param.videoDelay = VIDEO_DELAY_2;
183     } else if (audioType_ == AudioMuxerFormatType::TYPE_MPEG3 || audioType_ == AudioMuxerFormatType::TYPE_MPEG4) {
184         param.mimeType = OH_AVCODEC_MIMETYPE_AUDIO_MPEG;
185     } else if (audioType_ == AudioMuxerFormatType::TYPE_HDR) {
186         param.mimeType = OH_AVCODEC_MIMETYPE_VIDEO_HEVC;
187         param.width = WIDTH_3840;
188         param.height = HEIGHT_2160;
189         param.frameRate = FRAME_RATE_30;
190         param.colorPrimaries = COLOR_PRIMARIES_9;
191         param.colorTransfer = COLOR_TRANSFER_18;
192         param.colorMatrixCoeff = COLOR_MATRIXCIEFF_9;
193         param.isHdrVivid = 1;
194     } else if (audioType_ == AudioMuxerFormatType::TYPE_JPG) {
195         param.mimeType = OH_AVCODEC_MIMETYPE_IMAGE_JPG;
196         param.isNeedCover = true;
197     } else if (audioType_ == AudioMuxerFormatType::TYPE_AMRNB) {
198         param.mimeType = OH_AVCODEC_MIMETYPE_AUDIO_AMR_NB;
199         param.sampleRate = SAMPLE_RATE_8000;
200         param.channels = 1;
201     } else if (audioType_ == AudioMuxerFormatType::TYPE_AMRWB) {
202         param.mimeType = OH_AVCODEC_MIMETYPE_AUDIO_AMR_WB;
203         param.sampleRate = SAMPLE_RATE_16000;
204         param.channels = 1;
205     }
206     return param;
207 }
208 
Create()209 OH_AVMuxer* AVMuxerDemo::Create()
210 {
211     std::string outputFile(output_path_);
212     outputFd_ = open(outputFile.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
213     if (outputFd_ < 0) {
214         std::cout << "open file failed! outputFd_ is:" << outputFd_ << std::endl;
215         return nullptr;
216     }
217     return OH_AVMuxer_Create(outputFd_, output_format_);
218 }
219 
Start()220 int32_t AVMuxerDemo::Start()
221 {
222     return OH_AVMuxer_Start(avmuxer_);
223 }
224 
Stop()225 int32_t AVMuxerDemo::Stop()
226 {
227     return OH_AVMuxer_Stop(avmuxer_);
228 }
229 
Destroy()230 int32_t AVMuxerDemo::Destroy()
231 {
232     if (avbuffer != nullptr) {
233         OH_AVBuffer_Destroy(avbuffer);
234         avbuffer = nullptr;
235     }
236     int32_t res = 0;
237     if (avmuxer_ != nullptr) {
238         res = OH_AVMuxer_Destroy(avmuxer_);
239         avmuxer_ = nullptr;
240     }
241     return res;
242 }
243 
SetRotation(OH_AVMuxer * muxer,int32_t rotation)244 int32_t AVMuxerDemo::SetRotation(OH_AVMuxer* muxer, int32_t rotation)
245 {
246     return OH_AVMuxer_SetRotation(muxer, rotation);
247 }
248 
AddTrack(OH_AVMuxer * muxer,int32_t & trackIndex,AudioTrackParam param)249 int32_t AVMuxerDemo::AddTrack(OH_AVMuxer* muxer, int32_t& trackIndex, AudioTrackParam param)
250 {
251     const int configBufferSize =  0x1FFF;
252     OH_AVFormat *trackFormat = OH_AVFormat_Create();
253     if (trackFormat == NULL) {
254         std::cout << "AddTrack: format failed!" << std::endl;
255         return AV_ERR_INVALID_VAL;
256     }
257     // set codec config
258     int extraSize = inputdatasize > configBufferSize ? configBufferSize : inputdatasize;
259     unsigned char buffer[configBufferSize] = {0};
260     errno_t res = 0;
261     res = strncpy_s(reinterpret_cast<char*>(buffer), configBufferSize, inputdata.c_str(), extraSize);
262     if (res != 0) {
263         return res;
264     }
265     OH_AVFormat_SetBuffer(trackFormat, OH_MD_KEY_CODEC_CONFIG, buffer, extraSize);
266     OH_AVFormat_SetStringValue(trackFormat, OH_MD_KEY_CODEC_MIME, param.mimeType);
267     // audio
268     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUD_SAMPLE_RATE, param.sampleRate);
269     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, param.channels);
270     OH_AVFormat_SetIntValue(trackFormat, "audio_samples_per_frame", param.frameSize);
271     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AAC_IS_ADTS, 1);
272     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_PROFILE, AAC_PROFILE_LC);
273     //video
274     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_WIDTH, param.width);
275     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_HEIGHT, param.height);
276     OH_AVFormat_SetDoubleValue(trackFormat, OH_MD_KEY_FRAME_RATE, param.frameRate);
277     OH_AVFormat_SetIntValue(trackFormat, "video_delay", param.videoDelay);
278     // hdr vivid
279     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_COLOR_PRIMARIES, param.colorPrimaries);
280     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_TRANSFER_CHARACTERISTICS, param.colorTransfer);
281     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_MATRIX_COEFFICIENTS, param.colorMatrixCoeff);
282     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_RANGE_FLAG, param.colorRange);
283     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_VIDEO_IS_HDR_VIVID, param.isHdrVivid);
284     int32_t ret = OH_AVMuxer_AddTrack(muxer, &trackIndex, trackFormat);
285     return ret;
286 }
287 
288 
AddCoverTrack(OH_AVMuxer * muxer,int32_t & trackId,AudioTrackParam param)289 int32_t AVMuxerDemo::AddCoverTrack(OH_AVMuxer* muxer, int32_t& trackId, AudioTrackParam param)
290 {
291     OH_AVFormat *trackFormat = OH_AVFormat_Create();
292     if (trackFormat == NULL) {
293         std::cout << "format failed!" << std::endl;
294         return AV_ERR_INVALID_VAL;
295     }
296     OH_AVFormat_SetStringValue(trackFormat, OH_MD_KEY_CODEC_MIME, param.mimeType);
297     // audio
298     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUD_SAMPLE_RATE, param.sampleRate);
299     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_AUD_CHANNEL_COUNT, param.channels);
300     OH_AVFormat_SetIntValue(trackFormat, "audio_samples_per_frame", param.frameSize);
301     //video
302     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_WIDTH, param.width);
303     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_HEIGHT, param.height);
304     OH_AVFormat_SetDoubleValue(trackFormat, OH_MD_KEY_FRAME_RATE, param.frameRate);
305     OH_AVFormat_SetIntValue(trackFormat, "video_delay", param.videoDelay);
306     // hdr vivid
307     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_COLOR_PRIMARIES, param.colorPrimaries);
308     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_TRANSFER_CHARACTERISTICS, param.colorTransfer);
309     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_MATRIX_COEFFICIENTS, param.colorMatrixCoeff);
310     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_RANGE_FLAG, param.colorRange);
311     OH_AVFormat_SetIntValue(trackFormat, OH_MD_KEY_VIDEO_IS_HDR_VIVID, param.isHdrVivid);
312     int32_t ret = OH_AVMuxer_AddTrack(muxer, &trackId, trackFormat);
313     return ret;
314 }
315 
WriteTrackCover(OH_AVMuxer * muxer,int32_t trackIndex)316 void AVMuxerDemo::WriteTrackCover(OH_AVMuxer *muxer, int32_t trackIndex)
317 {
318     OH_AVCodecBufferAttr info;
319     memset_s(&info, sizeof(info), 0, sizeof(info));
320     info.size = inputdatasize;
321     OH_AVBuffer *av_buffer = OH_AVBuffer_Create(info.size);
322     if (av_buffer == NULL) {
323         std::cout << "WriteTrackCover: create OH_AVMemory error!" << std::endl;
324         return;
325     }
326     size_t frameBytes = 1024;
327     size_t cSize = inputdatasize < frameBytes ? inputdatasize : frameBytes;
328     errno_t res = 0;
329     res = strncpy_s(reinterpret_cast<char*>(OH_AVBuffer_GetAddr(av_buffer)), cSize, inputdata.c_str(), cSize);
330     if (res != 0) {
331         return;
332     }
333     if (OH_AVMuxer_WriteSampleBuffer(muxer, trackIndex, av_buffer) != AV_ERR_OK) {
334         OH_AVBuffer_Destroy(av_buffer);
335         av_buffer = nullptr;
336         std::cout << "OH_AVMuxer_WriteSample error!" << std::endl;
337         return;
338     }
339     if (av_buffer != nullptr) {
340         OH_AVBuffer_Destroy(av_buffer);
341         av_buffer = nullptr;
342     }
343 }
344 
WriteSingleTrackSampleAVBuffer(OH_AVMuxer * muxer,int32_t trackIndex)345 void AVMuxerDemo::WriteSingleTrackSampleAVBuffer(OH_AVMuxer *muxer, int32_t trackIndex)
346 {
347     if (muxer == NULL || trackIndex  < 0) {
348         std::cout << "WriteSingleTrackSample muxer is null " << trackIndex << std::endl;
349         return;
350     }
351     OH_AVCodecBufferAttr info;
352     OH_AVBuffer *buffer = NULL;
353     memset_s(&info, sizeof(info), 0, sizeof(info));
354     bool ret = UpdateWriteBufferInfoAVBuffer(&buffer, &info);
355 	//此处只执行一次,正常要根据内容进行while循环将buffer所有数据写入,因为fuzz数据是假数据,故仅调用一次;
356     if (ret) {
357         OH_AVMuxer_WriteSampleBuffer(muxer, trackIndex, buffer);
358     }
359     if (buffer != NULL) {
360         OH_AVBuffer_Destroy(buffer);
361         buffer = nullptr;
362     }
363 }
364 
UpdateWriteBufferInfoAVBuffer(OH_AVBuffer ** buffer,OH_AVCodecBufferAttr * info)365 bool AVMuxerDemo::UpdateWriteBufferInfoAVBuffer(OH_AVBuffer **buffer, OH_AVCodecBufferAttr *info)
366 {
367     //此处不区分音频类型,所有pts、size、flags均取一样的值
368     info->pts = INFO_PTS_100;
369     info->size = INFO_SIZE_1024;
370     info->flags = AVCODEC_BUFFER_FLAGS_NONE;
371     if (buffer == NULL || info == NULL) {
372         return false;
373     }
374     if (*buffer != NULL) {
375         std::cout << "UpdateWriteBufferInfoAVBuffer: buffer is NULL!" << std::endl;
376         OH_AVBuffer_Destroy(*buffer);
377         *buffer = NULL;
378     }
379     if (*buffer == NULL) {
380         *buffer = OH_AVBuffer_Create(info->size);
381     }
382     if (*buffer == NULL) {
383         std::cout << "UpdateWriteBufferInfoAVBuffer: error create OH_AVMemory! " << std::endl;
384         return false;
385     }
386     errno_t res = 0;
387     res = strncpy_s(reinterpret_cast<char *>(OH_AVBuffer_GetAddr(*buffer)), info->size, inputdata.c_str(), info->size);
388     if (res != 0) {
389         return false;
390     }
391     OH_AVBuffer_SetBufferAttr(*buffer, info);
392     return true;
393 }