1da853ecaSopenharmony_ci/*
2da853ecaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License.
5da853ecaSopenharmony_ci * You may obtain a copy of the License at
6da853ecaSopenharmony_ci *
7da853ecaSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8da853ecaSopenharmony_ci *
9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and
13da853ecaSopenharmony_ci * limitations under the License.
14da853ecaSopenharmony_ci */
15da853ecaSopenharmony_ci
16da853ecaSopenharmony_ci#include "avmuxer_ffmpeg_demo.h"
17da853ecaSopenharmony_ci#include <dlfcn.h>
18da853ecaSopenharmony_ci#include <iostream>
19da853ecaSopenharmony_ci#include <fcntl.h>
20da853ecaSopenharmony_ci#include <fstream>
21da853ecaSopenharmony_ci#include "data_sink_fd.h"
22da853ecaSopenharmony_ci#include "plugin/plugin_manager_v2.h"
23da853ecaSopenharmony_ci
24da853ecaSopenharmony_cinamespace OHOS {
25da853ecaSopenharmony_cinamespace MediaAVCodec {
26da853ecaSopenharmony_ciint AVMuxerFFmpegDemo::DoAddTrack(int32_t &trackIndex, std::shared_ptr<Meta> trackDesc)
27da853ecaSopenharmony_ci{
28da853ecaSopenharmony_ci    int32_t tempTrackId = 0;
29da853ecaSopenharmony_ci    ffmpegMuxer_->AddTrack(tempTrackId, trackDesc);
30da853ecaSopenharmony_ci    if (tempTrackId < 0) {
31da853ecaSopenharmony_ci        std::cout<<"AVMuxerFFmpegDemo::DoAddTrack failed! trackId:"<<tempTrackId<<std::endl;
32da853ecaSopenharmony_ci        return -1;
33da853ecaSopenharmony_ci    }
34da853ecaSopenharmony_ci    trackIndex = tempTrackId;
35da853ecaSopenharmony_ci    return 0;
36da853ecaSopenharmony_ci}
37da853ecaSopenharmony_ci
38da853ecaSopenharmony_civoid AVMuxerFFmpegDemo::DoRunMuxer()
39da853ecaSopenharmony_ci{
40da853ecaSopenharmony_ci    long long testTimeStart = GetTimestamp();
41da853ecaSopenharmony_ci    std::string outFileName = GetOutputFileName("ffmpeg_mux");
42da853ecaSopenharmony_ci    outFd_ = open(outFileName.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
43da853ecaSopenharmony_ci    if (outFd_ < 0) {
44da853ecaSopenharmony_ci        std::cout<<"create muxer output file failed! fd:"<<outFd_<<std::endl;
45da853ecaSopenharmony_ci        return;
46da853ecaSopenharmony_ci    }
47da853ecaSopenharmony_ci    std::cout<<"==== open success! =====\noutputFileName: "<<outFileName<<"\n============"<<std::endl;
48da853ecaSopenharmony_ci
49da853ecaSopenharmony_ci    ffmpegMuxer_ = CreatePlugin(Plugins::OutputFormat::MPEG_4);
50da853ecaSopenharmony_ci    if (ffmpegMuxer_ == nullptr) {
51da853ecaSopenharmony_ci        std::cout<<"ffmpegMuxer create failed!"<<std::endl;
52da853ecaSopenharmony_ci        return;
53da853ecaSopenharmony_ci    }
54da853ecaSopenharmony_ci
55da853ecaSopenharmony_ci    ffmpegMuxer_->SetDataSink(std::make_shared<DataSinkFd>(outFd_));
56da853ecaSopenharmony_ci
57da853ecaSopenharmony_ci    AddAudioTrack(audioParams_);
58da853ecaSopenharmony_ci    AddVideoTrack(videoParams_);
59da853ecaSopenharmony_ci    AddCoverTrack(coverParams_);
60da853ecaSopenharmony_ci
61da853ecaSopenharmony_ci    ffmpegMuxer_->Start();
62da853ecaSopenharmony_ci    WriteCoverSample();
63da853ecaSopenharmony_ci    WriteTrackSample();
64da853ecaSopenharmony_ci    ffmpegMuxer_->Stop();
65da853ecaSopenharmony_ci    long long testTimeEnd = GetTimestamp();
66da853ecaSopenharmony_ci    std::cout << "muxer used time: " << testTimeEnd - testTimeStart << "us" << std::endl;
67da853ecaSopenharmony_ci}
68da853ecaSopenharmony_ci
69da853ecaSopenharmony_civoid AVMuxerFFmpegDemo::DoRunMultiThreadCase()
70da853ecaSopenharmony_ci{
71da853ecaSopenharmony_ci    std::cout<<"ffmpeg plugin demo is not support multi-thread write!"<<std::endl;
72da853ecaSopenharmony_ci    return;
73da853ecaSopenharmony_ci}
74da853ecaSopenharmony_ci
75da853ecaSopenharmony_ciint AVMuxerFFmpegDemo::DoWriteSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
76da853ecaSopenharmony_ci{
77da853ecaSopenharmony_ci    if (ffmpegMuxer_ != nullptr &&
78da853ecaSopenharmony_ci        ffmpegMuxer_->WriteSample(trackIndex, sample) == Status::OK) {
79da853ecaSopenharmony_ci        return 0;
80da853ecaSopenharmony_ci    }
81da853ecaSopenharmony_ci    return -1;
82da853ecaSopenharmony_ci}
83da853ecaSopenharmony_ci
84da853ecaSopenharmony_cistd::shared_ptr<Plugins::MuxerPlugin> AVMuxerFFmpegDemo::CreatePlugin(Plugins::OutputFormat format)
85da853ecaSopenharmony_ci{
86da853ecaSopenharmony_ci    static const std::unordered_map<Plugins::OutputFormat, std::string> table = {
87da853ecaSopenharmony_ci        {Plugins::OutputFormat::DEFAULT, Plugins::MimeType::MEDIA_MP4},
88da853ecaSopenharmony_ci        {Plugins::OutputFormat::MPEG_4, Plugins::MimeType::MEDIA_MP4},
89da853ecaSopenharmony_ci        {Plugins::OutputFormat::M4A, Plugins::MimeType::MEDIA_M4A},
90da853ecaSopenharmony_ci        {Plugins::OutputFormat::MP3, Plugins::MimeType::MEDIA_MP3},
91da853ecaSopenharmony_ci    };
92da853ecaSopenharmony_ci
93da853ecaSopenharmony_ci    auto plugin = Plugins::PluginManagerV2::Instance().CreatePluginByMime(Plugins::PluginType::MUXER, table.at(format));
94da853ecaSopenharmony_ci    if (plugin == nullptr) {
95da853ecaSopenharmony_ci        return nullptr;
96da853ecaSopenharmony_ci    }
97da853ecaSopenharmony_ci    return std::reinterpret_pointer_cast<Plugins::MuxerPlugin>(plugin);
98da853ecaSopenharmony_ci}
99da853ecaSopenharmony_ci}  // namespace MediaAVCodec
100da853ecaSopenharmony_ci}  // namespace OHOS