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