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 "avcodec_errors.h"
18 #include "avcodec_log.h"
19 #include "avmuxer.h"
20 #include "common/native_mfmagic.h"
21 #include "native_avmagic.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "NativeAVMuxer"};
25 }
26
27 using namespace OHOS::Media;
28 using namespace OHOS::MediaAVCodec;
29
30 struct AVMuxerObject : public OH_AVMuxer {
AVMuxerObjectAVMuxerObject31 explicit AVMuxerObject(const std::shared_ptr<AVMuxer> &muxer)
32 : OH_AVMuxer(AVMagic::AVCODEC_MAGIC_AVMUXER), muxer_(muxer) {}
33 ~AVMuxerObject() = default;
34
35 const std::shared_ptr<AVMuxer> muxer_;
36 };
37
OH_AVMuxer_Create(int32_t fd,OH_AVOutputFormat format)38 struct OH_AVMuxer *OH_AVMuxer_Create(int32_t fd, OH_AVOutputFormat format)
39 {
40 std::shared_ptr<AVMuxer> avmuxer = AVMuxerFactory::CreateAVMuxer(fd, static_cast<Plugins::OutputFormat>(format));
41 CHECK_AND_RETURN_RET_LOG(avmuxer != nullptr, nullptr, "create muxer failed!");
42 struct AVMuxerObject *object = new(std::nothrow) AVMuxerObject(avmuxer);
43 return object;
44 }
45
OH_AVMuxer_SetRotation(OH_AVMuxer * muxer,int32_t rotation)46 OH_AVErrCode OH_AVMuxer_SetRotation(OH_AVMuxer *muxer, int32_t rotation)
47 {
48 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
49 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
50
51 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
52 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
53
54 std::shared_ptr<Meta> param = std::make_shared<Meta>();
55 param->Set<Tag::VIDEO_ROTATION>(static_cast<Plugins::VideoRotation>(rotation));
56 int32_t ret = object->muxer_->SetParameter(param);
57 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
58 "muxer_ SetRotation failed!");
59
60 return AV_ERR_OK;
61 }
62
OH_AVMuxer_AddTrack(OH_AVMuxer * muxer,int32_t * trackIndex,OH_AVFormat * trackFormat)63 OH_AVErrCode OH_AVMuxer_AddTrack(OH_AVMuxer *muxer, int32_t *trackIndex, OH_AVFormat *trackFormat)
64 {
65 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
66 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
67 CHECK_AND_RETURN_RET_LOG(trackIndex != nullptr, AV_ERR_INVALID_VAL, "input track index is nullptr!");
68 CHECK_AND_RETURN_RET_LOG(trackFormat != nullptr, AV_ERR_INVALID_VAL, "input track format is nullptr!");
69 CHECK_AND_RETURN_RET_LOG(trackFormat->magic_ == MFMagic::MFMAGIC_FORMAT, AV_ERR_INVALID_VAL,
70 "track 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 int32_t ret = object->muxer_->AddTrack(*trackIndex, trackFormat->format_.GetMeta());
76 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
77 "muxer_ AddTrack failed!");
78
79 return AV_ERR_OK;
80 }
81
OH_AVMuxer_Start(OH_AVMuxer * muxer)82 OH_AVErrCode OH_AVMuxer_Start(OH_AVMuxer *muxer)
83 {
84 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
85 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
86
87 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
88 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
89
90 int32_t ret = object->muxer_->Start();
91 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
92 "muxer_ Start failed!");
93
94 return AV_ERR_OK;
95 }
96
OH_AVMuxer_WriteSample(OH_AVMuxer * muxer,uint32_t trackIndex,OH_AVMemory * sample,OH_AVCodecBufferAttr info)97 OH_AVErrCode OH_AVMuxer_WriteSample(OH_AVMuxer *muxer, uint32_t trackIndex,
98 OH_AVMemory *sample, OH_AVCodecBufferAttr info)
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(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
103 CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_SHARED_MEMORY, AV_ERR_INVALID_VAL,
104 "sample magic error!");
105 CHECK_AND_RETURN_RET_LOG(sample->memory_ != nullptr && info.offset >= 0 && info.size >= 0 &&
106 sample->memory_->GetSize() >= (info.offset + info.size), AV_ERR_INVALID_VAL, "invalid memory");
107
108 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
109 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
110
111 std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(sample->memory_->GetBase() + info.offset,
112 sample->memory_->GetSize(), info.size);
113 buffer->pts_ = info.pts;
114 buffer->flag_ = info.flags;
115
116 int32_t ret = object->muxer_->WriteSample(trackIndex, buffer);
117 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
118 "muxer_ WriteSample failed!");
119
120 return AV_ERR_OK;
121 }
122
OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer * muxer,uint32_t trackIndex,const OH_AVBuffer * sample)123 OH_AVErrCode OH_AVMuxer_WriteSampleBuffer(OH_AVMuxer *muxer, uint32_t trackIndex,
124 const OH_AVBuffer *sample)
125 {
126 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
127 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
128 CHECK_AND_RETURN_RET_LOG(sample != nullptr, AV_ERR_INVALID_VAL, "input sample is nullptr!");
129 CHECK_AND_RETURN_RET_LOG(sample->magic_ == MFMagic::MFMAGIC_AVBUFFER, AV_ERR_INVALID_VAL,
130 "sample magic error!");
131
132 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
133 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
134
135 int32_t ret = object->muxer_->WriteSample(trackIndex, sample->buffer_);
136 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
137 "muxer_ WriteSampleBuffer failed!");
138
139 return AV_ERR_OK;
140 }
141
OH_AVMuxer_Stop(OH_AVMuxer * muxer)142 OH_AVErrCode OH_AVMuxer_Stop(OH_AVMuxer *muxer)
143 {
144 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
145 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
146
147 struct AVMuxerObject *object = reinterpret_cast<AVMuxerObject *>(muxer);
148 CHECK_AND_RETURN_RET_LOG(object->muxer_ != nullptr, AV_ERR_INVALID_VAL, "muxer_ is nullptr!");
149
150 int32_t ret = object->muxer_->Stop();
151 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCSErrorToOHAVErrCode(static_cast<AVCodecServiceErrCode>(ret)),
152 "muxer_ Stop failed!");
153
154 return AV_ERR_OK;
155 }
156
OH_AVMuxer_Destroy(OH_AVMuxer * muxer)157 OH_AVErrCode OH_AVMuxer_Destroy(OH_AVMuxer *muxer)
158 {
159 CHECK_AND_RETURN_RET_LOG(muxer != nullptr, AV_ERR_INVALID_VAL, "input muxer is nullptr!");
160 CHECK_AND_RETURN_RET_LOG(muxer->magic_ == AVMagic::AVCODEC_MAGIC_AVMUXER, AV_ERR_INVALID_VAL, "magic error!");
161
162 delete muxer;
163
164 return AV_ERR_OK;
165 }