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