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 16da853ecaSopenharmony_ci#include "avdemuxer_impl.h" 17da853ecaSopenharmony_ci#include <fcntl.h> 18da853ecaSopenharmony_ci#include <unistd.h> 19da853ecaSopenharmony_ci#include <functional> 20da853ecaSopenharmony_ci#include <sys/types.h> 21da853ecaSopenharmony_ci#include "securec.h" 22da853ecaSopenharmony_ci#include "avcodec_log.h" 23da853ecaSopenharmony_ci#include "buffer/avsharedmemorybase.h" 24da853ecaSopenharmony_ci#include "avcodec_trace.h" 25da853ecaSopenharmony_ci#include "meta/media_types.h" 26da853ecaSopenharmony_ci#include "avcodec_errors.h" 27da853ecaSopenharmony_ci 28da853ecaSopenharmony_cinamespace { 29da853ecaSopenharmony_ci constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_DEMUXER, "AVDemuxerImpl"}; 30da853ecaSopenharmony_ci} 31da853ecaSopenharmony_ci 32da853ecaSopenharmony_cinamespace OHOS { 33da853ecaSopenharmony_cinamespace MediaAVCodec { 34da853ecaSopenharmony_ciusing namespace Media; 35da853ecaSopenharmony_ciusing namespace Media::Plugins; 36da853ecaSopenharmony_cistd::shared_ptr<AVDemuxer> AVDemuxerFactory::CreateWithSource(std::shared_ptr<AVSource> source) 37da853ecaSopenharmony_ci{ 38da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 39da853ecaSopenharmony_ci 40da853ecaSopenharmony_ci std::shared_ptr<AVDemuxerImpl> demuxerImpl = std::make_shared<AVDemuxerImpl>(); 41da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(demuxerImpl != nullptr, nullptr, "New avdemuxer failed"); 42da853ecaSopenharmony_ci 43da853ecaSopenharmony_ci int32_t ret = demuxerImpl->Init(source); 44da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init avdemuxer failed"); 45da853ecaSopenharmony_ci 46da853ecaSopenharmony_ci return demuxerImpl; 47da853ecaSopenharmony_ci} 48da853ecaSopenharmony_ci 49da853ecaSopenharmony_ciint32_t AVDemuxerImpl::Init(std::shared_ptr<AVSource> source) 50da853ecaSopenharmony_ci{ 51da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 52da853ecaSopenharmony_ci 53da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(source != nullptr, AVCS_ERR_INVALID_VAL, "AVSource is nullptr"); 54da853ecaSopenharmony_ci AVCODEC_LOGD("Init avdemuxer for %{private}s", source->sourceUri.c_str()); 55da853ecaSopenharmony_ci 56da853ecaSopenharmony_ci mediaDemuxer_ = source->mediaDemuxer; 57da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Init mediaDemuxer failed"); 58da853ecaSopenharmony_ci return AVCS_ERR_OK; 59da853ecaSopenharmony_ci} 60da853ecaSopenharmony_ci 61da853ecaSopenharmony_ciAVDemuxerImpl::AVDemuxerImpl() 62da853ecaSopenharmony_ci{ 63da853ecaSopenharmony_ci AVCODEC_LOGD("Create instances 0x%{public}06" PRIXPTR, FAKE_POINTER(this)); 64da853ecaSopenharmony_ci} 65da853ecaSopenharmony_ci 66da853ecaSopenharmony_ciAVDemuxerImpl::~AVDemuxerImpl() 67da853ecaSopenharmony_ci{ 68da853ecaSopenharmony_ci if (mediaDemuxer_ != nullptr) { 69da853ecaSopenharmony_ci mediaDemuxer_ = nullptr; 70da853ecaSopenharmony_ci } 71da853ecaSopenharmony_ci AVCODEC_LOGD("Destroy instances 0x%{public}06" PRIXPTR, FAKE_POINTER(this)); 72da853ecaSopenharmony_ci} 73da853ecaSopenharmony_ci 74da853ecaSopenharmony_ciint32_t AVDemuxerImpl::SelectTrackByID(uint32_t trackIndex) 75da853ecaSopenharmony_ci{ 76da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 77da853ecaSopenharmony_ci 78da853ecaSopenharmony_ci AVCODEC_LOGD("Select track %{public}u", trackIndex); 79da853ecaSopenharmony_ci 80da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 81da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->SelectTrack(trackIndex)); 82da853ecaSopenharmony_ci} 83da853ecaSopenharmony_ci 84da853ecaSopenharmony_ciint32_t AVDemuxerImpl::UnselectTrackByID(uint32_t trackIndex) 85da853ecaSopenharmony_ci{ 86da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 87da853ecaSopenharmony_ci 88da853ecaSopenharmony_ci AVCODEC_LOGD("Unselect track %{public}u", trackIndex); 89da853ecaSopenharmony_ci 90da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 91da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->UnselectTrack(trackIndex)); 92da853ecaSopenharmony_ci} 93da853ecaSopenharmony_ci 94da853ecaSopenharmony_ciint32_t AVDemuxerImpl::ReadSampleBuffer(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample) 95da853ecaSopenharmony_ci{ 96da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 97da853ecaSopenharmony_ci 98da853ecaSopenharmony_ci AVCODEC_LOGD("ReadSampleBuffer for track %{public}u", trackIndex); 99da853ecaSopenharmony_ci 100da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 101da853ecaSopenharmony_ci 102da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sample != nullptr && sample->memory_ != nullptr, AVCS_ERR_INVALID_VAL, 103da853ecaSopenharmony_ci "Sample buffer is nullptr"); 104da853ecaSopenharmony_ci 105da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->ReadSample(trackIndex, sample)); 106da853ecaSopenharmony_ci} 107da853ecaSopenharmony_ci 108da853ecaSopenharmony_ciint32_t AVDemuxerImpl::ReadSample(uint32_t trackIndex, std::shared_ptr<AVSharedMemory> sample, 109da853ecaSopenharmony_ci AVCodecBufferInfo &info, uint32_t &flag) 110da853ecaSopenharmony_ci{ 111da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 112da853ecaSopenharmony_ci 113da853ecaSopenharmony_ci AVCODEC_LOGD("ReadSample for track %{public}u", trackIndex); 114da853ecaSopenharmony_ci 115da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 116da853ecaSopenharmony_ci 117da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sample != nullptr, AVCS_ERR_INVALID_VAL, "Sample buffer is nullptr"); 118da853ecaSopenharmony_ci 119da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sample->GetSize() > 0, AVCS_ERR_INVALID_VAL, "Sample size must be greater than 0"); 120da853ecaSopenharmony_ci 121da853ecaSopenharmony_ci std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer( 122da853ecaSopenharmony_ci sample->GetBase(), sample->GetSize(), sample->GetSize()); 123da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(buffer != nullptr && buffer->memory_ != nullptr, AVCS_ERR_INVALID_VAL, 124da853ecaSopenharmony_ci "Buffer is nullptr"); 125da853ecaSopenharmony_ci Status ret = mediaDemuxer_->ReadSample(trackIndex, buffer); 126da853ecaSopenharmony_ci 127da853ecaSopenharmony_ci info.presentationTimeUs = buffer->pts_; 128da853ecaSopenharmony_ci info.size = buffer->memory_->GetSize(); 129da853ecaSopenharmony_ci info.offset = 0; 130da853ecaSopenharmony_ci flag = buffer->flag_; 131da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(ret); 132da853ecaSopenharmony_ci} 133da853ecaSopenharmony_ci 134da853ecaSopenharmony_ciint32_t AVDemuxerImpl::ReadSample(uint32_t trackIndex, std::shared_ptr<AVSharedMemory> sample, 135da853ecaSopenharmony_ci AVCodecBufferInfo &info, AVCodecBufferFlag &flag) 136da853ecaSopenharmony_ci{ 137da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 138da853ecaSopenharmony_ci 139da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(sample != nullptr, AVCS_ERR_INVALID_VAL, "Sample buffer is nullptr"); 140da853ecaSopenharmony_ci std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer( 141da853ecaSopenharmony_ci sample->GetBase(), sample->GetSize(), sample->GetSize()); 142da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(buffer != nullptr && buffer->memory_ != nullptr, AVCS_ERR_INVALID_VAL, 143da853ecaSopenharmony_ci "Buffer is nullptr"); 144da853ecaSopenharmony_ci 145da853ecaSopenharmony_ci int32_t ret = ReadSampleBuffer(trackIndex, buffer); 146da853ecaSopenharmony_ci info.presentationTimeUs = buffer->pts_; 147da853ecaSopenharmony_ci info.size = buffer->memory_->GetSize(); 148da853ecaSopenharmony_ci info.offset = 0; 149da853ecaSopenharmony_ci 150da853ecaSopenharmony_ci AVBufferFlag innerFlag = AVBufferFlag::NONE; 151da853ecaSopenharmony_ci if (buffer->flag_ & (uint32_t)(AVBufferFlag::SYNC_FRAME)) { 152da853ecaSopenharmony_ci innerFlag = AVBufferFlag::SYNC_FRAME; 153da853ecaSopenharmony_ci } else if (buffer->flag_ & (uint32_t)(AVBufferFlag::EOS)) { 154da853ecaSopenharmony_ci innerFlag = AVBufferFlag::EOS; 155da853ecaSopenharmony_ci } 156da853ecaSopenharmony_ci flag = static_cast<AVCodecBufferFlag>(innerFlag); 157da853ecaSopenharmony_ci return ret; 158da853ecaSopenharmony_ci} 159da853ecaSopenharmony_ci 160da853ecaSopenharmony_ciint32_t AVDemuxerImpl::SeekToTime(int64_t millisecond, SeekMode mode) 161da853ecaSopenharmony_ci{ 162da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 163da853ecaSopenharmony_ci 164da853ecaSopenharmony_ci AVCODEC_LOGD("Seek to time: millisecond=%{public}" PRId64 "; mode=%{public}d", millisecond, mode); 165da853ecaSopenharmony_ci 166da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 167da853ecaSopenharmony_ci 168da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(millisecond >= 0, AVCS_ERR_INVALID_VAL, "Millisecond is negative"); 169da853ecaSopenharmony_ci 170da853ecaSopenharmony_ci int64_t realTime = 0; 171da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->SeekTo(millisecond, mode, realTime)); 172da853ecaSopenharmony_ci} 173da853ecaSopenharmony_ci 174da853ecaSopenharmony_ciint32_t AVDemuxerImpl::SetCallback(const std::shared_ptr<AVDemuxerCallback> &callback) 175da853ecaSopenharmony_ci{ 176da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 177da853ecaSopenharmony_ci AVCODEC_LOGD("AVDemuxer::SetCallback"); 178da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 179da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Callback is nullptr"); 180da853ecaSopenharmony_ci mediaDemuxer_->SetDrmCallback(callback); 181da853ecaSopenharmony_ci return AVCS_ERR_OK; 182da853ecaSopenharmony_ci} 183da853ecaSopenharmony_ci 184da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetMediaKeySystemInfo(std::multimap<std::string, std::vector<uint8_t>> &infos) 185da853ecaSopenharmony_ci{ 186da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 187da853ecaSopenharmony_ci AVCODEC_LOGD("AVDemuxer::GetMediaKeySystemInfo"); 188da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 189da853ecaSopenharmony_ci mediaDemuxer_->GetMediaKeySystemInfo(infos); 190da853ecaSopenharmony_ci return AVCS_ERR_OK; 191da853ecaSopenharmony_ci} 192da853ecaSopenharmony_ci 193da853ecaSopenharmony_ciint32_t AVDemuxerImpl::StartReferenceParser(int64_t startTimeMs) 194da853ecaSopenharmony_ci{ 195da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 196da853ecaSopenharmony_ci AVCODEC_LOGD("AVDemuxer::StartReferenceParser"); 197da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 198da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->StartReferenceParser(startTimeMs)); 199da853ecaSopenharmony_ci} 200da853ecaSopenharmony_ci 201da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample, FrameLayerInfo &frameLayerInfo) 202da853ecaSopenharmony_ci{ 203da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 204da853ecaSopenharmony_ci AVCODEC_LOGD("AVDemuxer::GetFrameLayerInfo"); 205da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 206da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->GetFrameLayerInfo(videoSample, frameLayerInfo)); 207da853ecaSopenharmony_ci} 208da853ecaSopenharmony_ci 209da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo) 210da853ecaSopenharmony_ci{ 211da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 212da853ecaSopenharmony_ci AVCODEC_LOGD("AVDemuxer::GetGopLayerInfo"); 213da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 214da853ecaSopenharmony_ci return StatusToAVCodecServiceErrCode(mediaDemuxer_->GetGopLayerInfo(gopId, gopLayerInfo)); 215da853ecaSopenharmony_ci} 216da853ecaSopenharmony_ci 217da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex, 218da853ecaSopenharmony_ci const uint64_t relativePresentationTimeUs, uint32_t &index) 219da853ecaSopenharmony_ci{ 220da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 221da853ecaSopenharmony_ci AVCODEC_LOGD("GetIndexByRelativePresentationTimeUs"); 222da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 223da853ecaSopenharmony_ci int32_t ret = StatusToAVCodecServiceErrCode(mediaDemuxer_->GetIndexByRelativePresentationTimeUs(trackIndex, 224da853ecaSopenharmony_ci relativePresentationTimeUs, index)); 225da853ecaSopenharmony_ci return ret; 226da853ecaSopenharmony_ci} 227da853ecaSopenharmony_ci 228da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex, 229da853ecaSopenharmony_ci const uint32_t index, uint64_t &relativePresentationTimeUs) 230da853ecaSopenharmony_ci{ 231da853ecaSopenharmony_ci AVCODEC_SYNC_TRACE; 232da853ecaSopenharmony_ci AVCODEC_LOGD("GetRelativePresentationTimeUsByIndex"); 233da853ecaSopenharmony_ci CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist"); 234da853ecaSopenharmony_ci int32_t ret = StatusToAVCodecServiceErrCode(mediaDemuxer_->GetRelativePresentationTimeUsByIndex(trackIndex, 235da853ecaSopenharmony_ci index, relativePresentationTimeUs)); 236da853ecaSopenharmony_ci return ret; 237da853ecaSopenharmony_ci} 238da853ecaSopenharmony_ci} // namespace MediaAVCodec 239da853ecaSopenharmony_ci} // namespace OHOS