• 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     }
108 }
109 
SeparateMeta(std::shared_ptr<Meta> meta,std::shared_ptr<Meta> & definedMeta,std::shared_ptr<Meta> & userMeta)110 static void SeparateMeta(std::shared_ptr<Meta> meta, std::shared_ptr<Meta> &definedMeta,
111     std::shared_ptr<Meta> &userMeta)
112 {
113     for (auto iter = meta->begin(); iter != meta->end(); ++iter) {
114         TagType tag = iter->first;
115         if (meta->IsDefinedKey(tag)) {
116             CopyMetaData(tag, meta, definedMeta);
117         } else {
118             CopyMetaData(tag, meta, userMeta);
119         }
120     }
121 }
122 
SetDefinedMetaParam(std::shared_ptr<Meta> definedMeta,AVMuxerObject * object)123 static OH_AVErrCode SetDefinedMetaParam(std::shared_ptr<Meta> definedMeta, AVMuxerObject *object)
124 {
125     std::shared_ptr<Meta> param = std::make_shared<Meta>();
126     if (definedMeta->Find(Tag::MEDIA_CREATION_TIME) != definedMeta->end()) {
127         AVCODEC_LOGI("set format defined key %{public}s", Tag::MEDIA_CREATION_TIME);
128         std::string value;
129         definedMeta->Get<Tag::MEDIA_CREATION_TIME>(value);
130         std::regex pattern(R"((\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(.\d{1,6})?((\+|-\d{4})?)Z?)");
131         std::smatch match;
132         CHECK_AND_RETURN_RET_LOG(std::regex_match(value, match, pattern), AV_ERR_INVALID_VAL,
133             "format defined key %{public}s, value invalid", Tag::MEDIA_CREATION_TIME);
134         param->Set<Tag::MEDIA_CREATION_TIME>(value);
135     } else {
136         AVCODEC_LOGW("input format does not have a valid key!");
137         return AV_ERR_OK;
138     }
139     int32_t ret = object->muxer_->SetParameter(param);
140     return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
141 }
142 
SetUserMetaParam(std::shared_ptr<Meta> userMeta,AVMuxerObject * object)143 static OH_AVErrCode SetUserMetaParam(std::shared_ptr<Meta> userMeta, AVMuxerObject *object)
144 {
145     int32_t ret = object->muxer_->SetUserMeta(userMeta);
146     return AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret));
147 }
148 
OH_AVMuxer_SetFormat(OH_AVMuxer * muxer,OH_AVFormat * format)149 OH_AVErrCode OH_AVMuxer_SetFormat(OH_AVMuxer *muxer, OH_AVFormat *format)
150 {
151     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
152     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
153     CHECK_AND_RETURN_RET_LOG(format != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
154     CHECK_AND_RETURN_RET_LOG(format->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
155         "format magic error!");
156 
157     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
158     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
159 
160     std::shared_ptr<Meta> meta = format->format_.GetMeta();
161     std::shared_ptr<Meta> definedMeta = std::make_shared<Meta>();
162     std::shared_ptr<Meta> userMeta = std::make_shared<Meta>();
163 
164     CHECK_AND_RETURN_RET_LOG(meta != nullptr, AV_ERR_INVALID_VAL, "input format is nullptr!");
165     SeparateMeta(meta, definedMeta, userMeta);
166 
167     OH_AVErrCode ret = SetDefinedMetaParam(definedMeta, object);
168     CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, ret, "muxer_ SetFormat SetDefinedMetaParam failed!");
169 
170     if (userMeta != nullptr && !userMeta->Empty()) {
171         ret = SetUserMetaParam(userMeta, object);
172         CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, ret, "muxer_ SetFormat SetUserMetaParam failed!");
173     }
174     return AV_ERR_OK;
175 }
176 
OH_AVMuxer_AddTrack(OH_AVMuxer * muxer,int32_t * trackIndex,OH_AVFormat * trackFormat)177 OH_AVErrCode OH_AVMuxer_AddTrack(OH_AVMuxer *muxer, int32_t *trackIndex, OH_AVFormat *trackFormat)
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     CHECK_AND_RETURN_RET_LOG(trackIndex != nullptr, AV_ERR_INVALID_VAL, "input track index is nullptr!");
182     CHECK_AND_RETURN_RET_LOG(trackFormat != nullptr, AV_ERR_INVALID_VAL, "input track format is nullptr!");
183     CHECK_AND_RETURN_RET_LOG(trackFormat->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
184         "track format magic error!");
185 
186     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
187     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
188 
189     int32_t ret = object->muxer_->AddTrack(*trackIndex, trackFormat->format_.GetMeta());
190     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
191         "muxer_ AddTrack failed!");
192 
193     return AV_ERR_OK;
194 }
195 
OH_AVMuxer_Start(OH_AVMuxer * muxer)196 OH_AVErrCode OH_AVMuxer_Start(OH_AVMuxer *muxer)
197 {
198     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
199     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
200 
201     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
202     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
203 
204     int32_t ret = object->muxer_->Start();
205     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
206         "muxer_ Start failed!");
207 
208     return AV_ERR_OK;
209 }
210 
OH_AVMuxer_WriteSample(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVMemory * sample,OH_AVCodecBufferAttr info)211 OH_AVErrCode OH_AVMuxer_WriteSample(OH_AVMuxer *muxer, uint32_t trackIndex,
212     OH_AVMemory *sample, OH_AVCodecBufferAttr info)
213 {
214     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
215     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
216     CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
217     CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_SHARED_MEMORY, AV_ERR_INVALID_VAL,
218         "sample magic error!");
219     CHECK_AND_RETURN_RET_LOG(sample->memory_ != nullptr && info.offset >= 0 && info.size >= 0 &&
220         sample->memory_->GetSize() >= (info.offset + info.size), AV_ERR_INVALID_VAL, "invalid memory");
221 
222     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
223     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
224 
225     std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(sample->memory_->GetBase() + info.offset,
226         sample->memory_->GetSize(), info.size);
227     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AV_ERR_NO_MEMORY, "create buffer failed");
228     buffer->pts_ = info.pts;
229     buffer->flag_ = info.flags;
230 
231     int32_t ret = object->muxer_->WriteSample(trackIndex, buffer);
232     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
233         "muxer_ WriteSample failed!");
234 
235     return AV_ERR_OK;
236 }
237 
OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,const OH_AVBuffer * sample)238 OH_AVErrCode OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer *muxer, uint32_t trackIndex,
239     const OH_AVBuffer *sample)
240 {
241     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
242     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
243     CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
244     CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_AVBUFFER, AV_ERR_INVALID_VAL,
245         "sample magic error!");
246 
247     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
248     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
249 
250     int32_t ret = object->muxer_->WriteSample(trackIndex, sample->buffer_);
251     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
252         "muxer_ WriteSampleBuffer failed!");
253 
254     return AV_ERR_OK;
255 }
256 
OH_AVMuxer_Stop(OH_AVMuxer * muxer)257 OH_AVErrCode OH_AVMuxer_Stop(OH_AVMuxer *muxer)
258 {
259     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
260     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
261 
262     struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
263     CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
264 
265     int32_t ret = object->muxer_->Stop();
266     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
267         "muxer_ Stop failed!");
268 
269     return AV_ERR_OK;
270 }
271 
OH_AVMuxer_Destroy(OH_AVMuxer * muxer)272 OH_AVErrCode OH_AVMuxer_Destroy(OH_AVMuxer *muxer)
273 {
274     CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
275     CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
276 
277     delete muxer;
278 
279     return AV_ERR_OK;
280 }