• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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