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_server.h"
17 #include "media_log.h"
18 #include "media_errors.h"
19 #include "engine_factory_repo.h"
20
21 namespace {
22 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "AVCodecServer"};
23 }
24
25 namespace OHOS {
26 namespace Media {
Create()27 std::shared_ptr<IAVCodecService> AVCodecServer::Create()
28 {
29 std::shared_ptr<AVCodecServer> server = std::make_shared<AVCodecServer>();
30 int32_t ret = server->Init();
31 if (ret != MSERR_OK) {
32 MEDIA_LOGE("failed to init AVCodecServer");
33 return nullptr;
34 }
35 return server;
36 }
37
AVCodecServer()38 AVCodecServer::AVCodecServer()
39 {
40 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
41 }
42
~AVCodecServer()43 AVCodecServer::~AVCodecServer()
44 {
45 MEDIA_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
46 }
47
Init()48 int32_t AVCodecServer::Init()
49 {
50 auto engineFactory = EngineFactoryRepo::Instance().GetEngineFactory(IEngineFactory::Scene::SCENE_AVCODEC);
51 CHECK_AND_RETURN_RET_LOG(engineFactory != nullptr, MSERR_CREATE_REC_ENGINE_FAILED, "failed to get factory");
52 codecEngine_ = engineFactory->CreateAVCodecEngine();
53 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_CREATE_REC_ENGINE_FAILED,
54 "Failed to create codec engine");
55 status_ = AVCODEC_INITIALIZED;
56 return MSERR_OK;
57 }
58
InitParameter(AVCodecType type,bool isMimeType,const std::string & name)59 int32_t AVCodecServer::InitParameter(AVCodecType type, bool isMimeType, const std::string &name)
60 {
61 std::lock_guard<std::mutex> lock(mutex_);
62 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
63 int32_t ret = codecEngine_->Init(type, isMimeType, name);
64 return ret;
65 }
66
Configure(const Format & format)67 int32_t AVCodecServer::Configure(const Format &format)
68 {
69 std::lock_guard<std::mutex> lock(mutex_);
70 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_INITIALIZED, MSERR_INVALID_OPERATION, "invalid state");
71 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
72 int32_t ret = codecEngine_->Configure(format);
73 status_ = (ret == MSERR_OK ? AVCODEC_CONFIGURED : AVCODEC_ERROR);
74 return ret;
75 }
76
Prepare()77 int32_t AVCodecServer::Prepare()
78 {
79 std::lock_guard<std::mutex> lock(mutex_);
80 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_CONFIGURED, MSERR_INVALID_OPERATION, "invalid state");
81 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
82 int32_t ret = codecEngine_->Prepare();
83 status_ = (ret == MSERR_OK ? AVCODEC_PREPARED : AVCODEC_ERROR);
84 return ret;
85 }
86
Start()87 int32_t AVCodecServer::Start()
88 {
89 std::lock_guard<std::mutex> lock(mutex_);
90 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_PREPARED, MSERR_INVALID_OPERATION, "invalid state");
91 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
92 int32_t ret = codecEngine_->Start();
93 status_ = (ret == MSERR_OK ? AVCODEC_RUNNING : AVCODEC_ERROR);
94 return ret;
95 }
96
Stop()97 int32_t AVCodecServer::Stop()
98 {
99 std::lock_guard<std::mutex> lock(mutex_);
100 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_RUNNING || status_ == AVCODEC_END_OF_STREAM,
101 MSERR_INVALID_OPERATION, "invalid state");
102 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
103 int32_t ret = codecEngine_->Stop();
104 status_ = (ret == MSERR_OK ? AVCODEC_PREPARED : AVCODEC_ERROR);
105 return ret;
106 }
107
Flush()108 int32_t AVCodecServer::Flush()
109 {
110 std::lock_guard<std::mutex> lock(mutex_);
111 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_RUNNING || status_ == AVCODEC_END_OF_STREAM,
112 MSERR_INVALID_OPERATION, "invalid state");
113 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
114 int32_t ret = codecEngine_->Flush();
115 status_ = (ret == MSERR_OK ? AVCODEC_RUNNING : AVCODEC_ERROR);
116 return ret;
117 }
118
Reset()119 int32_t AVCodecServer::Reset()
120 {
121 std::lock_guard<std::mutex> lock(mutex_);
122 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
123 int32_t ret = codecEngine_->Reset();
124 status_ = (ret == MSERR_OK ? AVCODEC_INITIALIZED : AVCODEC_ERROR);
125 return ret;
126 }
127
Release()128 int32_t AVCodecServer::Release()
129 {
130 std::lock_guard<std::mutex> lock(mutex_);
131 codecEngine_ = nullptr;
132 return MSERR_OK;
133 }
134
CreateInputSurface()135 sptr<Surface> AVCodecServer::CreateInputSurface()
136 {
137 std::lock_guard<std::mutex> lock(mutex_);
138 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_CONFIGURED, nullptr, "invalid state");
139 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, nullptr, "engine is nullptr");
140 return codecEngine_->CreateInputSurface();
141 }
142
SetOutputSurface(sptr<Surface> surface)143 int32_t AVCodecServer::SetOutputSurface(sptr<Surface> surface)
144 {
145 std::lock_guard<std::mutex> lock(mutex_);
146 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_CONFIGURED, MSERR_INVALID_OPERATION, "invalid state");
147 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
148 return codecEngine_->SetOutputSurface(surface);
149 }
150
GetInputBuffer(uint32_t index)151 std::shared_ptr<AVSharedMemory> AVCodecServer::GetInputBuffer(uint32_t index)
152 {
153 std::lock_guard<std::mutex> lock(mutex_);
154 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_RUNNING, nullptr, "invalid state");
155 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, nullptr, "engine is nullptr");
156 return codecEngine_->GetInputBuffer(index);
157 }
158
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)159 int32_t AVCodecServer::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
160 {
161 std::lock_guard<std::mutex> lock(mutex_);
162 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_RUNNING, MSERR_INVALID_OPERATION, "invalid state");
163 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
164 int32_t ret = codecEngine_->QueueInputBuffer(index, info, flag);
165 if (flag & AVCODEC_BUFFER_FLAG_EOS) {
166 if (ret == MSERR_OK) {
167 status_ = AVCODEC_END_OF_STREAM;
168 MEDIA_LOGI("EOS state");
169 }
170 }
171 return ret;
172 }
173
GetOutputBuffer(uint32_t index)174 std::shared_ptr<AVSharedMemory> AVCodecServer::GetOutputBuffer(uint32_t index)
175 {
176 std::lock_guard<std::mutex> lock(mutex_);
177 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_RUNNING || status_ == AVCODEC_END_OF_STREAM,
178 nullptr, "invalid state");
179 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, nullptr, "engine is nullptr");
180 return codecEngine_->GetOutputBuffer(index);
181 }
182
GetOutputFormat(Format & format)183 int32_t AVCodecServer::GetOutputFormat(Format &format)
184 {
185 std::lock_guard<std::mutex> lock(mutex_);
186 CHECK_AND_RETURN_RET_LOG(status_ != AVCODEC_UNINITIALIZED, MSERR_INVALID_OPERATION, "invalid state");
187 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
188 return codecEngine_->GetOutputFormat(format);
189 }
190
GetAudioCaps()191 std::shared_ptr<AudioCaps> AVCodecServer::GetAudioCaps()
192 {
193 std::lock_guard<std::mutex> lock(mutex_);
194 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, nullptr, "engine is nullptr");
195 return codecEngine_->GetAudioCaps();
196 }
GetVideoCaps()197 std::shared_ptr<VideoCaps> AVCodecServer::GetVideoCaps()
198 {
199 std::lock_guard<std::mutex> lock(mutex_);
200 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, nullptr, "engine is nullptr");
201 return codecEngine_->GetVideoCaps();
202 }
203
ReleaseOutputBuffer(uint32_t index,bool render)204 int32_t AVCodecServer::ReleaseOutputBuffer(uint32_t index, bool render)
205 {
206 std::lock_guard<std::mutex> lock(mutex_);
207 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_RUNNING || status_ == AVCODEC_END_OF_STREAM,
208 MSERR_INVALID_OPERATION, "invalid state");
209 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
210 return codecEngine_->ReleaseOutputBuffer(index, render);
211 }
212
SetParameter(const Format & format)213 int32_t AVCodecServer::SetParameter(const Format &format)
214 {
215 std::lock_guard<std::mutex> lock(mutex_);
216 CHECK_AND_RETURN_RET_LOG(status_ != AVCODEC_INITIALIZED && status_ != AVCODEC_CONFIGURED,
217 MSERR_INVALID_OPERATION, "invalid state");
218 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
219 return codecEngine_->SetParameter(format);
220 }
221
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)222 int32_t AVCodecServer::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
223 {
224 std::lock_guard<std::mutex> lock(mutex_);
225 CHECK_AND_RETURN_RET_LOG(status_ == AVCODEC_INITIALIZED, MSERR_INVALID_OPERATION, "invalid state");
226 {
227 std::lock_guard<std::mutex> cbLock(cbMutex_);
228 codecCb_ = callback;
229 }
230 CHECK_AND_RETURN_RET_LOG(codecEngine_ != nullptr, MSERR_NO_MEMORY, "engine is nullptr");
231 std::shared_ptr<IAVCodecEngineObs> obs = shared_from_this();
232 (void)codecEngine_->SetObs(obs);
233 return MSERR_OK;
234 }
235
OnError(int32_t errorType,int32_t errorCode)236 void AVCodecServer::OnError(int32_t errorType, int32_t errorCode)
237 {
238 std::lock_guard<std::mutex> lock(cbMutex_);
239 if (codecCb_ == nullptr) {
240 return;
241 }
242 codecCb_->OnError(static_cast<AVCodecErrorType>(errorType), errorCode);
243 }
244
OnOutputFormatChanged(const Format & format)245 void AVCodecServer::OnOutputFormatChanged(const Format &format)
246 {
247 std::lock_guard<std::mutex> lock(cbMutex_);
248 if (codecCb_ == nullptr) {
249 return;
250 }
251 codecCb_->OnOutputFormatChanged(format);
252 }
253
OnInputBufferAvailable(uint32_t index)254 void AVCodecServer::OnInputBufferAvailable(uint32_t index)
255 {
256 std::lock_guard<std::mutex> lock(cbMutex_);
257 if (codecCb_ == nullptr) {
258 return;
259 }
260 codecCb_->OnInputBufferAvailable(index);
261 }
262
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)263 void AVCodecServer::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
264 {
265 std::lock_guard<std::mutex> lock(cbMutex_);
266 if (codecCb_ == nullptr) {
267 return;
268 }
269 codecCb_->OnOutputBufferAvailable(index, info, flag);
270 }
271 } // namespace Media
272 } // namespace OHOS
273