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