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