1 /*
2 * Copyright (C) 2023 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 "avmuxer_ffmpeg_demo.h"
17 #include <dlfcn.h>
18 #include <iostream>
19 #include <fcntl.h>
20 #include <fstream>
21 #include "data_sink_fd.h"
22 #include "plugin/plugin_manager_v2.h"
23
24 namespace OHOS {
25 namespace MediaAVCodec {
DoAddTrack(int32_t & trackIndex,std::shared_ptr<Meta> trackDesc)26 int AVMuxerFFmpegDemo::DoAddTrack(int32_t &trackIndex, std::shared_ptr<Meta> trackDesc)
27 {
28 int32_t tempTrackId = 0;
29 ffmpegMuxer_->AddTrack(tempTrackId, trackDesc);
30 if (tempTrackId < 0) {
31 std::cout<<"AVMuxerFFmpegDemo::DoAddTrack failed! trackId:"<<tempTrackId<<std::endl;
32 return -1;
33 }
34 trackIndex = tempTrackId;
35 return 0;
36 }
37
DoRunMuxer()38 void AVMuxerFFmpegDemo::DoRunMuxer()
39 {
40 long long testTimeStart = GetTimestamp();
41 std::string outFileName = GetOutputFileName("ffmpeg_mux");
42 outFd_ = open(outFileName.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
43 if (outFd_ < 0) {
44 std::cout<<"create muxer output file failed! fd:"<<outFd_<<std::endl;
45 return;
46 }
47 std::cout<<"==== open success! =====\noutputFileName: "<<outFileName<<"\n============"<<std::endl;
48
49 ffmpegMuxer_ = CreatePlugin(Plugins::OutputFormat::MPEG_4);
50 if (ffmpegMuxer_ == nullptr) {
51 std::cout<<"ffmpegMuxer create failed!"<<std::endl;
52 return;
53 }
54
55 ffmpegMuxer_->SetDataSink(std::make_shared<DataSinkFd>(outFd_));
56
57 AddAudioTrack(audioParams_);
58 AddVideoTrack(videoParams_);
59 AddCoverTrack(coverParams_);
60
61 ffmpegMuxer_->Start();
62 WriteCoverSample();
63 WriteTrackSample();
64 ffmpegMuxer_->Stop();
65 long long testTimeEnd = GetTimestamp();
66 std::cout << "muxer used time: " << testTimeEnd - testTimeStart << "us" << std::endl;
67 }
68
DoRunMultiThreadCase()69 void AVMuxerFFmpegDemo::DoRunMultiThreadCase()
70 {
71 std::cout<<"ffmpeg plugin demo is not support multi-thread write!"<<std::endl;
72 return;
73 }
74
DoWriteSample(uint32_t trackIndex,std::shared_ptr<AVBuffer> sample)75 int AVMuxerFFmpegDemo::DoWriteSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
76 {
77 if (ffmpegMuxer_ != nullptr &&
78 ffmpegMuxer_->WriteSample(trackIndex, sample) == Status::OK) {
79 return 0;
80 }
81 return -1;
82 }
83
CreatePlugin(Plugins::OutputFormat format)84 std::shared_ptr<Plugins::MuxerPlugin> AVMuxerFFmpegDemo::CreatePlugin(Plugins::OutputFormat format)
85 {
86 static const std::unordered_map<Plugins::OutputFormat, std::string> table = {
87 {Plugins::OutputFormat::DEFAULT, Plugins::MimeType::MEDIA_MP4},
88 {Plugins::OutputFormat::MPEG_4, Plugins::MimeType::MEDIA_MP4},
89 {Plugins::OutputFormat::M4A, Plugins::MimeType::MEDIA_M4A},
90 {Plugins::OutputFormat::MP3, Plugins::MimeType::MEDIA_MP3},
91 };
92
93 auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByMime(Plugins::PluginType::MUXER, table.at(format));
94 if (plugin == nullptr) {
95 return nullptr;
96 }
97 return std::reinterpret_pointer_cast<Plugins::MuxerPlugin>(plugin);
98 }
99 } // namespace MediaAVCodec
100 } // namespace OHOS