1 /*
2 * Copyright (C) 2023 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 "codec_server.h"
17 #include <map>
18 #include <vector>
19 #include <malloc.h>
20 #include "avcodec_dfx.h"
21 #include "avcodec_errors.h"
22 #include "avcodec_log.h"
23 #include "codec_factory.h"
24 #include "avcodec_dump_utils.h"
25 #include "media_description.h"
26 #include "surface_type.h"
27 #include "avcodec_codec_name.h"
28
29 namespace {
30 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "CodecServer"};
31 constexpr uint32_t DUMP_CODEC_INFO_INDEX = 0x01010000;
32 constexpr uint32_t DUMP_STATUS_INDEX = 0x01010100;
33 constexpr uint32_t DUMP_LAST_ERROR_INDEX = 0x01010200;
34 constexpr uint32_t DUMP_OFFSET_8 = 8;
35
36 const std::map<OHOS::MediaAVCodec::CodecServer::CodecStatus, std::string> CODEC_STATE_MAP = {
37 {OHOS::MediaAVCodec::CodecServer::UNINITIALIZED, "uninitialized"},
38 {OHOS::MediaAVCodec::CodecServer::INITIALIZED, "initialized"},
39 {OHOS::MediaAVCodec::CodecServer::CONFIGURED, "configured"},
40 {OHOS::MediaAVCodec::CodecServer::RUNNING, "running"},
41 {OHOS::MediaAVCodec::CodecServer::FLUSHED, "flushed"},
42 {OHOS::MediaAVCodec::CodecServer::END_OF_STREAM, "end of stream"},
43 {OHOS::MediaAVCodec::CodecServer::ERROR, "error"},
44 };
45
46 const std::vector<std::pair<std::string_view, const std::string>> DEFAULT_DUMP_TABLE = {
47 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_NAME, "Codec_Name" },
48 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE, "Bit_Rate" },
49 };
50
51 const std::vector<std::pair<std::string_view, const std::string>> VIDEO_DUMP_TABLE = {
52 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_NAME, "Codec_Name" },
53 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, "Width" },
54 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, "Height" },
55 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_FRAME_RATE, "Frame_Rate" },
56 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE, "Bit_Rate" },
57 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_PIXEL_FORMAT, "Pixel_Format" },
58 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_SCALE_TYPE, "Scale_Type" },
59 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_ROTATION_ANGLE, "Rotation_Angle" },
60 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE, "Max_Input_Size" },
61 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_INPUT_BUFFER_COUNT, "Max_Input_Buffer_Count" },
62 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_OUTPUT_BUFFER_COUNT, "Max_Output_Buffer_Count" },
63 };
64
65 const std::vector<std::pair<std::string_view, const std::string>> AUDIO_DUMP_TABLE = {
66 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_NAME, "Codec_Name" },
67 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, "Channel_Count" },
68 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_BITRATE, "Bit_Rate" },
69 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_SAMPLE_RATE, "Sample_Rate" },
70 { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_MAX_INPUT_SIZE, "Max_Input_Size" },
71 };
72
73 const std::map<OHOS::MediaAVCodec::CodecServer::CodecType,
74 std::vector<std::pair<std::string_view, const std::string>>> CODEC_DUMP_TABLE = {
75 { OHOS::MediaAVCodec::CodecServer::CodecType::CODEC_TYPE_DEFAULT, DEFAULT_DUMP_TABLE },
76 { OHOS::MediaAVCodec::CodecServer::CodecType::CODEC_TYPE_VIDEO, VIDEO_DUMP_TABLE },
77 { OHOS::MediaAVCodec::CodecServer::CodecType::CODEC_TYPE_AUDIO, AUDIO_DUMP_TABLE },
78 };
79
80 const std::map<int32_t, const std::string> PIXEL_FORMAT_STRING_MAP = {
81 { OHOS::MediaAVCodec::VideoPixelFormat::YUV420P, "YUV420P" },
82 { OHOS::MediaAVCodec::VideoPixelFormat::YUVI420, "YUVI420" },
83 { OHOS::MediaAVCodec::VideoPixelFormat::NV12, "NV12" },
84 { OHOS::MediaAVCodec::VideoPixelFormat::NV21, "NV21" },
85 { OHOS::MediaAVCodec::VideoPixelFormat::SURFACE_FORMAT, "SURFACE_FORMAT" },
86 { OHOS::MediaAVCodec::VideoPixelFormat::RGBA, "RGBA" },
87 { OHOS::MediaAVCodec::VideoPixelFormat::UNKNOWN_FORMAT, "UNKNOWN_FORMAT" },
88 };
89
90 const std::map<int32_t, const std::string> SCALE_TYPE_STRING_MAP = {
91 { OHOS::ScalingMode::SCALING_MODE_FREEZE, "Freeze" },
92 { OHOS::ScalingMode::SCALING_MODE_SCALE_TO_WINDOW, "Scale_to_window" },
93 { OHOS::ScalingMode::SCALING_MODE_SCALE_CROP, "Scale_crop" },
94 { OHOS::ScalingMode::SCALING_MODE_NO_SCALE_CROP, "No_scale_crop" },
95 };
96 }
97
98 namespace OHOS {
99 namespace MediaAVCodec {
Create()100 std::shared_ptr<ICodecService> CodecServer::Create()
101 {
102 std::shared_ptr<CodecServer> server = std::make_shared<CodecServer>();
103
104 int32_t ret = server->InitServer();
105 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Codec server init failed!");
106 return server;
107 }
108
CodecServer()109 CodecServer::CodecServer()
110 {
111 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
112 }
113
~CodecServer()114 CodecServer::~CodecServer()
115 {
116 std::unique_ptr<std::thread> thread = std::make_unique<std::thread>(&CodecServer::ExitProcessor, this);
117 if (thread->joinable()) {
118 thread->join();
119 }
120 (void)mallopt(M_FLUSH_THREAD_CACHE, 0);
121 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
122 }
123
ExitProcessor()124 void CodecServer::ExitProcessor()
125 {
126 codecBase_ = nullptr;
127 }
128
InitServer()129 int32_t CodecServer::InitServer()
130 {
131 return AVCS_ERR_OK;
132 }
133
Init(AVCodecType type,bool isMimeType,const std::string & name)134 int32_t CodecServer::Init(AVCodecType type, bool isMimeType, const std::string &name)
135 {
136 std::lock_guard<std::shared_mutex> lock(mutex_);
137 (void)mallopt(M_SET_THREAD_CACHE, M_THREAD_CACHE_DISABLE);
138 (void)mallopt(M_DELAYED_FREE, M_DELAYED_FREE_DISABLE);
139 std::string codecMimeName = name;
140 if (isMimeType) {
141 bool isEncoder = (type == AVCODEC_TYPE_VIDEO_ENCODER) || (type == AVCODEC_TYPE_AUDIO_ENCODER);
142 codecBase_ = CodecFactory::Instance().CreateCodecByMime(isEncoder, codecMimeName);
143 } else {
144 if (name.compare(AVCodecCodecName::AUDIO_DECODER_API9_AAC_NAME) == 0) {
145 codecMimeName = AVCodecCodecName::AUDIO_DECODER_AAC_NAME;
146 } else if (name.compare(AVCodecCodecName::AUDIO_ENCODER_API9_AAC_NAME) == 0) {
147 codecMimeName = AVCodecCodecName::AUDIO_ENCODER_AAC_NAME;
148 }
149 if (codecMimeName.find("Audio") != codecMimeName.npos) {
150 if ((codecMimeName.find("Decoder") != codecMimeName.npos && type != AVCODEC_TYPE_AUDIO_DECODER) ||
151 (codecMimeName.find("Encoder") != codecMimeName.npos && type != AVCODEC_TYPE_AUDIO_ENCODER)) {
152 AVCODEC_LOGE("Codec name invalid");
153 return AVCS_ERR_INVALID_OPERATION;
154 }
155 }
156 codecBase_ = CodecFactory::Instance().CreateCodecByName(codecMimeName);
157 }
158 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "CodecBase is nullptr");
159 codecName_ = codecMimeName;
160 std::shared_ptr<AVCodecCallback> callback = std::make_shared<CodecBaseCallback>(shared_from_this());
161 int32_t ret = codecBase_->SetCallback(callback);
162 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, AVCS_ERR_INVALID_OPERATION, "CodecBase SetCallback failed");
163 status_ = INITIALIZED;
164 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
165 return AVCS_ERR_OK;
166 }
167
Configure(const Format & format)168 int32_t CodecServer::Configure(const Format &format)
169 {
170 std::lock_guard<std::shared_mutex> lock(mutex_);
171 CHECK_AND_RETURN_RET_LOG(status_ == INITIALIZED, AVCS_ERR_INVALID_STATE, "In invalid state");
172 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
173 config_ = format;
174 int32_t ret = codecBase_->Configure(format);
175
176 status_ = (ret == AVCS_ERR_OK ? CONFIGURED : ERROR);
177 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
178 return ret;
179 }
180
Start()181 int32_t CodecServer::Start()
182 {
183 std::lock_guard<std::shared_mutex> lock(mutex_);
184 CHECK_AND_RETURN_RET_LOG(status_ == FLUSHED || status_ == CONFIGURED,
185 AVCS_ERR_INVALID_STATE, "In invalid state");
186 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
187 int32_t ret = codecBase_->Start();
188 status_ = (ret == AVCS_ERR_OK ? RUNNING : ERROR);
189 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
190 return ret;
191 }
192
Stop()193 int32_t CodecServer::Stop()
194 {
195 std::lock_guard<std::shared_mutex> lock(mutex_);
196 CHECK_AND_RETURN_RET_LOG(status_ == RUNNING || status_ == END_OF_STREAM ||
197 status_ == FLUSHED, AVCS_ERR_INVALID_STATE, "In invalid state");
198 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
199 int32_t ret = codecBase_->Stop();
200 status_ = (ret == AVCS_ERR_OK ? CONFIGURED : ERROR);
201 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
202 return ret;
203 }
204
Flush()205 int32_t CodecServer::Flush()
206 {
207 std::lock_guard<std::shared_mutex> lock(mutex_);
208 CHECK_AND_RETURN_RET_LOG(status_ == RUNNING || status_ == END_OF_STREAM,
209 AVCS_ERR_INVALID_STATE, "In invalid state");
210 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
211 int32_t ret = codecBase_->Flush();
212 status_ = (ret == AVCS_ERR_OK ? FLUSHED : ERROR);
213 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
214 return ret;
215 }
216
NotifyEos()217 int32_t CodecServer::NotifyEos()
218 {
219 std::lock_guard<std::shared_mutex> lock(mutex_);
220 CHECK_AND_RETURN_RET_LOG(status_ == RUNNING, AVCS_ERR_INVALID_STATE, "In invalid state");
221 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
222 int32_t ret = codecBase_->NotifyEos();
223 if (ret == AVCS_ERR_OK) {
224 status_ = END_OF_STREAM;
225 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
226 }
227 return ret;
228 }
229
Reset()230 int32_t CodecServer::Reset()
231 {
232 std::lock_guard<std::shared_mutex> lock(mutex_);
233 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
234 int32_t ret = codecBase_->Reset();
235 status_ = (ret == AVCS_ERR_OK ? INITIALIZED : ERROR);
236 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
237 lastErrMsg_.clear();
238 return ret;
239 }
240
Release()241 int32_t CodecServer::Release()
242 {
243 std::lock_guard<std::shared_mutex> lock(mutex_);
244 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
245 int32_t ret = codecBase_->Release();
246 std::unique_ptr<std::thread> thread = std::make_unique<std::thread>(&CodecServer::ExitProcessor, this);
247 if (thread->joinable()) {
248 thread->join();
249 }
250 return ret;
251 }
252
CreateInputSurface()253 sptr<Surface> CodecServer::CreateInputSurface()
254 {
255 std::lock_guard<std::shared_mutex> lock(mutex_);
256 CHECK_AND_RETURN_RET_LOG(status_ == CONFIGURED, nullptr, "In invalid state");
257 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, nullptr, "Codecbase is nullptr");
258 sptr<Surface> surface = codecBase_->CreateInputSurface();
259 return surface;
260 }
261
SetOutputSurface(sptr<Surface> surface)262 int32_t CodecServer::SetOutputSurface(sptr<Surface> surface)
263 {
264 std::lock_guard<std::shared_mutex> lock(mutex_);
265 CHECK_AND_RETURN_RET_LOG(status_ == CONFIGURED, AVCS_ERR_INVALID_STATE, "In invalid state");
266 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
267 return codecBase_->SetOutputSurface(surface);
268 }
269
QueueInputBuffer(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag)270 int32_t CodecServer::QueueInputBuffer(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag)
271 {
272 int32_t ret = AVCS_ERR_OK;
273 if (flag != AVCODEC_BUFFER_FLAG_CODEC_DATA) {
274 if (isFirstFrameIn_) {
275 AVCodecTrace::TraceBegin("CodecServer::FirstFrame", info.presentationTimeUs);
276 isFirstFrameIn_ = false;
277 } else {
278 AVCodecTrace::TraceBegin("CodecServer::Frame", info.presentationTimeUs);
279 }
280 }
281 {
282 std::shared_lock<std::shared_mutex> lock(mutex_);
283 CHECK_AND_RETURN_RET_LOG(status_ == RUNNING, AVCS_ERR_INVALID_STATE, "In invalid state");
284 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
285 ret = codecBase_->QueueInputBuffer(index, info, flag);
286 }
287 if (flag & AVCODEC_BUFFER_FLAG_EOS) {
288 if (ret == AVCS_ERR_OK) {
289 std::unique_lock<std::shared_mutex> lock(mutex_);
290 status_ = END_OF_STREAM;
291 AVCODEC_LOGI("Codec server in %{public}s status", GetStatusDescription(status_).data());
292 }
293 }
294 return ret;
295 }
296
GetOutputFormat(Format & format)297 int32_t CodecServer::GetOutputFormat(Format &format)
298 {
299 std::lock_guard<std::shared_mutex> lock(mutex_);
300 CHECK_AND_RETURN_RET_LOG(status_ != UNINITIALIZED, AVCS_ERR_INVALID_STATE, "In invalid state");
301 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
302 return codecBase_->GetOutputFormat(format);
303 }
304
ReleaseOutputBuffer(uint32_t index,bool render)305 int32_t CodecServer::ReleaseOutputBuffer(uint32_t index, bool render)
306 {
307 std::shared_lock<std::shared_mutex> lock(mutex_);
308 CHECK_AND_RETURN_RET_LOG(status_ == RUNNING || status_ == END_OF_STREAM,
309 AVCS_ERR_INVALID_STATE, "In invalid state");
310 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
311
312 int32_t ret;
313 if (render) {
314 ret = codecBase_->RenderOutputBuffer(index);
315 } else {
316 ret = codecBase_->ReleaseOutputBuffer(index);
317 }
318 return ret;
319 }
320
SetParameter(const Format & format)321 int32_t CodecServer::SetParameter(const Format &format)
322 {
323 std::lock_guard<std::shared_mutex> lock(mutex_);
324 CHECK_AND_RETURN_RET_LOG(status_ != INITIALIZED && status_ != CONFIGURED,
325 AVCS_ERR_INVALID_STATE, "In invalid state");
326 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
327 return codecBase_->SetParameter(format);
328 }
329
SetCallback(const std::shared_ptr<AVCodecCallback> & callback)330 int32_t CodecServer::SetCallback(const std::shared_ptr<AVCodecCallback> &callback)
331 {
332 std::lock_guard<std::shared_mutex> cbLock(cbMutex_);
333 codecCb_ = callback;
334 return AVCS_ERR_OK;
335 }
336
GetInputFormat(Format & format)337 int32_t CodecServer::GetInputFormat(Format &format)
338 {
339 std::lock_guard<std::shared_mutex> lock(mutex_);
340 CHECK_AND_RETURN_RET_LOG(status_ != CONFIGURED, AVCS_ERR_INVALID_STATE, "In invalid state");
341 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
342 return codecBase_->GetInputFormat(format);
343 }
344
DumpInfo(int32_t fd)345 int32_t CodecServer::DumpInfo(int32_t fd)
346 {
347 CHECK_AND_RETURN_RET_LOG(codecBase_ != nullptr, AVCS_ERR_NO_MEMORY, "Codecbase is nullptr");
348 Format codecFormat;
349 int32_t ret = codecBase_->GetOutputFormat(codecFormat);
350 CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, ret, "Get codec format failed.");
351 CodecType codecType = GetCodecType();
352 auto it = CODEC_DUMP_TABLE.find(codecType);
353 const auto &dumpTable = it != CODEC_DUMP_TABLE.end() ? it->second : DEFAULT_DUMP_TABLE;
354 AVCodecDumpControler dumpControler;
355 std::string codecInfo;
356 switch (codecType) {
357 case CODEC_TYPE_VIDEO:
358 codecInfo = "Video_Codec_Info";
359 break;
360 case CODEC_TYPE_DEFAULT:
361 codecInfo = "Codec_Info";
362 break;
363 case CODEC_TYPE_AUDIO:
364 codecInfo = "Audio_Codec_Info";
365 break;
366 }
367 auto statusIt = CODEC_STATE_MAP.find(status_);
368 dumpControler.AddInfo(DUMP_CODEC_INFO_INDEX, codecInfo);
369 dumpControler.AddInfo(DUMP_STATUS_INDEX, "Status", statusIt != CODEC_STATE_MAP.end() ? statusIt->second : "");
370 dumpControler.AddInfo(DUMP_LAST_ERROR_INDEX, "Last_Error", lastErrMsg_.size() ? lastErrMsg_ : "Null");
371
372 int32_t dumpIndex = 3;
373 for (auto iter : dumpTable) {
374 if (iter.first == MediaDescriptionKey::MD_KEY_PIXEL_FORMAT) {
375 dumpControler.AddInfoFromFormatWithMapping(DUMP_CODEC_INFO_INDEX + (dumpIndex << DUMP_OFFSET_8),
376 codecFormat, iter.first, iter.second, PIXEL_FORMAT_STRING_MAP);
377 } else if (iter.first == MediaDescriptionKey::MD_KEY_SCALE_TYPE) {
378 dumpControler.AddInfoFromFormatWithMapping(DUMP_CODEC_INFO_INDEX + (dumpIndex << DUMP_OFFSET_8),
379 codecFormat, iter.first, iter.second, SCALE_TYPE_STRING_MAP);
380 } else {
381 dumpControler.AddInfoFromFormat(
382 DUMP_CODEC_INFO_INDEX + (dumpIndex << DUMP_OFFSET_8), codecFormat, iter.first, iter.second);
383 }
384 dumpIndex++;
385 }
386 std::string dumpString;
387 dumpControler.GetDumpString(dumpString);
388 if (fd != -1) {
389 write(fd, dumpString.c_str(), dumpString.size());
390 }
391 return AVCS_ERR_OK;
392 }
393
GetStatusDescription(OHOS::MediaAVCodec::CodecServer::CodecStatus status)394 const std::string &CodecServer::GetStatusDescription(OHOS::MediaAVCodec::CodecServer::CodecStatus status)
395 {
396 static const std::string ILLEGAL_STATE = "CODEC_STATUS_ILLEGAL";
397 if (status < OHOS::MediaAVCodec::CodecServer::UNINITIALIZED ||
398 status > OHOS::MediaAVCodec::CodecServer::ERROR) {
399 return ILLEGAL_STATE;
400 }
401
402 return CODEC_STATE_MAP.find(status)->second;
403 }
404
OnError(int32_t errorType,int32_t errorCode)405 void CodecServer::OnError(int32_t errorType, int32_t errorCode)
406 {
407 std::lock_guard<std::shared_mutex> lock(cbMutex_);
408 lastErrMsg_ = AVCSErrorToString(static_cast<AVCodecServiceErrCode>(errorCode));
409 FaultEventWrite(FaultType::FAULT_TYPE_INNER_ERROR, lastErrMsg_, "Codec");
410 if (codecCb_ == nullptr) {
411 return;
412 }
413 codecCb_->OnError(static_cast<AVCodecErrorType>(errorType), errorCode);
414 }
415
OnOutputFormatChanged(const Format & format)416 void CodecServer::OnOutputFormatChanged(const Format &format)
417 {
418 std::lock_guard<std::shared_mutex> lock(cbMutex_);
419 if (codecCb_ == nullptr) {
420 return;
421 }
422 codecCb_->OnOutputFormatChanged(format);
423 }
424
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)425 void CodecServer::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
426 {
427 std::shared_lock<std::shared_mutex> lock(cbMutex_);
428 if (codecCb_ == nullptr) {
429 return;
430 }
431 codecCb_->OnInputBufferAvailable(index, buffer);
432 }
433
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)434 void CodecServer::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
435 std::shared_ptr<AVSharedMemory> buffer)
436 {
437 if (flag != AVCODEC_BUFFER_FLAG_CODEC_DATA) {
438 if (isFirstFrameOut_) {
439 AVCodecTrace::TraceEnd("CodecServer::FirstFrame", info.presentationTimeUs);
440 isFirstFrameOut_ = false;
441 } else {
442 AVCodecTrace::TraceEnd("CodecServer::Frame", info.presentationTimeUs);
443 }
444 }
445
446 if (flag == AVCODEC_BUFFER_FLAG_EOS) {
447 isFirstFrameIn_ = true;
448 isFirstFrameOut_ = true;
449 }
450 std::shared_lock<std::shared_mutex> lock(cbMutex_);
451 if (codecCb_ == nullptr) {
452 return;
453 }
454 codecCb_->OnOutputBufferAvailable(index, info, flag, buffer);
455 }
456
CodecBaseCallback(const std::shared_ptr<CodecServer> & codec)457 CodecBaseCallback::CodecBaseCallback(const std::shared_ptr<CodecServer> &codec)
458 : codec_(codec)
459 {
460 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
461 }
462
~CodecBaseCallback()463 CodecBaseCallback::~CodecBaseCallback()
464 {
465 AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
466 }
467
OnError(AVCodecErrorType errorType,int32_t errorCode)468 void CodecBaseCallback::OnError(AVCodecErrorType errorType, int32_t errorCode)
469 {
470 if (codec_ != nullptr) {
471 codec_->OnError(errorType, errorCode);
472 }
473 }
474
OnOutputFormatChanged(const Format & format)475 void CodecBaseCallback::OnOutputFormatChanged(const Format &format)
476 {
477 if (codec_ != nullptr) {
478 codec_->OnOutputFormatChanged(format);
479 }
480 }
481
OnInputBufferAvailable(uint32_t index,std::shared_ptr<AVSharedMemory> buffer)482 void CodecBaseCallback::OnInputBufferAvailable(uint32_t index, std::shared_ptr<AVSharedMemory> buffer)
483 {
484 if (codec_ != nullptr) {
485 codec_->OnInputBufferAvailable(index, buffer);
486 }
487 }
488
OnOutputBufferAvailable(uint32_t index,AVCodecBufferInfo info,AVCodecBufferFlag flag,std::shared_ptr<AVSharedMemory> buffer)489 void CodecBaseCallback::OnOutputBufferAvailable(uint32_t index, AVCodecBufferInfo info, AVCodecBufferFlag flag,
490 std::shared_ptr<AVSharedMemory> buffer)
491 {
492 if (codec_ != nullptr) {
493 codec_->OnOutputBufferAvailable(index, info, flag, buffer);
494 }
495 }
496
GetCodecType()497 CodecServer::CodecType CodecServer::GetCodecType()
498 {
499 CodecType codecType;
500
501 if ((codecName_.find("Video") != codecName_.npos) || (codecName_.find("video") != codecName_.npos)) {
502 codecType = CodecType::CODEC_TYPE_VIDEO;
503 } else if ((codecName_.find("Audio") != codecName_.npos) || (codecName_.find("audio") != codecName_.npos)) {
504 codecType = CodecType::CODEC_TYPE_AUDIO;
505 } else {
506 codecType = CodecType::CODEC_TYPE_DEFAULT;
507 }
508
509 return codecType;
510 }
511 } // namespace MediaAVCodec
512 } // namespace OHOS