1 /*
2 * Copyright (c) 2024-2024 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 <cstdint>
17 #include <unistd.h>
18 #include "audio_video_muxer.h"
19 #include "camera_log.h"
20
21 namespace OHOS {
22 namespace CameraStandard {
23
AudioVideoMuxer()24 AudioVideoMuxer::AudioVideoMuxer()
25 {
26 }
27
~AudioVideoMuxer()28 AudioVideoMuxer::~AudioVideoMuxer()
29 {
30 MEDIA_INFO_LOG("~AudioVideoMuxer enter");
31 }
32
Create(OH_AVOutputFormat format,std::shared_ptr<PhotoAssetIntf> photoAssetProxy)33 int32_t AudioVideoMuxer::Create(OH_AVOutputFormat format, std::shared_ptr<PhotoAssetIntf> photoAssetProxy)
34 {
35 photoAssetProxy_ = photoAssetProxy;
36 if (photoAssetProxy_) {
37 fd_ = photoAssetProxy_->GetVideoFd();
38 } else {
39 MEDIA_ERR_LOG("AudioVideoMuxer::Create photoAssetProxy_ is nullptr!");
40 }
41 MEDIA_INFO_LOG("CreateAVMuxer with videoFd: %{public}d", fd_);
42 muxer_ = AVMuxerFactory::CreateAVMuxer(fd_, static_cast<Plugins::OutputFormat>(format));
43 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "create muxer failed!");
44 return 0;
45 }
46
Start()47 int32_t AudioVideoMuxer::Start()
48 {
49 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
50 int32_t ret = muxer_->Start();
51 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK, 1, "Start failed, ret: %{public}d", ret);
52 return 0;
53 }
54
SetRotation(int32_t rotation)55 int32_t AudioVideoMuxer::SetRotation(int32_t rotation)
56 {
57 MEDIA_INFO_LOG("SetRotation rotation : %{public}d", rotation);
58 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
59 std::shared_ptr<Meta> param = std::make_shared<Meta>();
60 param->Set<Tag::VIDEO_ROTATION>(static_cast<Plugins::VideoRotation>(rotation));
61 int32_t ret = muxer_->SetParameter(param);
62 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK, 1, "SetRotation failed, ret: %{public}d", ret);
63 return 0;
64 }
65
SetCoverTime(float timems)66 int32_t AudioVideoMuxer::SetCoverTime(float timems)
67 {
68 MEDIA_INFO_LOG("SetCoverTime coverTime : %{public}f", timems);
69 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
70 std::shared_ptr<Meta> userMeta = std::make_shared<Meta>();
71 userMeta->SetData("com.openharmony.covertime", timems);
72 int32_t ret = muxer_->SetUserMeta(userMeta);
73 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK, 1, "SetCoverTime failed, ret: %{public}d", ret);
74 return 0;
75 }
76
SetStartTime(float timems)77 int32_t AudioVideoMuxer::SetStartTime(float timems)
78 {
79 MEDIA_INFO_LOG("SetStartTime StartTime: %{public}f", timems);
80 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
81 constexpr int64_t SEC_TO_MSEC = 1e3;
82 constexpr int64_t MSEC_TO_NSEC = 1e6;
83 struct timespec realTime;
84 struct timespec monotonic;
85 clock_gettime(CLOCK_REALTIME, &realTime);
86 clock_gettime(CLOCK_MONOTONIC, &monotonic);
87 int64_t realTimeStamp = realTime.tv_sec * SEC_TO_MSEC + realTime.tv_nsec / MSEC_TO_NSEC;
88 int64_t monotonicTimeStamp = monotonic.tv_sec * SEC_TO_MSEC + monotonic.tv_nsec / MSEC_TO_NSEC;
89 int64_t firstFrameTime = realTimeStamp - monotonicTimeStamp + int64_t(timems);
90 std::string firstFrameTimeStr = std::to_string(firstFrameTime);
91 MEDIA_INFO_LOG("SetStartTime StartTime end: %{public}s", firstFrameTimeStr.c_str());
92 std::shared_ptr<Meta> userMeta = std::make_shared<Meta>();
93 userMeta->SetData("com.openharmony.starttime", firstFrameTimeStr);
94 int32_t ret = muxer_->SetUserMeta(userMeta);
95 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK, 1, "SetStartTime Failed, ret: %{public}d", ret);
96 return 0;
97 }
98
SetTimedMetadata()99 int32_t AudioVideoMuxer::SetTimedMetadata()
100 {
101 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
102 std::shared_ptr<Meta> param = std::make_shared<Meta>();
103 param->SetData("use_timed_meta_track", 1);
104 return muxer_->SetParameter(param);
105 }
106
WriteSampleBuffer(std::shared_ptr<OHOS::Media::AVBuffer> sample,TrackType type)107 int32_t AudioVideoMuxer::WriteSampleBuffer(std::shared_ptr<OHOS::Media::AVBuffer> sample, TrackType type)
108 {
109 CAMERA_SYNC_TRACE;
110 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
111 CHECK_ERROR_RETURN_RET_LOG(sample == nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
112 int32_t ret = AV_ERR_OK;
113 int trackId = -1;
114 switch (type) {
115 case TrackType::AUDIO_TRACK:
116 trackId = audioTrackId_;
117 break;
118 case TrackType::VIDEO_TRACK:
119 trackId = videoTrackId_;
120 break;
121 case TrackType::META_TRACK:
122 trackId = metaTrackId_;
123 break;
124 default:
125 MEDIA_ERR_LOG("TrackType type = %{public}d not supported", type);
126 }
127 ret = muxer_->WriteSample(trackId, sample);
128 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK, 1, "WriteSampleBuffer failed, ret: %{public}d", ret);
129 return 0;
130 }
131
GetVideoFd()132 int32_t AudioVideoMuxer::GetVideoFd()
133 {
134 return fd_;
135 }
136
GetPhotoAssetProxy()137 std::shared_ptr<PhotoAssetIntf> AudioVideoMuxer::GetPhotoAssetProxy()
138 {
139 return photoAssetProxy_;
140 }
141
142
AddTrack(int & trackId,std::shared_ptr<Format> format,TrackType type)143 int32_t AudioVideoMuxer::AddTrack(int &trackId, std::shared_ptr<Format> format, TrackType type)
144 {
145 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
146 CHECK_ERROR_RETURN_RET_LOG(format == nullptr, AV_ERR_INVALID_VAL, "input track format is nullptr!");
147 int32_t ret = muxer_->AddTrack(trackId, format->GetMeta());
148 switch (type) {
149 case TrackType::AUDIO_TRACK:
150 audioTrackId_ = trackId;
151 break;
152 case TrackType::VIDEO_TRACK:
153 videoTrackId_ = trackId;
154 break;
155 case TrackType::META_TRACK:
156 metaTrackId_ = trackId;
157 break;
158 default:
159 MEDIA_ERR_LOG("TrackType type = %{public}d not supported", type);
160 }
161 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK && trackId >= 0, 1, "AddTrack failed, ret: %{public}d", ret);
162 return 0;
163 }
164
Stop()165 int32_t AudioVideoMuxer::Stop()
166 {
167 CHECK_ERROR_RETURN_RET_LOG(muxer_ == nullptr, 1, "muxer_ is null");
168 int32_t ret = muxer_->Stop();
169 CHECK_ERROR_RETURN_RET_LOG(ret != AV_ERR_OK, 1, "Stop failed, ret: %{public}d", ret);
170 return 0;
171 }
172
Release()173 int32_t AudioVideoMuxer::Release()
174 {
175 MEDIA_INFO_LOG("AudioVideoMuxer::Release enter");
176 if (muxer_ != nullptr) {
177 muxer_ = nullptr;
178 close(fd_);
179 }
180 return 0;
181 }
182
183 } // CameraStandard
184 } // OHOS