• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CopyMetaData(const TagType & tag,std::shared_ptr<Meta> & fromMeta,std::shared_ptr<Meta> & toMeta)64 static void CopyMetaData(const TagType &tag, std::shared_ptr<Meta> &fromMeta, std::shared_ptr<Meta> &toMeta)
65 {
66     AnyValueType type = fromMeta->GetValueType(tag);
67     if (type == AnyValueType::INVALID_TYPE || type == AnyValueType::STRING) {
68         std::string value;
69         fromMeta->GetData(tag, value);
70         toMeta->SetData(tag, value);
71     } else if (type == AnyValueType::BOOL) {
72         bool value = false;
73         fromMeta->GetData(tag, value);
74         toMeta->SetData(tag, value);
75     } else if (type == AnyValueType::INT8_T) {
76         int8_t value = 0;
77         fromMeta->GetData(tag, value);
78         toMeta->SetData(tag, value);
79     } else if (type == AnyValueType::UINT8_T) {
80         uint8_t value = 0;
81         fromMeta->GetData(tag, value);
82         toMeta->SetData(tag, value);
83     } else if (type == AnyValueType::INT32_T) {
84         int32_t value = 0;
85         fromMeta->GetData(tag, value);
86         toMeta->SetData(tag, value);
87     } else if (type == AnyValueType::UINT32_T) {
88         uint32_t value = 0;
89         fromMeta->GetData(tag, value);
90         toMeta->SetData(tag, value);
91     } else if (type == AnyValueType::INT64_T) {
92         int64_t value = 0;
93         fromMeta->GetData(tag, value);
94         toMeta->SetData(tag, value);
95     } else if (type == AnyValueType::UINT64_T) {
96         uint64_t value = 0;
97         fromMeta->GetData(tag, value);
98         toMeta->SetData(tag, value);
99     } else if (type == AnyValueType::FLOAT) {
100         float value = 0.0f;
101         fromMeta->GetData(tag, value);
102         toMeta->SetData(tag, value);
103     } else if (type == AnyValueType::DOUBLE) {
104         double value = 0.0;
105         fromMeta->GetData(tag, value);
106         toMeta->SetData(tag, value);
107     } else if (type == AnyValueType::VECTOR_UINT8) {
108         std::vector<uint8_t> value;
109         fromMeta->GetData(tag, value);
110         toMeta->SetData(tag, value);
111     }
112 }
113 
SeparateMeta(std::shared_ptr<Meta> meta,std::shared_ptr<Meta> & definedMeta,std::shared_ptr<Meta> & userMeta)114 static void SeparateMeta(std::shared_ptr<Meta> meta, std::shared_ptr<Meta> &definedMeta,
115     std::shared_ptr<Meta> &userMeta)
116 {
117     for (auto iter = meta->begin(); iter != meta->end(); ++iter) {
118         TagType tag = iter->first;
119         if (meta->IsDefinedKey(tag)) {
120             CopyMetaData(tag, meta, definedMeta);
121         } else {
122             CopyMetaData(tag, meta, userMeta);
123         }
124     }
125 }
126 
SetCreationTimeMeta(std::shared_ptr<Meta> definedMeta,std::shared_ptr<Meta> & param)127 static OH_AVErrCode SetCreationTimeMeta(std::shared_ptr<Meta> definedMeta, std::shared_ptr<Meta> &param)
128 {
129     if (definedMeta->Find(Tag::MEDIA_CREATION_TIME) == definedMeta->end()) {
130         return AV_ERR_OK;
131     }
132 
133     AVCODEC_LOGI("set format defined key %{public}s", Tag::MEDIA_CREATION_TIME);
134     std::string value;
135     definedMeta->Get<Tag::MEDIA_CREATION_TIME>(value);
136     std::regex pattern(R"((\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.\d{1,6})?((\+|-\d{4})?)Z?)");
137     std::smatch match;
138     CHECK_AND_RETURN_RET_LOG(std::regex_match(value, match, pattern), AV_ERR_INVALID_VAL, "creation time is invalid");
139 
140     param->Set<Tag::MEDIA_CREATION_TIME>(value);
141     return AV_ERR_OK;
142 }
143 
SetCommentMeta(std::shared_ptr<Meta> definedMeta,std::shared_ptr<Meta> & param)144 static OH_AVErrCode SetCommentMeta(std::shared_ptr<Meta> definedMeta, std::shared_ptr<Meta> &param)
145 {
146     if (definedMeta->Find(Tag::MEDIA_COMMENT) == definedMeta->end()) {
147         return AV_ERR_OK;
148     }
149 
150     AVCODEC_LOGI("set format defined key %{public}s", Tag::MEDIA_COMMENT);
151     std::string comment;
152     definedMeta->Get<Tag::MEDIA_COMMENT>(comment);
153     std::regex pattern(R"(^.{1,256}$)");
154     std::smatch match;
155     CHECK_AND_RETURN_RET_LOG(std::regex_match(comment, match, pattern), AV_ERR_INVALID_VAL, "comment is invalid");
156 
157     param->Set<Tag::MEDIA_COMMENT>(comment);
158     return AV_ERR_OK;
159 }
160 
SetMoovFrontMeta(std::shared_ptr<Meta> definedMeta,std::shared_ptr<Meta> & param)161 static OH_AVErrCode SetMoovFrontMeta(std::shared_ptr<Meta> definedMeta, std::shared_ptr<Meta> &param)
162 {
163     if (definedMeta->Find(Tag::MEDIA_ENABLE_MOOV_FRONT) == definedMeta->end()) {
164         return AV_ERR_OK;
165     }
166 
167     AVCODEC_LOGI("set format defined key %{public}s", Tag::MEDIA_ENABLE_MOOV_FRONT);
168     int32_t isFront;
169     definedMeta->Get<Tag::MEDIA_ENABLE_MOOV_FRONT>(isFront);
170     param->Set<Tag::MEDIA_ENABLE_MOOV_FRONT>(isFront);
171     return AV_ERR_OK;
172 }
173 
SetDefinedMetaParam(std::shared_ptr<Meta> definedMeta,AVMuxerObject * object)174 static OH_AVErrCode SetDefinedMetaParam(std::shared_ptr<Meta> definedMeta, AVMuxerObject* object)
175 {
176     std::shared_ptr<Meta> param = std::make_shared<Meta>();
177 
178     OH_AVErrCode metaRet = SetCreationTimeMeta(definedMeta, param);
179     CHECK_AND_RETURN_RET_LOG(metaRet == AV_ERR_OK, AV_ERR_INVALID_VAL, "input format is invalid");
180     metaRet = SetCommentMeta(definedMeta, param);
181     CHECK_AND_RETURN_RET_LOG(metaRet == AV_ERR_OK, AV_ERR_INVALID_VAL, "input format is invalid");
182     metaRet = SetMoovFrontMeta(definedMeta, param);
183     CHECK_AND_RETURN_RET_LOG(metaRet == AV_ERR_OK, AV_ERR_INVALID_VAL, "input format is invalid");
184 
185     if (param->Empty()) {
186         AVCODEC_LOGW("input format does not have a valid key");
187         return AV_ERR_OK;
188     }
189 
190     int32_t ret = object->muxer_->SetParameter(param);
191     return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
192 }
193 
SetUserMetaParam(std::shared_ptr<Meta> userMeta,AVMuxerObject * object)194 static OH_AVErrCode SetUserMetaParam(std::shared_ptr<Meta> userMeta, AVMuxerObject *object)
195 {
196     int32_t ret = object->muxer_->SetUserMeta(userMeta);
197     return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
198 }
199 
OH_AVMuxer_SetFormat(OH_AVMuxer * muxer,OH_AVFormat * format)200 OH_AVErrCode OH_AVMuxer_SetFormat(OH_AVMuxer *muxer, OH_AVFormat *format)
201 {
202     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
203     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
204     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
205     CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
206         "format magic error!");
207 
208     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
209     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
210 
211     std::shared_ptr<Meta> meta = format->format_.GetMeta();
212     std::shared_ptr<Meta> definedMeta = std::make_shared<Meta>();
213     std::shared_ptr<Meta> userMeta = std::make_shared<Meta>();
214 
215     CHECK_AND_RETURN_RET_LOG(meta != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
216     SeparateMeta(meta, definedMeta, userMeta);
217 
218     OH_AVErrCode ret = AV_ERR_OK;
219     if (definedMeta != nullptr && !definedMeta->Empty()) {
220         ret = SetDefinedMetaParam(definedMeta, object);
221         CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, ret, "muxer_ SetFormat SetDefinedMetaParam failed!");
222     }
223 
224     if (userMeta != nullptr && !userMeta->Empty()) {
225         ret = SetUserMetaParam(userMeta, object);
226         CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, ret, "muxer_ SetFormat SetUserMetaParam failed!");
227     }
228     return AV_ERR_OK;
229 }
230 
OH_AVMuxer_AddTrack(OH_AVMuxer * muxer,int32_t * trackIndex,OH_AVFormat * trackFormat)231 OH_AVErrCode OH_AVMuxer_AddTrack(OH_AVMuxer *muxer, int32_t *trackIndex, OH_AVFormat *trackFormat)
232 {
233     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
234     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
235     CHECK_AND_RETURN_RET_LOG(trackIndex != nullptr, AV_ERR_INVALID_VAL, "input track index is nullptr!");
236     CHECK_AND_RETURN_RET_LOG(trackFormat != nullptr, AV_ERR_INVALID_VAL, "input track format is nullptr!");
237     CHECK_AND_RETURN_RET_LOG(trackFormat->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
238         "track format magic error!");
239 
240     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
241     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
242 
243     int32_t ret = object->muxer_->AddTrack(*trackIndex, trackFormat->format_.GetMeta());
244     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
245         "muxer_ AddTrack failed!");
246 
247     return AV_ERR_OK;
248 }
249 
OH_AVMuxer_Start(OH_AVMuxer * muxer)250 OH_AVErrCode OH_AVMuxer_Start(OH_AVMuxer *muxer)
251 {
252     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
253     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
254 
255     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
256     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
257 
258     int32_t ret = object->muxer_->Start();
259     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
260         "muxer_ Start failed!");
261 
262     return AV_ERR_OK;
263 }
264 
OH_AVMuxer_WriteSample(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVMemory * sample,OH_AVCodecBufferAttr info)265 OH_AVErrCode OH_AVMuxer_WriteSample(OH_AVMuxer *muxer, uint32_t trackIndex,
266     OH_AVMemory *sample, OH_AVCodecBufferAttr info)
267 {
268     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
269     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
270     CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
271     CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_SHARED_MEMORY, AV_ERR_INVALID_VAL,
272         "sample magic error!");
273     CHECK_AND_RETURN_RET_LOG(sample->memory_ != nullptr && info.offset >= 0 && info.size >= 0 &&
274         sample->memory_->GetSize() >= (info.offset + info.size), AV_ERR_INVALID_VAL, "invalid memory");
275 
276     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
277     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
278 
279     std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(sample->memory_->GetBase() + info.offset,
280         sample->memory_->GetSize(), info.size);
281     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AV_ERR_NO_MEMORY, "create buffer failed");
282     buffer->pts_ = info.pts;
283     buffer->flag_ = info.flags;
284 
285     int32_t ret = object->muxer_->WriteSample(trackIndex, buffer);
286     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
287         "muxer_ WriteSample failed!");
288 
289     return AV_ERR_OK;
290 }
291 
OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,const OH_AVBuffer * sample)292 OH_AVErrCode OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer *muxer, uint32_t trackIndex,
293     const OH_AVBuffer *sample)
294 {
295     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
296     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
297     CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
298     CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_AVBUFFER, AV_ERR_INVALID_VAL,
299         "sample magic error!");
300 
301     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
302     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
303 
304     int32_t ret = object->muxer_->WriteSample(trackIndex, sample->buffer_);
305     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
306         "muxer_ WriteSampleBuffer failed!");
307 
308     return AV_ERR_OK;
309 }
310 
OH_AVMuxer_Stop(OH_AVMuxer * muxer)311 OH_AVErrCode OH_AVMuxer_Stop(OH_AVMuxer *muxer)
312 {
313     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
314     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
315 
316     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
317     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
318 
319     int32_t ret = object->muxer_->Stop();
320     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
321         "muxer_ Stop failed!");
322 
323     return AV_ERR_OK;
324 }
325 
OH_AVMuxer_Destroy(OH_AVMuxer * muxer)326 OH_AVErrCode OH_AVMuxer_Destroy(OH_AVMuxer *muxer)
327 {
328     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
329     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
330 
331     delete muxer;
332 
333     return AV_ERR_OK;
334 }