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 "native_avmuxer.h"
17 #include <regex>
18 #include "avcodec_errors.h"
19 #include "avcodec_log.h"
20 #include "avmuxer.h"
21 #include "common/native_mfmagic.h"
22 #include "native_avmagic.h"
23
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_MUXER, "NativeAVMuxer"};
26 }
27
28 using namespace OHOS::Media;
29 using namespace OHOS::MediaAVCodec;
30
31 struct AVMuxerObject : public OH_AVMuxer {
AVMuxerObjectAVMuxerObject32 explicit AVMuxerObject(const std::shared_ptr<AVMuxer> &muxer)
33 : OH_AVMuxer(AVMagic::AVCODEC_MAGIC_AVMUXER), muxer_(muxer) {}
34 ~AVMuxerObject() = default;
35
36 const std::shared_ptr<AVMuxer> muxer_;
37 };
38
OH_AVMuxer_Create(int32_t fd,OH_AVOutputFormat format)39 struct OH_AVMuxer *OH_AVMuxer_Create(int32_t fd, OH_AVOutputFormat format)
40 {
41 std::shared_ptr<AVMuxer> avmuxer = AVMuxerFactory::CreateAVMuxer(fd, static_cast<Plugins::OutputFormat>(format));
42 CHECK_AND_RETURN_RET_LOG(avmuxer != nullptr, nullptr, "create muxer failed!");
43 struct AVMuxerObject *object = new(std::nothrow) AVMuxerObject(avmuxer);
44 return object;
45 }
46
OH_AVMuxer_SetRotation(OH_AVMuxer * muxer,int32_t rotation)47 OH_AVErrCode OH_AVMuxer_SetRotation(OH_AVMuxer *muxer, int32_t rotation)
48 {
49 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
50 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
51
52 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
53 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
54
55 std::shared_ptr<Meta> param = std::make_shared<Meta>();
56 param->Set<Tag::VIDEO_ROTATION>(static_cast<Plugins::VideoRotation>(rotation));
57 int32_t ret = object->muxer_->SetParameter(param);
58 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
59 "muxer_ SetRotation failed!");
60
61 return AV_ERR_OK;
62 }
63
OH_AVMuxer_SetFormat(OH_AVMuxer * muxer,OH_AVFormat * format)64 OH_AVErrCode OH_AVMuxer_SetFormat(OH_AVMuxer *muxer, OH_AVFormat *format)
65 {
66 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
67 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
68 CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
69 CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
70 "format magic error!");
71
72 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
73 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
74
75 std::shared_ptr<Meta> param = std::make_shared<Meta>();
76 std::shared_ptr<Meta> meta = format->format_.GetMeta();
77 CHECK_AND_RETURN_RET_LOG(meta != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
78 if (meta->Find(Tag::MEDIA_CREATION_TIME) != meta->end()) {
79 AVCODEC_LOGI("set format key %{public}s", Tag::MEDIA_CREATION_TIME);
80 std::string value;
81 meta->Get<Tag::MEDIA_CREATION_TIME>(value);
82 std::regex pattern(R"((\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.\d{1,6})?((\+|-\d{4})?)Z?)");
83 std::smatch match;
84 CHECK_AND_RETURN_RET_LOG(std::regex_match(value, match, pattern), AV_ERR_INVALID_VAL,
85 "format key %{public}s, value invalid", Tag::MEDIA_CREATION_TIME);
86 param->Set<Tag::MEDIA_CREATION_TIME>(value);
87 } else {
88 AVCODEC_LOGW("input format does not have a valid key!");
89 return AV_ERR_OK;
90 }
91 int32_t ret = object->muxer_->SetParameter(param);
92 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
93 "muxer_ SetFormat failed!");
94
95 return AV_ERR_OK;
96 }
97
OH_AVMuxer_AddTrack(OH_AVMuxer * muxer,int32_t * trackIndex,OH_AVFormat * trackFormat)98 OH_AVErrCode OH_AVMuxer_AddTrack(OH_AVMuxer *muxer, int32_t *trackIndex, OH_AVFormat *trackFormat)
99 {
100 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
101 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
102 CHECK_AND_RETURN_RET_LOG(trackIndex != nullptr, AV_ERR_INVALID_VAL, "input track index is nullptr!");
103 CHECK_AND_RETURN_RET_LOG(trackFormat != nullptr, AV_ERR_INVALID_VAL, "input track format is nullptr!");
104 CHECK_AND_RETURN_RET_LOG(trackFormat->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
105 "track format magic error!");
106
107 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
108 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
109
110 int32_t ret = object->muxer_->AddTrack(*trackIndex, trackFormat->format_.GetMeta());
111 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
112 "muxer_ AddTrack failed!");
113
114 return AV_ERR_OK;
115 }
116
OH_AVMuxer_Start(OH_AVMuxer * muxer)117 OH_AVErrCode OH_AVMuxer_Start(OH_AVMuxer *muxer)
118 {
119 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
120 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
121
122 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
123 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
124
125 int32_t ret = object->muxer_->Start();
126 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
127 "muxer_ Start failed!");
128
129 return AV_ERR_OK;
130 }
131
OH_AVMuxer_WriteSample(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVMemory * sample,OH_AVCodecBufferAttr info)132 OH_AVErrCode OH_AVMuxer_WriteSample(OH_AVMuxer *muxer, uint32_t trackIndex,
133 OH_AVMemory *sample, OH_AVCodecBufferAttr info)
134 {
135 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
136 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
137 CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
138 CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_SHARED_MEMORY, AV_ERR_INVALID_VAL,
139 "sample magic error!");
140 CHECK_AND_RETURN_RET_LOG(sample->memory_ != nullptr && info.offset >= 0 && info.size >= 0 &&
141 sample->memory_->GetSize() >= (info.offset + info.size), AV_ERR_INVALID_VAL, "invalid memory");
142
143 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
144 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
145
146 std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(sample->memory_->GetBase() + info.offset,
147 sample->memory_->GetSize(), info.size);
148 buffer->pts_ = info.pts;
149 buffer->flag_ = info.flags;
150
151 int32_t ret = object->muxer_->WriteSample(trackIndex, buffer);
152 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
153 "muxer_ WriteSample failed!");
154
155 return AV_ERR_OK;
156 }
157
OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,const OH_AVBuffer * sample)158 OH_AVErrCode OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer *muxer, uint32_t trackIndex,
159 const OH_AVBuffer *sample)
160 {
161 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
162 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
163 CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
164 CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_AVBUFFER, AV_ERR_INVALID_VAL,
165 "sample magic error!");
166
167 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
168 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
169
170 int32_t ret = object->muxer_->WriteSample(trackIndex, sample->buffer_);
171 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
172 "muxer_ WriteSampleBuffer failed!");
173
174 return AV_ERR_OK;
175 }
176
OH_AVMuxer_Stop(OH_AVMuxer * muxer)177 OH_AVErrCode OH_AVMuxer_Stop(OH_AVMuxer *muxer)
178 {
179 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
180 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
181
182 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
183 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
184
185 int32_t ret = object->muxer_->Stop();
186 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
187 "muxer_ Stop failed!");
188
189 return AV_ERR_OK;
190 }
191
OH_AVMuxer_Destroy(OH_AVMuxer * muxer)192 OH_AVErrCode OH_AVMuxer_Destroy(OH_AVMuxer *muxer)
193 {
194 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
195 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
196
197 delete muxer;
198
199 return AV_ERR_OK;
200 }