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 "avcodec_video_encoder_impl.h"
17 #include "avcodec_errors.h"
18 #include "avcodec_log.h"
19 #include "avcodec_trace.h"
20 #include "i_avcodec_service.h"
21 
22 namespace {
23 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "AVCodecVideoEncoderImpl"};
24 }
25 
26 namespace OHOS {
27 namespace MediaAVCodec {
CreateByMime(const std::string & mime)28 std::shared_ptr<AVCodecVideoEncoder> VideoEncoderFactory::CreateByMime(const std::string &mime)
29 {
30     std::shared_ptr<AVCodecVideoEncoder> impl = nullptr;
31     Format format;
32 
33     int32_t ret = CreateByMime(mime, format, impl);
34     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK || impl != nullptr, nullptr,
35                              "AVCodec video encoder impl init failed, %{public}s",
36                              AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
37 
38     return impl;
39 }
40 
CreateByName(const std::string & name)41 std::shared_ptr<AVCodecVideoEncoder> VideoEncoderFactory::CreateByName(const std::string &name)
42 {
43     std::shared_ptr<AVCodecVideoEncoder> impl = nullptr;
44     Format format;
45 
46     int32_t ret = CreateByName(name, format, impl);
47     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK || impl != nullptr, nullptr,
48                              "AVCodec video encoder impl init failed, %{public}s",
49                              AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
50 
51     return impl;
52 }
53 
CreateByMime(const std::string & mime,Format & format,std::shared_ptr<AVCodecVideoEncoder> & encoder)54 int32_t VideoEncoderFactory::CreateByMime(const std::string &mime, Format &format,
55                                           std::shared_ptr<AVCodecVideoEncoder> &encoder)
56 {
57     auto impl = std::make_shared<AVCodecVideoEncoderImpl>();
58 
59     int32_t ret = impl->Init(AVCODEC_TYPE_VIDEO_ENCODER, true, mime, format);
60     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "AVCodec video encoder impl init failed, %{public}s",
61                              AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
62 
63     encoder = impl;
64     return AVCS_ERR_OK;
65 }
66 
CreateByName(const std::string & name,Format & format,std::shared_ptr<AVCodecVideoEncoder> & encoder)67 int32_t VideoEncoderFactory::CreateByName(const std::string &name, Format &format,
68                                           std::shared_ptr<AVCodecVideoEncoder> &encoder)
69 {
70     auto impl = std::make_shared<AVCodecVideoEncoderImpl>();
71 
72     int32_t ret = impl->Init(AVCODEC_TYPE_VIDEO_ENCODER, false, name, format);
73     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "AVCodec video encoder impl init failed, %{public}s",
74                              AVCSErrorToString(static_cast<AVCodecServiceErrCode>(ret)).c_str());
75 
76     encoder = impl;
77     return AVCS_ERR_OK;
78 }
79 
Init(AVCodecType type,bool isMimeType,const std::string & name,Format & format)80 int32_t AVCodecVideoEncoderImpl::Init(AVCodecType type, bool isMimeType, const std::string &name, Format &format)
81 {
82     AVCODEC_SYNC_TRACE;
83 
84     int32_t ret = AVCodecServiceFactory::GetInstance().CreateCodecService(codecClient_);
85     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, ret, "Codec client create failed");
86 
87     return codecClient_->Init(type, isMimeType, name, *format.GetMeta());
88 }
89 
AVCodecVideoEncoderImpl()90 AVCodecVideoEncoderImpl::AVCodecVideoEncoderImpl()
91 {
92     AVCODEC_LOGD("AVCodecVideoEncoderImpl:0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
93 }
94 
~AVCodecVideoEncoderImpl()95 AVCodecVideoEncoderImpl::~AVCodecVideoEncoderImpl()
96 {
97     if (codecClient_ != nullptr) {
98         (void)AVCodecServiceFactory::GetInstance().DestroyCodecService(codecClient_);
99         codecClient_ = nullptr;
100     }
101     AVCODEC_LOGD("AVCodecVideoEncoderImpl:0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
102 }
103 
Configure(const Format & format)104 int32_t AVCodecVideoEncoderImpl::Configure(const Format &format)
105 {
106     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
107 
108     AVCODEC_SYNC_TRACE;
109     return codecClient_->Configure(format);
110 }
111 
SetCustomBuffer(std::shared_ptr<AVBuffer> buffer)112 int32_t AVCodecVideoEncoderImpl::SetCustomBuffer(std::shared_ptr<AVBuffer> buffer)
113 {
114     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
115 
116     AVCODEC_SYNC_TRACE;
117     return codecClient_->SetCustomBuffer(buffer);
118 }
119 
Prepare()120 int32_t AVCodecVideoEncoderImpl::Prepare()
121 {
122     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
123 
124     AVCODEC_SYNC_TRACE;
125     return AVCS_ERR_OK;
126 }
127 
Start()128 int32_t AVCodecVideoEncoderImpl::Start()
129 {
130     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
131 
132     AVCODEC_SYNC_TRACE;
133     return codecClient_->Start();
134 }
135 
Stop()136 int32_t AVCodecVideoEncoderImpl::Stop()
137 {
138     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
139 
140     AVCODEC_SYNC_TRACE;
141     return codecClient_->Stop();
142 }
143 
Flush()144 int32_t AVCodecVideoEncoderImpl::Flush()
145 {
146     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
147 
148     AVCODEC_SYNC_TRACE;
149     return codecClient_->Flush();
150 }
151 
NotifyEos()152 int32_t AVCodecVideoEncoderImpl::NotifyEos()
153 {
154     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
155 
156     AVCODEC_SYNC_TRACE;
157     return codecClient_->NotifyEos();
158 }
159 
Reset()160 int32_t AVCodecVideoEncoderImpl::Reset()
161 {
162     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
163 
164     AVCODEC_SYNC_TRACE;
165     return codecClient_->Reset();
166 }
167 
Release()168 int32_t AVCodecVideoEncoderImpl::Release()
169 {
170     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
171 
172     AVCODEC_SYNC_TRACE;
173     return codecClient_->Release();
174 }
175 
CreateInputSurface()176 sptr<Surface> AVCodecVideoEncoderImpl::CreateInputSurface()
177 {
178     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, nullptr, "Codec service is nullptr");
179 
180     AVCODEC_SYNC_TRACE;
181     return codecClient_->CreateInputSurface();
182 }
183 
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)184 int32_t AVCodecVideoEncoderImpl::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
185 {
186     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
187 
188     AVCODEC_SYNC_TRACE;
189     return codecClient_->QueueInputBuffer(index, info, flag);
190 }
191 
QueueInputBuffer(uint32_t index)192 int32_t AVCodecVideoEncoderImpl::QueueInputBuffer(uint32_t index)
193 {
194     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
195 
196     AVCODEC_SYNC_TRACE;
197     return codecClient_->QueueInputBuffer(index);
198 }
199 
QueueInputParameter(uint32_t index)200 int32_t AVCodecVideoEncoderImpl::QueueInputParameter(uint32_t index)
201 {
202     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
203 
204     AVCODEC_SYNC_TRACE;
205     return codecClient_->QueueInputParameter(index);
206 }
207 
GetOutputFormat(Format & format)208 int32_t AVCodecVideoEncoderImpl::GetOutputFormat(Format &format)
209 {
210     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
211 
212     AVCODEC_SYNC_TRACE;
213     return codecClient_->GetOutputFormat(format);
214 }
215 
ReleaseOutputBuffer(uint32_t index)216 int32_t AVCodecVideoEncoderImpl::ReleaseOutputBuffer(uint32_t index)
217 {
218     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
219 
220     AVCODEC_SYNC_TRACE;
221     return codecClient_->ReleaseOutputBuffer(index);
222 }
223 
SetParameter(const Format & format)224 int32_t AVCodecVideoEncoderImpl::SetParameter(const Format &format)
225 {
226     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
227 
228     AVCODEC_SYNC_TRACE;
229     return codecClient_->SetParameter(format);
230 }
231 
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)232 int32_t AVCodecVideoEncoderImpl::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
233 {
234     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
235     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Callback is nullptr");
236     AVCODEC_SYNC_TRACE;
237     return codecClient_->SetCallback(callback);
238 }
239 
SetCallback(const std::shared_ptr<MediaCodecCallback> & callback)240 int32_t AVCodecVideoEncoderImpl::SetCallback(const std::shared_ptr<MediaCodecCallback> &callback)
241 {
242     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "service died");
243     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "callback is nullptr");
244 
245     AVCODEC_SYNC_TRACE;
246     return codecClient_->SetCallback(callback);
247 }
248 
SetCallback(const std::shared_ptr<MediaCodecParameterCallback> & callback)249 int32_t AVCodecVideoEncoderImpl::SetCallback(const std::shared_ptr<MediaCodecParameterCallback> &callback)
250 {
251     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "service died");
252     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "callback is nullptr");
253 
254     AVCODEC_SYNC_TRACE;
255     return codecClient_->SetCallback(callback);
256 }
257 
SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> & callback)258 int32_t AVCodecVideoEncoderImpl::SetCallback(const std::shared_ptr<MediaCodecParameterWithAttrCallback> &callback)
259 {
260     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "service died");
261     CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "callback is nullptr");
262 
263     AVCODEC_SYNC_TRACE;
264     return codecClient_->SetCallback(callback);
265 }
266 
GetInputFormat(Format & format)267 int32_t AVCodecVideoEncoderImpl::GetInputFormat(Format &format)
268 {
269     CHECK_AND_RETURN_RET_LOG(codecClient_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Codec service is nullptr");
270 
271     AVCODEC_SYNC_TRACE;
272     return codecClient_->GetInputFormat(format);
273 }
274 } // namespace MediaAVCodec
275 } // namespace OHOS
276