1da853ecaSopenharmony_ci/* 2da853ecaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd. 3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License. 5da853ecaSopenharmony_ci * You may obtain a copy of the License at 6da853ecaSopenharmony_ci * 7da853ecaSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8da853ecaSopenharmony_ci * 9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and 13da853ecaSopenharmony_ci * limitations under the License. 14da853ecaSopenharmony_ci */ 15da853ecaSopenharmony_ci#include <vector> 16da853ecaSopenharmony_ci#include <unistd.h> 17da853ecaSopenharmony_ci#include <fcntl.h> 18da853ecaSopenharmony_ci#include "i_avcodec_service.h" 19da853ecaSopenharmony_ci#include "avcodec_errors.h" 20da853ecaSopenharmony_ci#include "avcodec_log.h" 21da853ecaSopenharmony_ci#include "avcodec_trace.h" 22da853ecaSopenharmony_ci#include "avsource_impl.h" 23da853ecaSopenharmony_ci#include "common/media_source.h" 24da853ecaSopenharmony_ci#include "common/status.h" 25da853ecaSopenharmony_ci 26da853ecaSopenharmony_cinamespace { 27da853ecaSopenharmony_ci constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_DEMUXER, "AVSourceImpl"}; 28da853ecaSopenharmony_ci} 29da853ecaSopenharmony_ci 30da853ecaSopenharmony_cinamespace OHOS { 31da853ecaSopenharmony_cinamespace MediaAVCodec { 32da853ecaSopenharmony_ciusing namespace Media; 33da853ecaSopenharmony_ciusing namespace Media::Plugins; 34da853ecaSopenharmony_cistd::shared_ptr<AVSource> AVSourceFactory::CreateWithURI(const std::string &uri) 35da853ecaSopenharmony_ci{ 36da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 37da853ecaSopenharmony_ci 38da853ecaSopenharmony_ci AVCODEC_LOGD("Create source with uri %{private}s", uri.c_str()); 39da853ecaSopenharmony_ci 40da853ecaSopenharmony_ci std::shared_ptr<AVSourceImpl> sourceImpl = std::make_shared<AVSourceImpl>(); 41da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sourceImpl != nullptr, nullptr, "New avsource failed"); 42da853ecaSopenharmony_ci 43da853ecaSopenharmony_ci int32_t ret = sourceImpl->InitWithURI(uri); 44da853ecaSopenharmony_ci 45da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init avsource failed"); 46da853ecaSopenharmony_ci 47da853ecaSopenharmony_ci return sourceImpl; 48da853ecaSopenharmony_ci} 49da853ecaSopenharmony_ci 50da853ecaSopenharmony_cistd::shared_ptr<AVSource> AVSourceFactory::CreateWithFD(int32_t fd, int64_t offset, int64_t size) 51da853ecaSopenharmony_ci{ 52da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 53da853ecaSopenharmony_ci 54da853ecaSopenharmony_ci AVCODEC_LOGD("Create source with fd %{private}d, offset=%{public}" PRId64 ", size=%{public}" PRId64, 55da853ecaSopenharmony_ci fd, offset, size); 56da853ecaSopenharmony_ci 57da853ecaSopenharmony_ci std::shared_ptr<AVSourceImpl> sourceImpl = std::make_shared<AVSourceImpl>(); 58da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sourceImpl != nullptr, nullptr, "New avsource failed"); 59da853ecaSopenharmony_ci 60da853ecaSopenharmony_ci int32_t ret = sourceImpl->InitWithFD(fd, offset, size); 61da853ecaSopenharmony_ci 62da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init avsource failed"); 63da853ecaSopenharmony_ci 64da853ecaSopenharmony_ci return sourceImpl; 65da853ecaSopenharmony_ci} 66da853ecaSopenharmony_ci 67da853ecaSopenharmony_cistd::shared_ptr<AVSource> AVSourceFactory::CreateWithDataSource( 68da853ecaSopenharmony_ci const std::shared_ptr<Media::IMediaDataSource> &dataSource) 69da853ecaSopenharmony_ci{ 70da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 71da853ecaSopenharmony_ci 72da853ecaSopenharmony_ci std::shared_ptr<AVSourceImpl> sourceImpl = std::make_shared<AVSourceImpl>(); 73da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sourceImpl != nullptr, nullptr, "New avsource failed"); 74da853ecaSopenharmony_ci 75da853ecaSopenharmony_ci int32_t ret = sourceImpl->InitWithDataSource(dataSource); 76da853ecaSopenharmony_ci 77da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init avsource failed"); 78da853ecaSopenharmony_ci 79da853ecaSopenharmony_ci return sourceImpl; 80da853ecaSopenharmony_ci} 81da853ecaSopenharmony_ci 82da853ecaSopenharmony_ciint32_t AVSourceImpl::InitWithURI(const std::string &uri) 83da853ecaSopenharmony_ci{ 84da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 85da853ecaSopenharmony_ci 86da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer == nullptr, AVCS_ERR_INVALID_OPERATION, "Has been used by demuxer"); 87da853ecaSopenharmony_ci mediaDemuxer = std::make_shared<MediaDemuxer>(); 88da853ecaSopenharmony_ci mediaDemuxer->SetPlayerId("AVSource_URI"); 89da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer != nullptr, AVCS_ERR_INVALID_OPERATION, "Create mediaDemuxer failed"); 90da853ecaSopenharmony_ci 91da853ecaSopenharmony_ci std::shared_ptr<MediaSource> mediaSource = std::make_shared<MediaSource>(uri); 92da853ecaSopenharmony_ci Status ret = mediaDemuxer->SetDataSource(mediaSource); 93da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == Status::OK, StatusToAVCodecServiceErrCode(ret), "Set data source failed"); 94da853ecaSopenharmony_ci 95da853ecaSopenharmony_ci sourceUri = uri; 96da853ecaSopenharmony_ci return AVCS_ERR_OK; 97da853ecaSopenharmony_ci} 98da853ecaSopenharmony_ci 99da853ecaSopenharmony_ciint32_t AVSourceImpl::InitWithFD(int32_t fd, int64_t offset, int64_t size) 100da853ecaSopenharmony_ci{ 101da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 102da853ecaSopenharmony_ci 103da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer == nullptr, AVCS_ERR_INVALID_OPERATION, "Has been used by demuxer"); 104da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(fd >= 0, AVCS_ERR_INVALID_VAL, "Input fd is negative"); 105da853ecaSopenharmony_ci if (fd <= STDERR_FILENO) { 106da853ecaSopenharmony_ci AVCODEC_LOGW("Using special fd: %{public}d, isatty: %{public}d", fd, isatty(fd)); 107da853ecaSopenharmony_ci } 108da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(offset >= 0, AVCS_ERR_INVALID_VAL, "Input offset is negative"); 109da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(size > 0, AVCS_ERR_INVALID_VAL, "Input size must be greater than zero"); 110da853ecaSopenharmony_ci int32_t flag = fcntl(fd, F_GETFL, 0); 111da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(flag >= 0, AVCS_ERR_INVALID_VAL, "Get fd status failed"); 112da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG( 113da853ecaSopenharmony_ci (static_cast<uint32_t>(flag) & static_cast<uint32_t>(O_WRONLY)) != static_cast<uint32_t>(O_WRONLY), 114da853ecaSopenharmony_ci AVCS_ERR_INVALID_VAL, "Fd is not permitted to read"); 115da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(lseek(fd, 0, SEEK_CUR) != -1, AVCS_ERR_INVALID_VAL, "Fd unseekable"); 116da853ecaSopenharmony_ci 117da853ecaSopenharmony_ci std::string uri = "fd://" + std::to_string(fd) + "?offset=" + \ 118da853ecaSopenharmony_ci std::to_string(offset) + "&size=" + std::to_string(size); 119da853ecaSopenharmony_ci 120da853ecaSopenharmony_ci return InitWithURI(uri); 121da853ecaSopenharmony_ci} 122da853ecaSopenharmony_ci 123da853ecaSopenharmony_ciint32_t AVSourceImpl::InitWithDataSource(const std::shared_ptr<Media::IMediaDataSource> &dataSource) 124da853ecaSopenharmony_ci{ 125da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 126da853ecaSopenharmony_ci 127da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer == nullptr, AVCS_ERR_INVALID_OPERATION, "Has been used by demuxer"); 128da853ecaSopenharmony_ci mediaDemuxer = std::make_shared<MediaDemuxer>(); 129da853ecaSopenharmony_ci mediaDemuxer->SetPlayerId("AVSource_Data"); 130da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer != nullptr, AVCS_ERR_INVALID_OPERATION, "Create mediaDemuxer failed"); 131da853ecaSopenharmony_ci 132da853ecaSopenharmony_ci std::shared_ptr<MediaSource> mediaSource = std::make_shared<MediaSource>(dataSource); 133da853ecaSopenharmony_ci Status ret = mediaDemuxer->SetDataSource(mediaSource); 134da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == Status::OK, StatusToAVCodecServiceErrCode(ret), "Set data source failed"); 135da853ecaSopenharmony_ci 136da853ecaSopenharmony_ci return AVCS_ERR_OK; 137da853ecaSopenharmony_ci} 138da853ecaSopenharmony_ci 139da853ecaSopenharmony_ciAVSourceImpl::AVSourceImpl() 140da853ecaSopenharmony_ci{ 141da853ecaSopenharmony_ci AVCODEC_LOGD("Create instances 0x%{public}06" PRIXPTR, FAKE_POINTER(this)); 142da853ecaSopenharmony_ci} 143da853ecaSopenharmony_ci 144da853ecaSopenharmony_ciAVSourceImpl::~AVSourceImpl() 145da853ecaSopenharmony_ci{ 146da853ecaSopenharmony_ci if (mediaDemuxer != nullptr) { 147da853ecaSopenharmony_ci mediaDemuxer = nullptr; 148da853ecaSopenharmony_ci } 149da853ecaSopenharmony_ci AVCODEC_LOGD("Destroy instances 0x%{public}06" PRIXPTR, FAKE_POINTER(this)); 150da853ecaSopenharmony_ci} 151da853ecaSopenharmony_ci 152da853ecaSopenharmony_ciint32_t AVSourceImpl::GetSourceFormat(OHOS::Media::Format &format) 153da853ecaSopenharmony_ci{ 154da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 155da853ecaSopenharmony_ci AVCODEC_LOGD("Get source format"); 156da853ecaSopenharmony_ci 157da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 158da853ecaSopenharmony_ci 159da853ecaSopenharmony_ci std::shared_ptr<OHOS::Media::Meta> mediaInfo = mediaDemuxer->GetGlobalMetaInfo(); 160da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaInfo != nullptr, AVCS_ERR_INVALID_OPERATION, "Parse media info failed"); 161da853ecaSopenharmony_ci 162da853ecaSopenharmony_ci bool set = format.SetMeta(mediaInfo); 163da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(set, AVCS_ERR_INVALID_OPERATION, "Convert meta failed"); 164da853ecaSopenharmony_ci 165da853ecaSopenharmony_ci return AVCS_ERR_OK; 166da853ecaSopenharmony_ci} 167da853ecaSopenharmony_ci 168da853ecaSopenharmony_ciint32_t AVSourceImpl::GetTrackFormat(OHOS::Media::Format &format, uint32_t trackIndex) 169da853ecaSopenharmony_ci{ 170da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 171da853ecaSopenharmony_ci AVCODEC_LOGD("Get track %{public}u format", trackIndex); 172da853ecaSopenharmony_ci 173da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 174da853ecaSopenharmony_ci 175da853ecaSopenharmony_ci std::vector<std::shared_ptr<Meta>> streamsInfo = mediaDemuxer->GetStreamMetaInfo(); 176da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(trackIndex < streamsInfo.size(), AVCS_ERR_INVALID_VAL, 177da853ecaSopenharmony_ci "Just have %{public}zu tracks. index is out of range", streamsInfo.size()); 178da853ecaSopenharmony_ci 179da853ecaSopenharmony_ci bool set = format.SetMeta(streamsInfo[trackIndex]); 180da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(set, AVCS_ERR_INVALID_OPERATION, "Convert meta failed"); 181da853ecaSopenharmony_ci 182da853ecaSopenharmony_ci return AVCS_ERR_OK; 183da853ecaSopenharmony_ci} 184da853ecaSopenharmony_ci 185da853ecaSopenharmony_ciint32_t AVSourceImpl::GetUserMeta(OHOS::Media::Format &format) 186da853ecaSopenharmony_ci{ 187da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 188da853ecaSopenharmony_ci AVCODEC_LOGD("get user meta"); 189da853ecaSopenharmony_ci 190da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 191da853ecaSopenharmony_ci 192da853ecaSopenharmony_ci std::shared_ptr<OHOS::Media::Meta> userDataMeta = mediaDemuxer->GetUserMeta(); 193da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(userDataMeta != nullptr, AVCS_ERR_INVALID_OPERATION, "Parse user info failed"); 194da853ecaSopenharmony_ci 195da853ecaSopenharmony_ci bool set = format.SetMeta(userDataMeta); 196da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(set, AVCS_ERR_INVALID_OPERATION, "Convert meta failed"); 197da853ecaSopenharmony_ci 198da853ecaSopenharmony_ci return AVCS_ERR_OK; 199da853ecaSopenharmony_ci} 200da853ecaSopenharmony_ci} // namespace MediaAVCodec 201da853ecaSopenharmony_ci} // namespace OHOS