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