1 /*
2  * Copyright (c) 2023-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 "muxer.h"
17 
18 #include "dp_log.h"
19 
20 namespace OHOS {
21 namespace CameraStandard {
22 namespace DeferredProcessing {
23 namespace {
24     constexpr int32_t INVALID_TRACK_ID = -1;
25 }
26 
~Muxer()27 Muxer::~Muxer()
28 {
29     DP_DEBUG_LOG("entered.");
30     muxer_ = nullptr;
31 }
32 
Create(int32_t outputFd,Plugins::OutputFormat format)33 MediaManagerError Muxer::Create(int32_t outputFd, Plugins::OutputFormat format)
34 {
35     DP_DEBUG_LOG("entered.");
36     DP_CHECK_ERROR_RETURN_RET_LOG(outputFd == INVALID_FD, ERROR_FAIL, "outputFd is invalid: %{public}d.", outputFd);
37 
38     muxer_ = AVMuxerFactory::CreateAVMuxer(outputFd, format);
39     DP_CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, ERROR_FAIL, "create avmuxer failed.");
40 
41     return OK;
42 }
43 
AddTracks(const std::map<TrackType,const std::shared_ptr<Track>> & trackMap)44 MediaManagerError Muxer::AddTracks(const std::map<TrackType, const std::shared_ptr<Track>>& trackMap)
45 {
46     DP_DEBUG_LOG("entered.");
47     DP_CHECK_ERROR_RETURN_RET_LOG(trackMap.empty(), ERROR_FAIL, "finvalid track map.");
48 
49     DP_CHECK_ERROR_RETURN_RET_LOG(trackMap.find(TrackType::AV_KEY_VIDEO_TYPE) == trackMap.end(),
50         ERROR_FAIL, "not find video track.");
51     auto video = trackMap.at(TrackType::AV_KEY_VIDEO_TYPE);
52     auto ret = muxer_->AddTrack(videoTrackId_, video->GetFormat().format->GetMeta());
53     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "add video track failed.");
54 
55     DP_CHECK_ERROR_RETURN_RET_LOG(trackMap.find(TrackType::AV_KEY_AUDIO_TYPE) == trackMap.end(),
56         ERROR_FAIL, "not find audio track.");
57     auto audio = trackMap.at(TrackType::AV_KEY_AUDIO_TYPE);
58     ret = muxer_->AddTrack(audioTrackId_, audio->GetFormat().format->GetMeta());
59     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "add audio track failed.");
60 
61     return OK;
62 }
63 
WriteStream(TrackType trackType,const std::shared_ptr<AVBuffer> & sample)64 MediaManagerError Muxer::WriteStream(TrackType trackType, const std::shared_ptr<AVBuffer>& sample)
65 {
66     DP_DEBUG_LOG("entered.");
67     int32_t trackId = INVALID_TRACK_ID;
68     if (trackType == TrackType::AV_KEY_VIDEO_TYPE) {
69         trackId = videoTrackId_;
70     } else if (trackType == TrackType::AV_KEY_AUDIO_TYPE) {
71         trackId = audioTrackId_;
72     }
73     DP_CHECK_ERROR_RETURN_RET_LOG(trackId == INVALID_TRACK_ID, ERROR_FAIL, "invalid track id.");
74 
75     auto ret = muxer_->WriteSample(trackId, sample);
76     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "write sample failed.");
77 
78     return OK;
79 }
80 
Start()81 MediaManagerError Muxer::Start()
82 {
83     DP_DEBUG_LOG("entered.");
84     auto ret = muxer_->Start();
85     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
86         "failed to start, ret: %{public}d", ret);
87 
88     return OK;
89 }
90 
Stop()91 MediaManagerError Muxer::Stop()
92 {
93     DP_DEBUG_LOG("entered.");
94     auto ret = muxer_->Stop();
95     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "failed to stop, ret: %{public}d", ret);
96 
97     return OK;
98 }
AddMediaInfo(const std::shared_ptr<MediaInfo> & mediaInfo)99 MediaManagerError Muxer::AddMediaInfo(const std::shared_ptr<MediaInfo>& mediaInfo)
100 {
101     auto param = std::make_shared<Meta>();
102     int32_t rotation = mediaInfo->codecInfo.rotation == -1 ? 0 : mediaInfo->codecInfo.rotation;
103     param->Set<Tag::VIDEO_ROTATION>(static_cast<Plugins::VideoRotation>(rotation));
104     param->Set<Tag::MEDIA_CREATION_TIME>(mediaInfo->creationTime);
105     param->Set<Tag::MEDIA_LATITUDE>(mediaInfo->latitude);
106     param->Set<Tag::MEDIA_LONGITUDE>(mediaInfo->longitude);
107     auto ret = muxer_->SetParameter(param);
108     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
109         "add param failed, ret: %{public}d", ret);
110 
111     auto userMeta = std::make_shared<Meta>();
112     userMeta->SetData(VIDEO_FRAME_COUNT, mediaInfo->codecInfo.numFrames);
113     userMeta->SetData(RECORD_SYSTEM_TIMESTAMP, mediaInfo->recorderTime);
114     ret = muxer_->SetUserMeta(userMeta);
115     DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL,
116         "add userMeta failed, ret: %{public}d", ret);
117 
118     return OK;
119 }
120 } // namespace DeferredProcessing
121 } // namespace CameraStandard
122 } // namespace OHOS
123