1 /*
2 * Copyright (C) 2021 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_engine_gst_impl.h"
17 #include "avcodeclist_engine_gst_impl.h"
18 #include "media_errors.h"
19 #include "media_log.h"
20
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecEngineGstImpl"};
23 }
24
25 namespace OHOS {
26 namespace Media {
AVCodecEngineGstImpl()27 AVCodecEngineGstImpl::AVCodecEngineGstImpl()
28 {
29 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
30 }
31
~AVCodecEngineGstImpl()32 AVCodecEngineGstImpl::~AVCodecEngineGstImpl()
33 {
34 std::unique_lock<std::mutex> lock(mutex_);
35 if (ctrl_ != nullptr) {
36 (void)ctrl_->Release();
37 }
38 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
39 }
40
Init(AVCodecType type,bool isMimeType,const std::string & name)41 int32_t AVCodecEngineGstImpl::Init(AVCodecType type, bool isMimeType, const std::string &name)
42 {
43 MEDIA_LOGD("Init AVCodecGstEngine: type:%{public}d, %{public}d, name:%{public}s", type, isMimeType, name.c_str());
44 std::unique_lock<std::mutex> lock(mutex_);
45 type_ = type;
46
47 InnerCodecMimeType codecName = CODEC_MIME_TYPE_DEFAULT;
48 if (!isMimeType) {
49 std::string mimeType = FindMimeTypeByName(type, name);
50 CHECK_AND_RETURN_RET(MapCodecMime(mimeType, codecName) == MSERR_OK, MSERR_UNKNOWN);
51 } else {
52 CHECK_AND_RETURN_RET(MapCodecMime(name, codecName) == MSERR_OK, MSERR_UNKNOWN);
53 }
54
55 processor_ = AVCodecEngineFactory::CreateProcessor(type);
56
57 ctrl_ = std::make_unique<AVCodecEngineCtrl>();
58 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_NO_MEMORY);
59 ctrl_->SetObs(obs_);
60
61 if (isMimeType) {
62 CHECK_AND_RETURN_RET(HandleMimeType(type, name) == MSERR_OK, MSERR_UNKNOWN);
63 } else {
64 CHECK_AND_RETURN_RET(HandlePluginName(type, name) == MSERR_OK, MSERR_UNKNOWN);
65 }
66 CHECK_AND_RETURN_RET(processor_ != nullptr, MSERR_NO_MEMORY);
67 CHECK_AND_RETURN_RET(processor_->Init(codecName, useSoftWare_) == MSERR_OK, MSERR_UNKNOWN);
68
69 return MSERR_OK;
70 }
71
CheckSurfaceFormat(Format & format)72 void AVCodecEngineGstImpl::CheckSurfaceFormat(Format &format)
73 {
74 int32_t pixelFormat = 0;
75 if (useSoftWare_) {
76 return;
77 }
78 if (format.GetIntValue("pixel_format", pixelFormat) && pixelFormat == SURFACE_FORMAT) {
79 format.RemoveKey("pixel_format");
80 if (capData_.format.empty()) {
81 return;
82 }
83 format.PutIntValue("pixel_format", capData_.format[0]);
84 }
85 }
86
Configure(const Format & format)87 int32_t AVCodecEngineGstImpl::Configure(const Format &format)
88 {
89 MEDIA_LOGD("Enter Configure");
90 std::unique_lock<std::mutex> lock(mutex_);
91 format_ = format;
92 CheckSurfaceFormat(format_);
93
94 CHECK_AND_RETURN_RET(processor_ != nullptr, MSERR_INVALID_OPERATION);
95 CHECK_AND_RETURN_RET(processor_->DoProcess(format_) == MSERR_OK, MSERR_UNKNOWN);
96 CHECK_AND_RETURN_RET(ctrl_->SetConfigParameter(format) == MSERR_OK, MSERR_UNKNOWN);
97
98 MEDIA_LOGD("Configure success");
99
100 return MSERR_OK;
101 }
102
Prepare()103 int32_t AVCodecEngineGstImpl::Prepare()
104 {
105 MEDIA_LOGD("Enter Prepare");
106 std::unique_lock<std::mutex> lock(mutex_);
107
108 CHECK_AND_RETURN_RET(processor_ != nullptr, MSERR_UNKNOWN);
109 auto inputConfig = processor_->GetInputPortConfig();
110 CHECK_AND_RETURN_RET(inputConfig != nullptr, MSERR_NO_MEMORY);
111
112 auto outputConfig = processor_->GetOutputPortConfig();
113 CHECK_AND_RETURN_RET(outputConfig != nullptr, MSERR_NO_MEMORY);
114
115 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
116 return ctrl_->Prepare(inputConfig, outputConfig);
117 }
118
Start()119 int32_t AVCodecEngineGstImpl::Start()
120 {
121 MEDIA_LOGD("Enter Start");
122 std::unique_lock<std::mutex> lock(mutex_);
123
124 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
125 return ctrl_->Start();
126 }
127
Stop()128 int32_t AVCodecEngineGstImpl::Stop()
129 {
130 MEDIA_LOGD("Enter Stop");
131 std::unique_lock<std::mutex> lock(mutex_);
132
133 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
134 return ctrl_->Stop();
135 }
136
Flush()137 int32_t AVCodecEngineGstImpl::Flush()
138 {
139 MEDIA_LOGD("Enter Flush");
140 std::unique_lock<std::mutex> lock(mutex_);
141
142 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
143 return ctrl_->Flush();
144 }
145
Reset()146 int32_t AVCodecEngineGstImpl::Reset()
147 {
148 MEDIA_LOGD("Enter Reset");
149 std::unique_lock<std::mutex> lock(mutex_);
150 if (ctrl_ != nullptr) {
151 (void)ctrl_->Release();
152 ctrl_ = nullptr;
153 }
154 ctrl_ = std::make_unique<AVCodecEngineCtrl>();
155 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_NO_MEMORY);
156 CHECK_AND_RETURN_RET(ctrl_->Init(type_, useSoftWare_, pluginName_) == MSERR_OK, MSERR_UNKNOWN);
157 ctrl_->SetObs(obs_);
158
159 MEDIA_LOGD("Reset success");
160 return MSERR_OK;
161 }
162
NotifyEos()163 int32_t AVCodecEngineGstImpl::NotifyEos()
164 {
165 MEDIA_LOGD("Enter NotifyEos");
166 std::unique_lock<std::mutex> lock(mutex_);
167
168 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
169 return ctrl_->NotifyEos();
170 }
171
CreateInputSurface()172 sptr<Surface> AVCodecEngineGstImpl::CreateInputSurface()
173 {
174 MEDIA_LOGD("Enter CreateInputSurface");
175 std::unique_lock<std::mutex> lock(mutex_);
176
177 CHECK_AND_RETURN_RET(processor_ != nullptr, nullptr);
178 auto inputConfig = processor_->GetInputPortConfig();
179 CHECK_AND_RETURN_RET(inputConfig != nullptr, nullptr);
180
181 CHECK_AND_RETURN_RET(ctrl_ != nullptr, nullptr);
182 return ctrl_->CreateInputSurface(inputConfig);
183 }
184
SetOutputSurface(const sptr<Surface> & surface)185 int32_t AVCodecEngineGstImpl::SetOutputSurface(const sptr<Surface> &surface)
186 {
187 MEDIA_LOGD("Enter SetOutputSurface");
188 std::unique_lock<std::mutex> lock(mutex_);
189
190 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_NO_MEMORY);
191 return ctrl_->SetOutputSurface(surface);
192 }
193
GetInputBuffer(uint32_t index)194 std::shared_ptr<AVSharedMemory> AVCodecEngineGstImpl::GetInputBuffer(uint32_t index)
195 {
196 std::unique_lock<std::mutex> lock(mutex_);
197
198 CHECK_AND_RETURN_RET(ctrl_ != nullptr, nullptr);
199 return ctrl_->GetInputBuffer(index);
200 }
201
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)202 int32_t AVCodecEngineGstImpl::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
203 {
204 std::unique_lock<std::mutex> lock(mutex_);
205
206 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_NO_MEMORY);
207 return ctrl_->QueueInputBuffer(index, info, flag);
208 }
209
GetOutputBuffer(uint32_t index)210 std::shared_ptr<AVSharedMemory> AVCodecEngineGstImpl::GetOutputBuffer(uint32_t index)
211 {
212 std::unique_lock<std::mutex> lock(mutex_);
213
214 CHECK_AND_RETURN_RET(ctrl_ != nullptr, nullptr);
215 return ctrl_->GetOutputBuffer(index);
216 }
217
GetOutputFormat(Format & format)218 int32_t AVCodecEngineGstImpl::GetOutputFormat(Format &format)
219 {
220 format_.PutStringValue("plugin_name", pluginName_);
221 format = format_;
222 return MSERR_OK;
223 }
224
ReleaseOutputBuffer(uint32_t index,bool render)225 int32_t AVCodecEngineGstImpl::ReleaseOutputBuffer(uint32_t index, bool render)
226 {
227 std::unique_lock<std::mutex> lock(mutex_);
228
229 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_NO_MEMORY);
230 return ctrl_->ReleaseOutputBuffer(index, render);
231 }
232
SetParameter(const Format & format)233 int32_t AVCodecEngineGstImpl::SetParameter(const Format &format)
234 {
235 MEDIA_LOGD("Enter SetParameter");
236 std::unique_lock<std::mutex> lock(mutex_);
237
238 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_NO_MEMORY);
239 return ctrl_->SetParameter(format);
240 }
241
SetObs(const std::weak_ptr<IAVCodecEngineObs> & obs)242 int32_t AVCodecEngineGstImpl::SetObs(const std::weak_ptr<IAVCodecEngineObs> &obs)
243 {
244 std::unique_lock<std::mutex> lock(mutex_);
245 obs_ = obs;
246 return MSERR_OK;
247 }
248
FindMimeTypeByName(AVCodecType type,const std::string & name)249 std::string AVCodecEngineGstImpl::FindMimeTypeByName(AVCodecType type, const std::string &name)
250 {
251 (void)type;
252 std::string mimeType = "error";
253 auto codecList = std::make_unique<AVCodecListEngineGstImpl>();
254 CHECK_AND_RETURN_RET(codecList != nullptr, mimeType);
255
256 std::vector<CapabilityData> data = codecList->GetCodecCapabilityInfos();
257 bool invalid = true;
258
259 for (auto it = data.begin(); it != data.end(); it++) {
260 if ((*it).codecName == name) {
261 mimeType = (*it).mimeType;
262 invalid = false;
263 break;
264 }
265 }
266
267 if (invalid) {
268 MEDIA_LOGW("invalid avcodec mimetype name:%{public}s", name.c_str());
269 }
270
271 return mimeType;
272 }
273
HandleMimeType(AVCodecType type,const std::string & name)274 int32_t AVCodecEngineGstImpl::HandleMimeType(AVCodecType type, const std::string &name)
275 {
276 int32_t ret = MSERR_OK;
277 auto codecList = std::make_unique<AVCodecListEngineGstImpl>();
278 CHECK_AND_RETURN_RET(codecList != nullptr, MSERR_NO_MEMORY);
279
280 std::string pluginName = "";
281 Format format;
282 format.PutStringValue("codec_mime", name);
283 switch (type) {
284 case AVCODEC_TYPE_VIDEO_ENCODER:
285 pluginName = codecList->FindVideoEncoder(format);
286 break;
287 case AVCODEC_TYPE_VIDEO_DECODER:
288 pluginName = codecList->FindVideoDecoder(format);
289 break;
290 case AVCODEC_TYPE_AUDIO_ENCODER:
291 pluginName = codecList->FindAudioEncoder(format);
292 break;
293 case AVCODEC_TYPE_AUDIO_DECODER:
294 pluginName = codecList->FindAudioDecoder(format);
295 break;
296 default:
297 ret = MSERR_INVALID_VAL;
298 MEDIA_LOGE("Unknown type");
299 break;
300 }
301 CHECK_AND_RETURN_RET(ret == MSERR_OK, MSERR_UNKNOWN);
302 MEDIA_LOGD("Found plugin name:%{public}s", pluginName.c_str());
303
304 (void)QueryIsSoftPlugin(pluginName, useSoftWare_);
305 pluginName_ = pluginName;
306
307 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
308 return ctrl_->Init(type, useSoftWare_, pluginName);
309 }
310
HandlePluginName(AVCodecType type,const std::string & name)311 int32_t AVCodecEngineGstImpl::HandlePluginName(AVCodecType type, const std::string &name)
312 {
313 bool isSoftware = true;
314 (void)QueryIsSoftPlugin(name, isSoftware);
315
316 useSoftWare_ = isSoftware;
317 pluginName_ = name;
318
319 CHECK_AND_RETURN_RET(ctrl_ != nullptr, MSERR_UNKNOWN);
320 return ctrl_->Init(type, isSoftware, name);
321 }
322
QueryIsSoftPlugin(const std::string & name,bool & isSoftware)323 int32_t AVCodecEngineGstImpl::QueryIsSoftPlugin(const std::string &name, bool &isSoftware)
324 {
325 auto codecList = std::make_unique<AVCodecListEngineGstImpl>();
326 CHECK_AND_RETURN_RET(codecList != nullptr, MSERR_NO_MEMORY);
327
328 std::vector<CapabilityData> data = codecList->GetCodecCapabilityInfos();
329 bool pluginExist = false;
330
331 for (auto it = data.begin(); it != data.end(); it++) {
332 if ((*it).codecName == name) {
333 isSoftware = !(*it).isVendor;
334 pluginExist = true;
335 capData_ = *it;
336 break;
337 }
338 }
339 CHECK_AND_RETURN_RET(pluginExist == true, MSERR_INVALID_VAL);
340
341 return MSERR_OK;
342 }
343 } // namespace Media
344 } // namespace OHOS
345