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_demo.h"
17#include <iostream>
18#include <fstream>
19#include <cstdio>
20#include <unistd.h>
21#include <fcntl.h>
22#include <thread>
23#include <vector>
24#include "avcodec_errors.h"
25
26namespace OHOS {
27namespace MediaAVCodec {
28int AVMuxerDemo::DoWriteSample(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
29{
30    if (avmuxer_ != nullptr &&
31        avmuxer_->WriteSample(trackIndex, sample) == AVCS_ERR_OK) {
32        return 0;
33    }
34    return -1;
35}
36
37int AVMuxerDemo::DoAddTrack(int32_t &trackIndex, std::shared_ptr<Meta> trackDesc)
38{
39    int ret;
40    if ((ret = avmuxer_->AddTrack(trackIndex, trackDesc)) != AVCS_ERR_OK) {
41        std::cout<<"AVMuxerDemo::DoAddTrack failed! ret:"<<ret<<std::endl;
42        return -1;
43    }
44    return 0;
45}
46
47sptr<AVBufferQueueProducer> AVMuxerDemo::DoGetInputBufferQueue(uint32_t trackIndex)
48{
49    std::cout<<"AVMuxerDemo::DoGetInputBufferQueue "<<trackIndex<<std::endl;
50    return avmuxer_->GetInputBufferQueue(trackIndex);
51}
52
53void AVMuxerDemo::DoRunMuxer(const std::string &runMode)
54{
55    std::string outFileName = GetOutputFileName("inner_mux_" + runMode);
56    outFd_ = open(outFileName.c_str(), O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR);
57    if (outFd_ < 0) {
58        std::cout << "Open file failed! filePath is: " << outFileName << std::endl;
59        return;
60    }
61    std::cout<<"==== open success! =====\noutputFileName: "<<outFileName<<"\n============"<<std::endl;
62    long long testTimeStart = GetTimestamp();
63    avmuxer_ = AVMuxerFactory::CreateAVMuxer(outFd_, outputFormat_);
64    if (avmuxer_ == nullptr) {
65        std::cout << "avmuxer_ is null" << std::endl;
66        return;
67    }
68    std::cout << "create muxer success " << avmuxer_ << std::endl;
69
70    SetParameter();
71    AddAudioTrack(audioParams_);
72    AddVideoTrack(videoParams_);
73    AddCoverTrack(coverParams_);
74
75    std::cout << "add track success" << std::endl;
76
77    if (avmuxer_->Start() != AVCS_ERR_OK) {
78        return;
79    }
80
81    std::cout << "start muxer success" << std::endl;
82
83    WriteCoverSample();
84
85    std::cout<<"AVMuxerDemo::DoRunMuxer runMode is : "<<runMode<<std::endl;
86    if (runMode.compare(RUN_NORMAL) == 0) {
87        WriteTrackSample();
88    } else if (runMode.compare(RUN_MUL_THREAD) == 0) {
89        std::vector<std::thread> vecThread;
90        vecThread.emplace_back(MulThdWriteTrackSample, this, audioTrackId_, audioFile_);
91        vecThread.emplace_back(MulThdWriteTrackSample, this, videoTrackId_, videoFile_);
92        for (uint32_t i = 0; i < vecThread.size(); ++i) {
93            vecThread[i].join();
94        }
95    }
96
97    std::cout << "write muxer success" << std::endl;
98
99    if (avmuxer_->Stop() != AVCS_ERR_OK) {
100        return;
101    }
102    std::cout << "stop muxer success" << std::endl;
103    long long testTimeEnd = GetTimestamp();
104    std::cout << "muxer used time: " << testTimeEnd - testTimeStart << "us" << std::endl;
105}
106
107void AVMuxerDemo::DoRunMuxer()
108{
109    DoRunMuxer(std::string(RUN_NORMAL));
110}
111
112void AVMuxerDemo::DoRunMultiThreadCase()
113{
114    DoRunMuxer(std::string(RUN_MUL_THREAD));
115}
116
117void AVMuxerDemo::SetParameter()
118{
119    std::shared_ptr<Meta> param = std::make_shared<Meta>();
120    param->Set<Tag::VIDEO_ROTATION>(Plugins::VideoRotation::VIDEO_ROTATION_0);
121    param->Set<Tag::MEDIA_CREATION_TIME>("2023-12-19T03:16:00.000Z");
122    param->Set<Tag::MEDIA_LATITUDE>(22.67f);
123    param->Set<Tag::MEDIA_LONGITUDE>(114.06f);
124    param->Set<Tag::MEDIA_TITLE>("ohos muxer");
125    param->Set<Tag::MEDIA_ARTIST>("ohos muxer");
126    param->Set<Tag::MEDIA_COMPOSER>("ohos muxer");
127    param->Set<Tag::MEDIA_DATE>("2023-12-19");
128    param->Set<Tag::MEDIA_ALBUM>("ohos muxer");
129    param->Set<Tag::MEDIA_ALBUM_ARTIST>("ohos muxer");
130    param->Set<Tag::MEDIA_COPYRIGHT>("ohos muxer");
131    if (avmuxer_->SetParameter(param) != AVCS_ERR_OK) {
132        std::cout<<"set parameter failed!"<<std::endl;
133    }
134}
135}  // namespace MediaAVCodec
136}  // namespace OHOS