• 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     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