• 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 "muxer_engine_impl.h"
17 #include <set>
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <string>
21 #include <vector>
22 #include <unordered_map>
23 #include "securec.h"
24 #include "avcodec_log.h"
25 #include "muxer_factory.h"
26 #include "avcodec_dfx.h"
27 #include "avcodec_info.h"
28 #include "avcodec_errors.h"
29 #include "avcodec_dump_utils.h"
30 #include "avsharedmemorybase.h"
31 
32 namespace {
33     constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN, "MuxerEngineImpl"};
34     constexpr int32_t ERR_TRACK_INDEX = -1;
35     constexpr uint32_t DUMP_MUXER_INFO_INDEX = 0x01010000;
36     constexpr uint32_t DUMP_STATUS_INDEX = 0x01010100;
37     constexpr uint32_t DUMP_OUTPUT_FORMAT_INDEX = 0x01010200;
38     constexpr uint32_t DUMP_OFFSET_8 = 8;
39 
40     const std::map<OHOS::MediaAVCodec::OutputFormat, const std::string> OutputFormatStringMap = {
41         { OHOS::MediaAVCodec::OutputFormat::OUTPUT_FORMAT_M4A, "m4a" },
42         { OHOS::MediaAVCodec::OutputFormat::OUTPUT_FORMAT_MPEG_4, "mp4" },
43     };
44 
45     const std::vector<std::pair<std::string_view, const std::string>> AUDIO_DUMP_TABLE = {
46         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_MIME, "Codec_Mime" },
47         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CHANNEL_COUNT, "Channel_Count" },
48         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_SAMPLE_RATE, "Sample_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_MIME, "Codec_Mime" },
53         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, "Width" },
54         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, "Height" },
55     };
56 
57     const std::vector<std::pair<std::string_view, const std::string>> IMAGE_DUMP_TABLE = {
58         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_CODEC_MIME, "Codec_Mime" },
59         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_WIDTH, "Width" },
60         { OHOS::MediaAVCodec::MediaDescriptionKey::MD_KEY_HEIGHT, "Height" },
61     };
62 
63     const std::map<OHOS::MediaAVCodec::MuxerEngineImpl::TrackMimeType,
64         std::vector<std::pair<std::string_view, const std::string>>> MUXER_DUMP_TABLE = {
65         { OHOS::MediaAVCodec::MuxerEngineImpl::TrackMimeType::TRACK_MIME_TYPE_AUDIO, AUDIO_DUMP_TABLE },
66         { OHOS::MediaAVCodec::MuxerEngineImpl::TrackMimeType::TRACK_MIME_TYPE_VIDEO, VIDEO_DUMP_TABLE },
67         { OHOS::MediaAVCodec::MuxerEngineImpl::TrackMimeType::TRACK_MIME_TYPE_IMAGE, IMAGE_DUMP_TABLE },
68     };
69 }
70 
71 namespace OHOS {
72 namespace MediaAVCodec {
73 const std::map<uint32_t, std::set<std::string_view>> MUX_FORMAT_INFO = {
74     {OUTPUT_FORMAT_MPEG_4, {CodecMimeType::AUDIO_MPEG, CodecMimeType::AUDIO_AAC,
75                             CodecMimeType::VIDEO_AVC, CodecMimeType::VIDEO_MPEG4, CodecMimeType::VIDEO_HEVC,
76                             CodecMimeType::IMAGE_JPG, CodecMimeType::IMAGE_PNG, CodecMimeType::IMAGE_BMP}},
77     {OUTPUT_FORMAT_M4A, {CodecMimeType::AUDIO_AAC,
78                          CodecMimeType::VIDEO_AVC, CodecMimeType::VIDEO_MPEG4,
79                          CodecMimeType::IMAGE_JPG, CodecMimeType::IMAGE_PNG, CodecMimeType::IMAGE_BMP}},
80 };
81 
82 const std::map<std::string_view, std::set<std::string_view>> MUX_MIME_INFO = {
83     {CodecMimeType::AUDIO_MPEG, {MediaDescriptionKey::MD_KEY_SAMPLE_RATE, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT}},
84     {CodecMimeType::AUDIO_AAC, {MediaDescriptionKey::MD_KEY_SAMPLE_RATE, MediaDescriptionKey::MD_KEY_CHANNEL_COUNT}},
85     {CodecMimeType::VIDEO_AVC, {MediaDescriptionKey::MD_KEY_WIDTH, MediaDescriptionKey::MD_KEY_HEIGHT}},
86     {CodecMimeType::VIDEO_MPEG4, {MediaDescriptionKey::MD_KEY_WIDTH, MediaDescriptionKey::MD_KEY_HEIGHT}},
87     {CodecMimeType::VIDEO_HEVC, {MediaDescriptionKey::MD_KEY_WIDTH, MediaDescriptionKey::MD_KEY_HEIGHT}},
88     {CodecMimeType::IMAGE_JPG, {MediaDescriptionKey::MD_KEY_WIDTH, MediaDescriptionKey::MD_KEY_HEIGHT}},
89     {CodecMimeType::IMAGE_PNG, {MediaDescriptionKey::MD_KEY_WIDTH, MediaDescriptionKey::MD_KEY_HEIGHT}},
90     {CodecMimeType::IMAGE_BMP, {MediaDescriptionKey::MD_KEY_WIDTH, MediaDescriptionKey::MD_KEY_HEIGHT}},
91 };
92 
CreateMuxerEngine(int32_t appUid,int32_t appPid,int32_t fd,OutputFormat format)93 std::shared_ptr<IMuxerEngine> IMuxerEngineFactory::CreateMuxerEngine(
94     int32_t appUid, int32_t appPid, int32_t fd, OutputFormat format)
95 {
96     AVCodecTrace trace("IMuxerEngineFactory::CreateMuxerEngine");
97     CHECK_AND_RETURN_RET_LOG(fd >= 0, nullptr, "fd %{public}d is error!", fd);
98     uint32_t fdPermission = static_cast<uint32_t>(fcntl(fd, F_GETFL, 0));
99     CHECK_AND_RETURN_RET_LOG((fdPermission & O_RDWR) == O_RDWR, nullptr, "no permission to read and write fd");
100     CHECK_AND_RETURN_RET_LOG(lseek(fd, 0, SEEK_CUR) != -1, nullptr, "the fd is not seekable");
101     std::shared_ptr<MuxerEngineImpl> muxerEngineImpl = std::make_shared<MuxerEngineImpl>(appUid, appPid, fd, format);
102     int32_t ret = muxerEngineImpl->Init();
103     CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init muxer engine implementation failed");
104     return muxerEngineImpl;
105 }
106 
MuxerEngineImpl(int32_t appUid,int32_t appPid,int32_t fd,OutputFormat format)107 MuxerEngineImpl::MuxerEngineImpl(int32_t appUid, int32_t appPid, int32_t fd, OutputFormat format)
108     : appUid_(appUid), appPid_(appPid), fd_(fd), format_(format), que_("muxer_write_q"), pool_("muxer_buffer_p")
109 {
110     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances create", FAKE_POINTER(this));
111 }
112 
~MuxerEngineImpl()113 MuxerEngineImpl::~MuxerEngineImpl()
114 {
115     AVCODEC_LOGD("Destroy");
116 
117     if (state_ == State::STARTED) {
118         que_.SetActive(false);
119         StopThread();
120     }
121 
122     appUid_ = -1;
123     appPid_ = -1;
124     muxer_ = nullptr;
125     tracksDesc_.clear();
126     AVCODEC_LOGD("0x%{public}06" PRIXPTR " Instances destroy", FAKE_POINTER(this));
127 }
128 
Init()129 int32_t MuxerEngineImpl::Init()
130 {
131     AVCodecTrace trace("MuxerEngine::Init");
132     format_ = (format_ == OUTPUT_FORMAT_DEFAULT) ? OUTPUT_FORMAT_MPEG_4 : format_;
133     muxer_ = Plugin::MuxerFactory::Instance().CreatePlugin(fd_, format_);
134     if (muxer_ != nullptr && fd_ >= 0) {
135         state_ = State::INITIALIZED;
136         AVCODEC_LOGI("state_ is INITIALIZED");
137     } else {
138         AVCODEC_LOGE("state_ is UNINITIALIZED");
139         FaultEventWrite(FaultType::FAULT_TYPE_INNER_ERROR, AVCSErrorToString(AVCS_ERR_INVALID_STATE), "Muxer");
140     }
141     CHECK_AND_RETURN_RET_LOG(state_ == State::INITIALIZED, AVCS_ERR_INVALID_STATE, "state_ is UNINITIALIZED");
142     return AVCS_ERR_OK;
143 }
144 
SetRotation(int32_t rotation)145 int32_t MuxerEngineImpl::SetRotation(int32_t rotation)
146 {
147     AVCodecTrace trace("MuxerEngine::SetRotation");
148     AVCODEC_LOGI("SetRotation");
149     std::lock_guard<std::mutex> lock(mutex_);
150     CHECK_AND_RETURN_RET_LOG(state_ == State::INITIALIZED, AVCS_ERR_INVALID_OPERATION,
151         "The state is not INITIALIZED, the interface must be called after constructor and before Start(). "
152         "The current state is %{public}s", ConvertStateToString(state_).c_str());
153     if (rotation != VIDEO_ROTATION_0 && rotation != VIDEO_ROTATION_90 &&
154         rotation != VIDEO_ROTATION_180 && rotation != VIDEO_ROTATION_270) {
155         AVCODEC_LOGW("Invalid rotation: %{public}d, keep default 0", rotation);
156         return AVCS_ERR_INVALID_VAL;
157     }
158     Plugin::Status ret = muxer_->SetRotation(rotation);
159     CHECK_AND_RETURN_RET_LOG(ret == Plugin::Status::NO_ERROR, TranslatePluginStatus(ret), "SetRotation failed");
160     return AVCS_ERR_OK;
161 }
162 
AddTrack(int32_t & trackIndex,const MediaDescription & trackDesc)163 int32_t MuxerEngineImpl::AddTrack(int32_t &trackIndex, const MediaDescription &trackDesc)
164 {
165     AVCodecTrace trace("MuxerEngine::AddTrack");
166     AVCODEC_LOGI("AddTrack");
167     std::lock_guard<std::mutex> lock(mutex_);
168     trackIndex = ERR_TRACK_INDEX;
169     CHECK_AND_RETURN_RET_LOG(state_ == State::INITIALIZED, AVCS_ERR_INVALID_OPERATION,
170         "The state is not INITIALIZED, the interface must be called after constructor and before Start(). "
171         "The current state is %{public}s", ConvertStateToString(state_).c_str());
172     std::string mimeType = {};
173     CHECK_AND_RETURN_RET_LOG(trackDesc.GetStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, mimeType),
174         AVCS_ERR_INVALID_VAL, "track format does not contain mime");
175     CHECK_AND_RETURN_RET_LOG(CanAddTrack(mimeType), AVCS_ERR_UNSUPPORT_CONTAINER_TYPE,
176         "track mime is unsupported: %{public}s", mimeType.c_str());
177     CHECK_AND_RETURN_RET_LOG(CheckKeys(mimeType, trackDesc), AVCS_ERR_INVALID_VAL,
178         "track format keys not contained");
179 
180     int32_t trackId = -1;
181     Plugin::Status ret = muxer_->AddTrack(trackId, trackDesc);
182     CHECK_AND_RETURN_RET_LOG(ret == Plugin::Status::NO_ERROR, TranslatePluginStatus(ret), "AddTrack failed");
183     CHECK_AND_RETURN_RET_LOG(trackId >= 0, AVCS_ERR_INVALID_OPERATION,
184         "The track index is greater than or equal to 0.");
185     trackIndex = trackId;
186     tracksDesc_.emplace(trackIndex, MediaDescription(trackDesc));
187 
188     return AVCS_ERR_OK;
189 }
190 
Start()191 int32_t MuxerEngineImpl::Start()
192 {
193     AVCodecTrace trace("MuxerEngine::Start");
194     AVCODEC_LOGI("Start");
195     std::lock_guard<std::mutex> lock(mutex_);
196     CHECK_AND_RETURN_RET_LOG(state_ == State::INITIALIZED, AVCS_ERR_INVALID_OPERATION,
197         "The state is not INITIALIZED, the interface must be called after AddTrack() and before WriteSample(). "
198         "The current state is %{public}s", ConvertStateToString(state_).c_str());
199     CHECK_AND_RETURN_RET_LOG(tracksDesc_.size() > 0, AVCS_ERR_INVALID_OPERATION,
200         "The track count is error, count is %{public}zu", tracksDesc_.size());
201     Plugin::Status ret = muxer_->Start();
202     CHECK_AND_RETURN_RET_LOG(ret == Plugin::Status::NO_ERROR, TranslatePluginStatus(ret), "Start failed");
203     state_ = State::STARTED;
204     StartThread("muxer_write_loop");
205     return AVCS_ERR_OK;
206 }
207 
WriteSample(uint32_t trackIndex,std::shared_ptr<AVSharedMemory> sample,AVCodecBufferInfo info,AVCodecBufferFlag flag)208 int32_t MuxerEngineImpl::WriteSample(uint32_t trackIndex, std::shared_ptr<AVSharedMemory> sample,
209     AVCodecBufferInfo info, AVCodecBufferFlag flag)
210 {
211     AVCodecTrace trace("MuxerEngine::WriteSample");
212     std::lock_guard<std::mutex> lock(mutex_);
213     CHECK_AND_RETURN_RET_LOG(state_ == State::STARTED, AVCS_ERR_INVALID_OPERATION,
214         "The state is not STARTED, the interface must be called after Start() and before Stop(). "
215         "The current state is %{public}s", ConvertStateToString(state_).c_str());
216     CHECK_AND_RETURN_RET_LOG(tracksDesc_.find(trackIndex) != tracksDesc_.end(), AVCS_ERR_INVALID_VAL,
217         "The track index does not exist");
218     CHECK_AND_RETURN_RET_LOG(sample != nullptr && info.offset >= 0 && info.size >= 0 &&
219         sample->GetSize() >= (info.offset + info.size), AVCS_ERR_INVALID_VAL, "Invalid memory");
220 
221     std::shared_ptr<uint8_t> buffer = pool_.AcquireBuffer(info.size);
222     CHECK_AND_RETURN_RET_LOG(buffer != nullptr, AVCS_ERR_NO_MEMORY, "AcquireBuffer from pool failed");
223     errno_t rc = memcpy_s(buffer.get(), info.size, sample->GetBase() + info.offset, info.size);
224     CHECK_AND_RETURN_RET_LOG(rc == EOK, AVCS_ERR_UNKNOWN, "memcpy_s failed");
225 
226     std::shared_ptr<BlockBuffer> blockBuffer = std::make_shared<BlockBuffer>();
227     blockBuffer->trackIndex_ = trackIndex;
228     blockBuffer->buffer_ = buffer;
229     blockBuffer->info_ = info;
230     blockBuffer->flag_ = flag;
231     que_.Push(blockBuffer);
232 
233     return AVCS_ERR_OK;
234 }
235 
Stop()236 int32_t MuxerEngineImpl::Stop()
237 {
238     AVCodecTrace trace("MuxerEngine::Stop");
239     AVCODEC_LOGI("Stop");
240     std::unique_lock<std::mutex> lock(mutex_);
241     if (state_ == State::STOPPED) {
242         AVCODEC_LOGW("current state is STOPPED!");
243         return AVCS_ERR_INVALID_OPERATION;
244     }
245     CHECK_AND_RETURN_RET_LOG(state_ == State::STARTED, AVCS_ERR_INVALID_OPERATION,
246         "The state is not STARTED. The current state is %{public}s", ConvertStateToString(state_).c_str());
247     state_ = State::STOPPED;
248     que_.SetActive(false, false);
249     cond_.wait(lock, [this] { return que_.Empty(); });
250     StopThread();
251     Plugin::Status ret = muxer_->Stop();
252     CHECK_AND_RETURN_RET_LOG(ret == Plugin::Status::NO_ERROR, TranslatePluginStatus(ret), "Stop failed");
253     return AVCS_ERR_OK;
254 }
255 
DumpInfo(int32_t fd)256 int32_t MuxerEngineImpl::DumpInfo(int32_t fd)
257 {
258     AVCodecDumpControler dumpControler;
259     dumpControler.AddInfo(DUMP_MUXER_INFO_INDEX, "Muxer_Info");
260     dumpControler.AddInfo(DUMP_STATUS_INDEX, "Status", ConvertStateToString(state_));
261     dumpControler.AddInfo(DUMP_OUTPUT_FORMAT_INDEX,
262         "Output_Format", OutputFormatStringMap.at(format_));
263 
264     int32_t dumpTrackIndex = 3;
265     int mediaDescIdx = 0;
266     for (auto it = tracksDesc_.begin(); it != tracksDesc_.end(); ++it) {
267         auto mediaDesc = it->second;
268         int32_t dumpInfoIndex = 1;
269         std::string codecMime;
270         bool ret = mediaDesc.GetStringValue(MediaDescriptionKey::MD_KEY_CODEC_MIME, codecMime);
271         CHECK_AND_CONTINUE_LOG(ret == true, "Get codec mime from format failed.");
272         TrackMimeType mimeType = GetTrackMimeType(codecMime);
273         auto &dumpTable = MUXER_DUMP_TABLE.at(mimeType);
274 
275         dumpControler.AddInfo(DUMP_MUXER_INFO_INDEX + (dumpTrackIndex << DUMP_OFFSET_8),
276             std::string("Track_") + std::to_string(mediaDescIdx++) + "_Info");
277         for (auto iter : dumpTable) {
278             dumpControler.AddInfoFromFormat(
279                 DUMP_MUXER_INFO_INDEX + (dumpTrackIndex << DUMP_OFFSET_8) + dumpInfoIndex,
280                 mediaDesc, iter.first, iter.second);
281             dumpInfoIndex++;
282         }
283         dumpTrackIndex++;
284     }
285 
286     std::string dumpString;
287     dumpControler.GetDumpString(dumpString);
288     CHECK_AND_RETURN_RET_LOG(fd != -1, AVCS_ERR_INVALID_VAL, "Get a invalid fd.");
289     write(fd, dumpString.c_str(), dumpString.size());
290 
291     return AVCS_ERR_OK;
292 }
293 
StartThread(const std::string & name)294 int32_t MuxerEngineImpl::StartThread(const std::string &name)
295 {
296     AVCodecTrace trace("MuxerEngine::StartThread");
297     threadName_ = name;
298     if (thread_ != nullptr) {
299         AVCODEC_LOGW("Started already! [%{public}s]", threadName_.c_str());
300         return AVCS_ERR_OK;
301     }
302     isThreadExit_ = false;
303     thread_ = std::make_unique<std::thread>(&MuxerEngineImpl::ThreadProcessor, this);
304     AVCodecTrace::TraceBegin("muxer_write_thread", FAKE_POINTER(thread_.get()));
305     AVCODEC_LOGD("thread started! [%{public}s]", threadName_.c_str());
306     return AVCS_ERR_OK;
307 }
308 
StopThread()309 int32_t MuxerEngineImpl::StopThread() noexcept
310 {
311     if (isThreadExit_) {
312         AVCODEC_LOGD("Stopped already! [%{public}s]", threadName_.c_str());
313         return AVCS_ERR_OK;
314     }
315     if (std::this_thread::get_id() == thread_->get_id()) {
316         AVCODEC_LOGD("Stop at the task thread, reject");
317         return AVCS_ERR_INVALID_OPERATION;
318     }
319 
320     std::unique_ptr<std::thread> t;
321     isThreadExit_ = true;
322     cond_.notify_all();
323     std::swap(thread_, t);
324     if (t != nullptr && t->joinable()) {
325         t->join();
326     }
327     thread_ = nullptr;
328     return AVCS_ERR_OK;
329 }
330 
ThreadProcessor()331 void MuxerEngineImpl::ThreadProcessor()
332 {
333     AVCODEC_LOGD("Enter ThreadProcessor [%{public}s]", threadName_.c_str());
334     constexpr uint32_t nameSizeMax = 15;
335     pthread_setname_np(pthread_self(), threadName_.substr(0, nameSizeMax).c_str());
336     int32_t taskId = FAKE_POINTER(thread_.get());
337     for (;;) {
338         AVCodecTrace trace(threadName_);
339         if (isThreadExit_) {
340             AVCodecTrace::TraceEnd("muxer_write_thread", taskId);
341             AVCODEC_LOGD("Exit ThreadProcessor [%{public}s]", threadName_.c_str());
342             return;
343         }
344         auto buffer = que_.Pop();
345         if (buffer != nullptr) {
346             (void)muxer_->WriteSample(buffer->trackIndex_, buffer->buffer_.get(), buffer->info_, buffer->flag_);
347             pool_.ReleaseBuffer(buffer->buffer_);
348         }
349         if (que_.Empty()) {
350             cond_.notify_all();
351         }
352     }
353 }
354 
CanAddTrack(const std::string & mimeType)355 bool MuxerEngineImpl::CanAddTrack(const std::string &mimeType)
356 {
357     auto it = MUX_FORMAT_INFO.find(format_);
358     if (it == MUX_FORMAT_INFO.end()) {
359         return false;
360     }
361     return it->second.find(mimeType) != it->second.end();
362 }
363 
CheckKeys(const std::string & mimeType,const MediaDescription & trackDesc)364 bool MuxerEngineImpl::CheckKeys(const std::string &mimeType, const MediaDescription &trackDesc)
365 {
366     bool ret = true;
367     auto it = MUX_MIME_INFO.find(mimeType);
368     if (it == MUX_MIME_INFO.end()) {
369         return ret; // 不做检查
370     }
371 
372     for (auto &key : it->second) {
373         if (!trackDesc.ContainKey(key)) {
374             ret = false;
375             AVCODEC_LOGE("the MediaDescriptionKey %{public}s not contained", key.data());
376         }
377     }
378     return ret;
379 }
380 
ConvertStateToString(State state)381 std::string MuxerEngineImpl::ConvertStateToString(State state)
382 {
383     std::string stateInfo {};
384     switch (state) {
385         case State::UNINITIALIZED:
386             stateInfo = "UNINITIALIZED";
387             break;
388         case State::INITIALIZED:
389             stateInfo = "INITIALIZED";
390             break;
391         case State::STARTED:
392             stateInfo = "STARTED";
393             break;
394         case State::STOPPED:
395             stateInfo = "STOPPED";
396             break;
397         default:
398             break;
399     }
400     return stateInfo;
401 }
402 
TranslatePluginStatus(Plugin::Status error)403 int32_t MuxerEngineImpl::TranslatePluginStatus(Plugin::Status error)
404 {
405     const static std::unordered_map<Plugin::Status, int32_t> g_transTable = {
406         {Plugin::Status::END_OF_STREAM, AVCodecServiceErrCode::AVCS_ERR_OK},
407         {Plugin::Status::OK, AVCodecServiceErrCode::AVCS_ERR_OK},
408         {Plugin::Status::NO_ERROR, AVCodecServiceErrCode::AVCS_ERR_OK},
409         {Plugin::Status::ERROR_UNKNOWN, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
410         {Plugin::Status::ERROR_PLUGIN_ALREADY_EXISTS, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
411         {Plugin::Status::ERROR_INCOMPATIBLE_VERSION, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
412         {Plugin::Status::ERROR_NO_MEMORY, AVCodecServiceErrCode::AVCS_ERR_NO_MEMORY},
413         {Plugin::Status::ERROR_WRONG_STATE, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION},
414         {Plugin::Status::ERROR_UNIMPLEMENTED, AVCodecServiceErrCode::AVCS_ERR_UNSUPPORT},
415         {Plugin::Status::ERROR_INVALID_PARAMETER, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL},
416         {Plugin::Status::ERROR_INVALID_DATA, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL},
417         {Plugin::Status::ERROR_MISMATCHED_TYPE, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL},
418         {Plugin::Status::ERROR_TIMED_OUT, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
419         {Plugin::Status::ERROR_UNSUPPORTED_FORMAT, AVCodecServiceErrCode::AVCS_ERR_UNSUPPORT_CONTAINER_TYPE},
420         {Plugin::Status::ERROR_NOT_ENOUGH_DATA, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
421         {Plugin::Status::ERROR_NOT_EXISTED, AVCodecServiceErrCode::AVCS_ERR_OPEN_FILE_FAILED},
422         {Plugin::Status::ERROR_AGAIN, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
423         {Plugin::Status::ERROR_PERMISSION_DENIED, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
424         {Plugin::Status::ERROR_NULL_POINTER, AVCodecServiceErrCode::AVCS_ERR_INVALID_VAL},
425         {Plugin::Status::ERROR_INVALID_OPERATION, AVCodecServiceErrCode::AVCS_ERR_INVALID_OPERATION},
426         {Plugin::Status::ERROR_CLIENT, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
427         {Plugin::Status::ERROR_SERVER, AVCodecServiceErrCode::AVCS_ERR_UNKNOWN},
428         {Plugin::Status::ERROR_DELAY_READY, AVCodecServiceErrCode::AVCS_ERR_OK},
429     };
430     auto ite = g_transTable.find(error);
431     if (ite == g_transTable.end()) {
432         return AVCS_ERR_UNKNOWN;
433     }
434     return ite->second;
435 }
436 
GetTrackMimeType(const std::string & mime)437 MuxerEngineImpl::TrackMimeType MuxerEngineImpl::GetTrackMimeType(const std::string &mime)
438 {
439     TrackMimeType type;
440     if (mime.find("audio") != mime.npos) {
441         type = TRACK_MIME_TYPE_AUDIO;
442     } else if (mime.find("video") != mime.npos) {
443         type = TRACK_MIME_TYPE_VIDEO;
444     } else {
445         type = TRACK_MIME_TYPE_IMAGE;
446     }
447 
448     return type;
449 }
450 } // MediaAVCodec
451 } // OHOS