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