已合并
[新需求]: 自研MP4性能优化-插件-优化cachequeue,取消map和多余mutex,fix fastinit meta解析问题,264 nalSize解析边界问题 #9356
杨俊晖创建于 11 天前
[新需求]: 自研MP4性能优化-插件-优化cachequeue,取消map和多余mutex,fix fastinit meta解析问题,264 nalSize解析边界问题 #9356
已合并
共 16 个文件变更+433-187
| @@ -581,7 +581,7 @@ bool AvcParserImpl::ParseNalUnits(std::vector<NalUnitInfo> &nalUnits, const uint | |||
| 581 | if (nalSize == 0) { | 581 | if (nalSize == 0) { |
| 582 | continue; | 582 | continue; |
| 583 | } | 583 | } |
| 584 | - if (nalSize < 0x02 || nalSize > MAX_RBSP_SKIP_BYTES || | 584 | + if (nalSize < 0x01 || nalSize > MAX_RBSP_SKIP_BYTES || |
| 585 | static_cast<int64_t>(nalSize) > bufEnd - buf) { | 585 | static_cast<int64_t>(nalSize) > bufEnd - buf) { |
| 586 | return false; | 586 | return false; |
| 587 | } | 587 | } |
| @@ -43,33 +43,6 @@ struct SamplePacket { | |||
| 43 | } // namespace Ffmpeg | 43 | } // namespace Ffmpeg |
| 44 | 44 | ||
| 45 | 45 | ||
| 46 | -namespace MPEG4 { | ||
| 47 | -struct Sample { | ||
| 48 | - enum SampleFlag : uint32_t { | ||
| 49 | - NONE = 0, | ||
| 50 | - EOS = 1 << 0, | ||
| 51 | - SYNC_FRAME = 1 << 1, | ||
| 52 | - DISCARD = 1 << 4, | ||
| 53 | - }; | ||
| 54 | - int64_t pts; | ||
| 55 | - int64_t dts; | ||
| 56 | - int64_t duration; | ||
| 57 | - uint32_t flag; | ||
| 58 | - int32_t size; | ||
| 59 | - std::vector<uint8_t> skipSamplesInfo; | ||
| 60 | - std::unique_ptr<uint8_t[]> data; | ||
| 61 | -}; | ||
| 62 | - | ||
| 63 | -struct MPEG4Sample { | ||
| 64 | - int32_t offset = 0; | ||
| 65 | - std::shared_ptr<Sample> sample = nullptr; | ||
| 66 | - bool isAnnexb = false; | ||
| 67 | - bool isVttc = false; | ||
| 68 | - uint32_t queueIndex = 0; | ||
| 69 | - uint32_t sampleIndex = 0; | ||
| 70 | -}; | ||
| 71 | -} // namespace MPEG4 | ||
| 72 | - | ||
| 73 | template<typename T> | 46 | template<typename T> |
| 74 | struct BlockTraits { | 47 | struct BlockTraits { |
| 75 | static uint32_t GetDataSize(const std::shared_ptr<T>& block); | 48 | static uint32_t GetDataSize(const std::shared_ptr<T>& block); |
| @@ -102,22 +75,6 @@ struct BlockTraits<Ffmpeg::SamplePacket> { | |||
| 102 | }; | 75 | }; |
| 103 | 76 | ||
| 104 | 77 | ||
| 105 | -// 为MPEG4Sample特化 | ||
| 106 | -template<> | ||
| 107 | -struct BlockTraits<MPEG4::MPEG4Sample> { | ||
| 108 | - static uint32_t GetDataSize(const std::shared_ptr<MPEG4::MPEG4Sample>& block) | ||
| 109 | - { | ||
| 110 | - return block->sample != nullptr ? static_cast<uint32_t>(block->sample->size) : 0; | ||
| 111 | - } | ||
| 112 | - | ||
| 113 | - static void UpdateMaxPts(const std::shared_ptr<MPEG4::MPEG4Sample>& block, int64_t& maxPts) | ||
| 114 | - { | ||
| 115 | - if (block->sample != nullptr && block->sample->pts > maxPts) { | ||
| 116 | - maxPts = block->sample->pts; | ||
| 117 | - } | ||
| 118 | - } | ||
| 119 | -}; | ||
| 120 | - | ||
| 121 | template <typename T> | 78 | template <typename T> |
| 122 | class BlockQueuePool { | 79 | class BlockQueuePool { |
| 123 | public: | 80 | public: |
| @@ -563,7 +520,6 @@ Status BlockQueuePool<T>::GetLastPTSByTrackId(uint32_t trackIndex, int64_t& maxP | |||
| 563 | return Status::ERROR_NOT_EXISTED; | 520 | return Status::ERROR_NOT_EXISTED; |
| 564 | } | 521 | } |
| 565 | 522 | ||
| 566 | -using Mpeg4BlockQueuePool = BlockQueuePool<MPEG4::MPEG4Sample>; | ||
| 567 | 523 | ||
| 568 | using FfmpegBlockQueuePool = BlockQueuePool<Ffmpeg::SamplePacket>; | 524 | using FfmpegBlockQueuePool = BlockQueuePool<Ffmpeg::SamplePacket>; |
| 569 | 525 | ||
| @@ -258,6 +258,7 @@ bool MultiStreamParserManager::ConvertExtraDataToAnnexb(uint32_t trackId, uint8_ | |||
| 258 | bool MultiStreamParserManager::ConvertPacketToAnnexb( | 258 | bool MultiStreamParserManager::ConvertPacketToAnnexb( |
| 259 | uint32_t trackId, uint8_t **hvccPacket, int32_t &hvccPacketSize, const PacketConvertInfo &packetInfo) | 259 | uint32_t trackId, uint8_t **hvccPacket, int32_t &hvccPacketSize, const PacketConvertInfo &packetInfo) |
| 260 | { | 260 | { |
| 261 | + FALSE_RETURN_V_MSG_W(hvccPacket != nullptr && hvccPacketSize > 0, false, "Packet is invalid"); | ||
| 261 | FALSE_RETURN_V_MSG_E(ParserIsInited(trackId), false, "Stream parser is invalid"); | 262 | FALSE_RETURN_V_MSG_E(ParserIsInited(trackId), false, "Stream parser is invalid"); |
| 262 | return streamMap_[trackId].parser->ConvertPacketToAnnexb(hvccPacket, hvccPacketSize, packetInfo.sideData, | 263 | return streamMap_[trackId].parser->ConvertPacketToAnnexb(hvccPacket, hvccPacketSize, packetInfo.sideData, |
| 263 | packetInfo.sideDataSize, packetInfo.isExtradata); | 264 | packetInfo.sideDataSize, packetInfo.isExtradata); |
| @@ -266,30 +267,31 @@ bool MultiStreamParserManager::ConvertPacketToAnnexb( | |||
| 266 | bool MultiStreamParserManager::ConvertPacketToAnnexb( | 267 | bool MultiStreamParserManager::ConvertPacketToAnnexb( |
| 267 | uint32_t trackId, const PacketConvertToBufferInfo &convertInfo) | 268 | uint32_t trackId, const PacketConvertToBufferInfo &convertInfo) |
| 268 | { | 269 | { |
| 270 | + FALSE_RETURN_V_MSG_W(convertInfo.srcData != nullptr && convertInfo.srcDataSize > 0, false, "Packet is invalid"); | ||
| 269 | FALSE_RETURN_V_MSG_E(ParserIsInited(trackId), false, "Stream parser is invalid"); | 271 | FALSE_RETURN_V_MSG_E(ParserIsInited(trackId), false, "Stream parser is invalid"); |
| 270 | return streamMap_[trackId].parser->ConvertPacketToAnnexb(convertInfo); | 272 | return streamMap_[trackId].parser->ConvertPacketToAnnexb(convertInfo); |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 273 | void MultiStreamParserManager::ParseAnnexbExtraData(uint32_t trackId, const uint8_t *sample, int32_t size) | 275 | void MultiStreamParserManager::ParseAnnexbExtraData(uint32_t trackId, const uint8_t *sample, int32_t size) |
| 274 | { | 276 | { |
| 277 | + FALSE_RETURN_MSG(sample != nullptr && size > 0, "Invalid extra data"); | ||
| 275 | FALSE_RETURN_MSG(ParserIsInited(trackId), "Stream parser is invalid"); | 278 | FALSE_RETURN_MSG(ParserIsInited(trackId), "Stream parser is invalid"); |
| 276 | streamMap_[trackId].parser->ParseAnnexbExtraData(sample, size); | 279 | streamMap_[trackId].parser->ParseAnnexbExtraData(sample, size); |
| 277 | } | 280 | } |
| 278 | 281 | ||
| 279 | -void MultiStreamParserManager::ParseMetadataInfo(uint32_t trackIndex, | 282 | +void MultiStreamParserManager::ParseMetadataInfo(uint32_t trackIndex, HevcParseFormat& parse) |
| 280 | - std::shared_ptr<MultiStreamParserManager> streamParsers, HevcParseFormat& parse) | ||
| 281 | { | 283 | { |
| 282 | - parse.isHdrVivid = streamParsers->IsHdrVivid(trackIndex); | 284 | + parse.isHdrVivid = IsHdrVivid(trackIndex); |
| 283 | - parse.isHdr10Plus = streamParsers->IsHdr10Plus(trackIndex); | 285 | + parse.isHdr10Plus = IsHdr10Plus(trackIndex); |
| 284 | - parse.colorRange = streamParsers->GetColorRange(trackIndex); | 286 | + parse.colorRange = GetColorRange(trackIndex); |
| 285 | - parse.colorPrimaries = streamParsers->GetColorPrimaries(trackIndex); | 287 | + parse.colorPrimaries = GetColorPrimaries(trackIndex); |
| 286 | - parse.colorTransfer = streamParsers->GetColorTransfer(trackIndex); | 288 | + parse.colorTransfer = GetColorTransfer(trackIndex); |
| 287 | - parse.colorMatrixCoeff = streamParsers->GetColorMatrixCoeff(trackIndex); | 289 | + parse.colorMatrixCoeff = GetColorMatrixCoeff(trackIndex); |
| 288 | - parse.profile = streamParsers->GetProfileIdc(trackIndex); | 290 | + parse.profile = GetProfileIdc(trackIndex); |
| 289 | - parse.level = streamParsers->GetLevelIdc(trackIndex); | 291 | + parse.level = GetLevelIdc(trackIndex); |
| 290 | - parse.chromaLocation = streamParsers->GetChromaLocation(trackIndex); | 292 | + parse.chromaLocation = GetChromaLocation(trackIndex); |
| 291 | - parse.picWidInLumaSamples = streamParsers->GetPicWidInLumaSamples(trackIndex); | 293 | + parse.picWidInLumaSamples = GetPicWidInLumaSamples(trackIndex); |
| 292 | - parse.picHetInLumaSamples = streamParsers->GetPicHetInLumaSamples(trackIndex); | 294 | + parse.picHetInLumaSamples = GetPicHetInLumaSamples(trackIndex); |
| 293 | } | 295 | } |
| 294 | } // namespace Plugins | 296 | } // namespace Plugins |
| 295 | } // namespace Media | 297 | } // namespace Media |
| @@ -65,8 +65,7 @@ public: | |||
| 65 | const PacketConvertInfo &packetInfo); | 65 | const PacketConvertInfo &packetInfo); |
| 66 | bool ConvertPacketToAnnexb(uint32_t trackId, const PacketConvertToBufferInfo &convertInfo); | 66 | bool ConvertPacketToAnnexb(uint32_t trackId, const PacketConvertToBufferInfo &convertInfo); |
| 67 | void ParseAnnexbExtraData(uint32_t trackId, const uint8_t *sample, int32_t size); | 67 | void ParseAnnexbExtraData(uint32_t trackId, const uint8_t *sample, int32_t size); |
| 68 | - static void ParseMetadataInfo(uint32_t trackIndex, std::shared_ptr<MultiStreamParserManager> streamParsers, | 68 | + void ParseMetadataInfo(uint32_t trackIndex, HevcParseFormat &parse); |
| 69 | - HevcParseFormat &parse); | ||
| 70 | private: | 69 | private: |
| 71 | static std::mutex mtx_; | 70 | static std::mutex mtx_; |
| 72 | 71 | ||
| @@ -2833,7 +2833,9 @@ Status FFmpegDemuxerPlugin::ParseVideoFirstFramesLimited() | |||
| 2833 | void FFmpegDemuxerPlugin::ParseHEVCMetadataInfo(const AVStream& avStream, Meta& format) | 2833 | void FFmpegDemuxerPlugin::ParseHEVCMetadataInfo(const AVStream& avStream, Meta& format) |
| 2834 | { | 2834 | { |
| 2835 | HevcParseFormat parse; | 2835 | HevcParseFormat parse; |
| 2836 | - MultiStreamParserManager::ParseMetadataInfo(avStream.index, streamParsers_, parse); | 2836 | + if (streamParsers_ != nullptr) { |
| 2837 | + streamParsers_->ParseMetadataInfo(avStream.index, parse); | ||
| 2838 | + } | ||
| 2837 | FFmpegFormatHelper::ParseHevcInfo(*formatContext_, avStream, parse, format); | 2839 | FFmpegFormatHelper::ParseHevcInfo(*formatContext_, avStream, parse, format); |
| 2838 | } | 2840 | } |
| 2839 | 2841 | ||
| @@ -26,6 +26,7 @@ | |||
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | 28 | ||
| 29 | + | ||
| 29 | 30 | ||
| 30 | 31 | ||
| 31 | 32 | ||
| @@ -1387,6 +1388,8 @@ Status MPEG4AtomParser::InitCurrentTrackForTrak() | |||
| 1387 | { | 1388 | { |
| 1388 | auto track = std::make_shared<Track>(); | 1389 | auto track = std::make_shared<Track>(); |
| 1389 | FALSE_RETURN_V_MSG_E(track != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate memory for track"); | 1390 | FALSE_RETURN_V_MSG_E(track != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate memory for track"); |
| 1391 | + track->cache = std::make_shared<SampleCache>(); | ||
| 1392 | + FALSE_RETURN_V_MSG_E(track->cache != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate track cache"); | ||
| 1390 | size_t originalTrackCount = mediaInfo_.tracks.size(); | 1393 | size_t originalTrackCount = mediaInfo_.tracks.size(); |
| 1391 | Meta newTrackMeta; | 1394 | Meta newTrackMeta; |
| 1392 | mediaInfo_.tracks.emplace_back(std::move(newTrackMeta)); | 1395 | mediaInfo_.tracks.emplace_back(std::move(newTrackMeta)); |
| @@ -3655,10 +3658,8 @@ Status MPEG4AtomParser::ParseMoof(const std::shared_ptr<Track>& track, int64_t o | |||
| 3655 | [this](const FragmentEntry& entry) { return entry.moofOffset == moofOffset_; }); | 3658 | [this](const FragmentEntry& entry) { return entry.moofOffset == moofOffset_; }); |
| 3656 | if (it != fragmentEntry_.end()) { | 3659 | if (it != fragmentEntry_.end()) { |
| 3657 | inEntry = true; | 3660 | inEntry = true; |
| 3661 | + FALSE_RETURN_V_NOLOG(!it->hasRead, Status::OK); | ||
| 3658 | fragIndex = static_cast<uint32_t>(std::distance(fragmentEntry_.begin(), it)); | 3662 | fragIndex = static_cast<uint32_t>(std::distance(fragmentEntry_.begin(), it)); |
| 3659 | - if (it->hasRead) { | ||
| 3660 | - return Status::OK; | ||
| 3661 | - } | ||
| 3662 | } | 3663 | } |
| 3663 | } | 3664 | } |
| 3664 | int64_t sidxDts = inEntry ? fragmentEntry_[fragIndex].firstDts : -1; | 3665 | int64_t sidxDts = inEntry ? fragmentEntry_[fragIndex].firstDts : -1; |
| @@ -3840,6 +3841,8 @@ Status MPEG4AtomParser::ParseCover(MPEG4Atom currentAtom, uint32_t dataType, uin | |||
| 3840 | 3841 | ||
| 3841 | auto coverTrack = std::make_shared<Track>(); | 3842 | auto coverTrack = std::make_shared<Track>(); |
| 3842 | FALSE_RETURN_V_MSG_E(coverTrack != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate cover track"); | 3843 | FALSE_RETURN_V_MSG_E(coverTrack != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate cover track"); |
| 3844 | + coverTrack->cache = std::make_shared<SampleCache>(); | ||
| 3845 | + FALSE_RETURN_V_MSG_E(coverTrack->cache != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate cover track cache"); | ||
| 3843 | 3846 | ||
| 3844 | coverTrack->trackIndex = trackCount_; | 3847 | coverTrack->trackIndex = trackCount_; |
| 3845 | coverTrack->codecParms.trackType = VIDEO_TYPE; | 3848 | coverTrack->codecParms.trackType = VIDEO_TYPE; |
| @@ -4434,8 +4437,7 @@ Status MPEG4AtomParser::ParseFrma(MPEG4Atom currentAtom, int32_t depth, ParseCon | |||
| 4434 | lastTrack_->sampleHelper->mimeType_ == MimeType::INVALID_TYPE)) { | 4437 | lastTrack_->sampleHelper->mimeType_ == MimeType::INVALID_TYPE)) { |
| 4435 | std::string mimeType = GetMimeType(originalFormat); | 4438 | std::string mimeType = GetMimeType(originalFormat); |
| 4436 | if (mimeType != MimeType::INVALID_TYPE) { | 4439 | if (mimeType != MimeType::INVALID_TYPE) { |
| 4437 | - lastTrack_->sampleHelper->mimeType_ = mimeType; | 4440 | + SetMime(mimeType); |
| 4438 | - mediaInfo_.tracks[lastTrack_->trackIndex].Set<Tag::MIME_TYPE>(mimeType); | ||
| 4439 | } | 4441 | } |
| 4440 | } | 4442 | } |
| 4441 | return Status::OK; | 4443 | return Status::OK; |
| @@ -5283,10 +5285,6 @@ Status MPEG4AtomParser::MPEG4ParseAtom(int32_t depth, ParseContext* ctx) | |||
| 5283 | FALSE_RETURN_V_MSG_E(atom.dataSize >= 0, Status::ERROR_INVALID_DATA, "Invalid atom data size"); | 5285 | FALSE_RETURN_V_MSG_E(atom.dataSize >= 0, Status::ERROR_INVALID_DATA, "Invalid atom data size"); |
| 5284 | FALSE_RETURN_V_MSG_W(!IsUnsupportedFmp4Atom(atom.type), | 5286 | FALSE_RETURN_V_MSG_W(!IsUnsupportedFmp4Atom(atom.type), |
| 5285 | Status::ERROR_MPEG4_DEMUXER_UNSUPPORTED_FORMAT, "Unsupported file: fmp4"); | 5287 | Status::ERROR_MPEG4_DEMUXER_UNSUPPORTED_FORMAT, "Unsupported file: fmp4"); |
| 5286 | - if (demuxerMode_ == Plugins::DemuxerMode::FAST_INIT && !ShouldParseAtomForFastInit(atom.type)) { | ||
| 5287 | - ctx->offset = atomEndOffset; | ||
| 5288 | - return Status::OK; | ||
| 5289 | - } | ||
| 5290 | // 使用函数指针查找和调用解析函数 | 5288 | // 使用函数指针查找和调用解析函数 |
删除 ShouldParseAtomForFastInit 白名单后,FAST_INIT 模式将解析全部 atom,fastinit 不再“fast”。虽然这能修复 meta 解析遗漏,但属于较粗粒度的改法。建议确认对 fastinit 启动耗时的影响可接受;若影响较大,可改为仅把缺失的 meta 相关 box 加入白名单而非整体移除过滤。 reviewed by agent ![]() ![]() | |||
| 5291 | ParseFunction parseFunc = FindAtomParser(atom, ctx); | 5289 | ParseFunction parseFunc = FindAtomParser(atom, ctx); |
| 5292 | if (parseFunc) { | 5290 | if (parseFunc) { |
| @@ -5300,30 +5298,6 @@ Status MPEG4AtomParser::MPEG4ParseAtom(int32_t depth, ParseContext* ctx) | |||
| 5300 | return ret; | 5298 | return ret; |
| 5301 | } | 5299 | } |
| 5302 | 5300 | ||
| 5303 | -bool MPEG4AtomParser::ShouldParseAtomForFastInit(uint32_t atomType) const | ||
| 5304 | -{ | ||
| 5305 | - static const std::set<uint32_t> fastInitAtoms = { | ||
| 5306 | - // File and track structure. | ||
| 5307 | - FourccType("ftyp"), FourccType("moov"), FourccType("wide"), FourccType("mdat"), | ||
| 5308 | - FourccType("trak"), FourccType("mvhd"), FourccType("tkhd"), FourccType("edts"), | ||
| 5309 | - FourccType("elst"), FourccType("mdia"), FourccType("mdhd"), FourccType("hdlr"), | ||
| 5310 | - FourccType("minf"), FourccType("stbl"), FourccType("stsd"), | ||
| 5311 | - // Codec configuration and playback-related track attributes. | ||
| 5312 | - FourccType("avcC"), FourccType("hvcC"), FourccType("vvcC"), FourccType("esds"), | ||
| 5313 | - FourccType("glbl"), FourccType("wave"), FourccType("pasp"), FourccType("chan"), | ||
| 5314 | - FourccType("colr"), FourccType("aclr"), FourccType("clli"), FourccType("mdcv"), | ||
| 5315 | - // Sample location, size and timing tables. | ||
| 5316 | - FourccType("stts"), FourccType("stss"), FourccType("ctts"), FourccType("stsc"), | ||
| 5317 | - FourccType("stsz"), FourccType("stz2"), FourccType("stco"), FourccType("co64"), | ||
| 5318 | - // Encrypted track and DRM information. | ||
| 5319 | - FourccType("frma"), FourccType("sinf"), FourccType("schm"), FourccType("schi"), | ||
| 5320 | - FourccType("tenc"), FourccType("senc"), FourccType("pssh"), | ||
| 5321 | - // This box is handled by SetHdrTypeInfo instead of a dedicated parser. | ||
| 5322 | - FourccType("cuvv") | ||
| 5323 | - }; | ||
| 5324 | - return fastInitAtoms.count(atomType) != 0; | ||
| 5325 | -} | ||
| 5326 | - | ||
| 5327 | auto MPEG4AtomParser::FindAtomParser(const MPEG4Atom& atom, ParseContext* ctx) -> ParseFunction | 5301 | auto MPEG4AtomParser::FindAtomParser(const MPEG4Atom& atom, ParseContext* ctx) -> ParseFunction |
| 5328 | { | 5302 | { |
| 5329 | // 首先查找静态解析函数表 | 5303 | // 首先查找静态解析函数表 |
| @@ -16,12 +16,14 @@ | |||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | + | ||
| 19 | 20 | ||
| 20 | 21 | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | 24 | ||
| 24 | 25 | ||
| 26 | + | ||
| 25 | 27 | ||
| 26 | 28 | ||
| 27 | 29 | ||
| @@ -111,6 +113,7 @@ public: | |||
| 111 | uint16_t audioSampleEntryBitsPerCodedSample = 0; | 113 | uint16_t audioSampleEntryBitsPerCodedSample = 0; |
| 112 | CodecParams codecParms{}; | 114 | CodecParams codecParms{}; |
| 113 | Mpeg4TrackDrmInfo drmInfo; | 115 | Mpeg4TrackDrmInfo drmInfo; |
| 116 | + std::shared_ptr<SampleCache> cache = nullptr; | ||
| 114 | 117 | ||
| 115 | Track() = default; | 118 | Track() = default; |
| 116 | }; | 119 | }; |
| @@ -147,7 +150,6 @@ public: | |||
| 147 | const std::vector<Mpeg4PsshInfo>& GetPsshList() const; | 150 | const std::vector<Mpeg4PsshInfo>& GetPsshList() const; |
| 148 | 151 | ||
| 149 | private: | 152 | private: |
| 150 | - bool ShouldParseAtomForFastInit(uint32_t atomType) const; | ||
| 151 | std::shared_ptr<Track> firstTrack_; | 153 | std::shared_ptr<Track> firstTrack_; |
| 152 | std::shared_ptr<Track> lastTrack_; | 154 | std::shared_ptr<Track> lastTrack_; |
| 153 | std::shared_ptr<Track> currentTrack_; | 155 | std::shared_ptr<Track> currentTrack_; |
| @@ -1064,8 +1064,7 @@ MPEG4DemuxerPlugin::MPEG4DemuxerPlugin(std::string name) | |||
| 1064 | hasSidxBox_(false), | 1064 | hasSidxBox_(false), |
| 1065 | hasMoofBox_(false), | 1065 | hasMoofBox_(false), |
| 1066 | seekable_(Seekable::SEEKABLE), | 1066 | seekable_(Seekable::SEEKABLE), |
| 1067 | - selectedTrackIds_(), | 1067 | + selectedTrackIds_() |
| 1068 | - cacheQueue_("cacheQueue") | ||
| 1069 | { | 1068 | { |
| 1070 | std::lock_guard<std::shared_mutex> lock(sharedMutex_); | 1069 | std::lock_guard<std::shared_mutex> lock(sharedMutex_); |
| 1071 | MEDIA_LOG_D("In"); | 1070 | MEDIA_LOG_D("In"); |
| @@ -1166,11 +1165,11 @@ void MPEG4DemuxerPlugin::ResetParam() | |||
| 1166 | { | 1165 | { |
| 1167 | ReleaseReadLoop(); | 1166 | ReleaseReadLoop(); |
| 1168 | for (const auto& selectedTrackId : selectedTrackIds_) { | 1167 | for (const auto& selectedTrackId : selectedTrackIds_) { |
| 1169 | - cacheQueue_.RemoveTrackQueue(selectedTrackId); | 1168 | + ClearTrackCache(selectedTrackId); |
| 1170 | } | 1169 | } |
| 1171 | - // Remove cacheQueue for all video and audio tracks | 1170 | + // Clear cache for all video and audio tracks. |
| 1172 | for (const auto& avTrackId: avTrackIds_) { | 1171 | for (const auto& avTrackId: avTrackIds_) { |
| 1173 | - cacheQueue_.RemoveTrackQueue(avTrackId); | 1172 | + ClearTrackCache(avTrackId); |
| 1174 | } | 1173 | } |
| 1175 | firstTrack_.reset(); | 1174 | firstTrack_.reset(); |
| 1176 | lastTrack_.reset(); | 1175 | lastTrack_.reset(); |
| @@ -1218,18 +1217,16 @@ Status MPEG4DemuxerPlugin::SeekToKeyFrame(int32_t trackId, int64_t seekTime, | |||
| 1218 | 1217 | ||
| 1219 | Status MPEG4DemuxerPlugin::Flush() | 1218 | Status MPEG4DemuxerPlugin::Flush() |
| 1220 | { | 1219 | { |
| 1221 | - Status ret = Status::OK; | ||
| 1222 | std::lock_guard<std::shared_mutex> lock(sharedMutex_); | 1220 | std::lock_guard<std::shared_mutex> lock(sharedMutex_); |
| 1223 | MEDIA_LOG_I("In"); | 1221 | MEDIA_LOG_I("In"); |
| 1224 | ReleaseReadLoop(); | 1222 | ReleaseReadLoop(); |
| 1225 | for (const auto& selectedTrackId : selectedTrackIds_) { | 1223 | for (const auto& selectedTrackId : selectedTrackIds_) { |
| 1226 | - ret = cacheQueue_.RemoveTrackQueue(selectedTrackId); | 1224 | + ClearTrackCache(selectedTrackId); |
| 1227 | - ret = cacheQueue_.AddTrackQueue(selectedTrackId); | ||
| 1228 | } | 1225 | } |
| 1229 | cacheSamples_.clear(); | 1226 | cacheSamples_.clear(); |
| 1230 | pendingWebVttSamples_.clear(); | 1227 | pendingWebVttSamples_.clear(); |
| 1231 | readToEnd_ = false; | 1228 | readToEnd_ = false; |
| 1232 | - return ret; | 1229 | + return Status::OK; |
| 1233 | } | 1230 | } |
| 1234 | 1231 | ||
| 1235 | void MPEG4DemuxerPlugin::InitBaseInfoByAtomParser(std::shared_ptr<MPEG4AtomParser> parser) | 1232 | void MPEG4DemuxerPlugin::InitBaseInfoByAtomParser(std::shared_ptr<MPEG4AtomParser> parser) |
| @@ -1428,7 +1425,6 @@ void MPEG4DemuxerPlugin::GetAVTrackIds() | |||
| 1428 | avTrackIds_.emplace_back(track->trackIndex); | 1425 | avTrackIds_.emplace_back(track->trackIndex); |
| 1429 | if (seekable_ == Seekable::UNSEEKABLE) { | 1426 | if (seekable_ == Seekable::UNSEEKABLE) { |
| 1430 | trackMtx_[track->trackIndex] = std::make_shared<std::mutex>(); | 1427 | trackMtx_[track->trackIndex] = std::make_shared<std::mutex>(); |
| 1431 | - cacheQueue_.AddTrackQueue(track->trackIndex); | ||
| 1432 | } | 1428 | } |
| 1433 | } | 1429 | } |
| 1434 | track = track->next; | 1430 | track = track->next; |
| @@ -1447,6 +1443,7 @@ Status MPEG4DemuxerPlugin::ParseAVFirstFrames() | |||
| 1447 | FALSE_RETURN_V_MSG_E(!isInterruptNeeded_.load(), Status::ERROR_WRONG_STATE, "ParseAVFirstFrames interrupt"); | 1443 | FALSE_RETURN_V_MSG_E(!isInterruptNeeded_.load(), Status::ERROR_WRONG_STATE, "ParseAVFirstFrames interrupt"); |
| 1448 | auto mpeg4Sample = std::make_shared<MPEG4Sample>(); | 1444 | auto mpeg4Sample = std::make_shared<MPEG4Sample>(); |
| 1449 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate mpeg4Sample"); | 1445 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate mpeg4Sample"); |
| 1446 | + mpeg4Sample->trackId = avTrackId; | ||
| 1450 | 1447 | ||
| 1451 | // 使用GetSampleBySeekableStatus获取首帧,传入空AVBuffer | 1448 | // 使用GetSampleBySeekableStatus获取首帧,传入空AVBuffer |
| 1452 | Status ret = GetSampleBySeekableStatus(avTrackId, mpeg4Sample, nullptr); | 1449 | Status ret = GetSampleBySeekableStatus(avTrackId, mpeg4Sample, nullptr); |
| @@ -1768,7 +1765,9 @@ void MPEG4DemuxerPlugin::ParseHEVCMetadataInfo(const MPEG4AtomParser::Track& tra | |||
| 1768 | { | 1765 | { |
| 1769 | HevcParseFormat parse; | 1766 | HevcParseFormat parse; |
| 1770 | uint32_t trackIndex = track.trackIndex; | 1767 | uint32_t trackIndex = track.trackIndex; |
| 1771 | - MultiStreamParserManager::ParseMetadataInfo(trackIndex, streamParsers_, parse); | 1768 | + if (streamParsers_ != nullptr) { |
| 1769 | + streamParsers_->ParseMetadataInfo(trackIndex, parse); | ||
| 1770 | + } | ||
| 1772 | if (parse.isHdrVivid) { | 1771 | if (parse.isHdrVivid) { |
| 1773 | format.Set<Tag::VIDEO_IS_HDR_VIVID>(true); | 1772 | format.Set<Tag::VIDEO_IS_HDR_VIVID>(true); |
| 1774 | } | 1773 | } |
| @@ -1827,7 +1826,7 @@ Status MPEG4DemuxerPlugin::SelectTrack(uint32_t trackId) | |||
| 1827 | if (!TrackIsSelected(trackId)) { | 1826 | if (!TrackIsSelected(trackId)) { |
| 1828 | selectedTrackIds_.emplace_back(trackId); | 1827 | selectedTrackIds_.emplace_back(trackId); |
| 1829 | trackMtx_[trackId] = std::make_shared<std::mutex>(); | 1828 | trackMtx_[trackId] = std::make_shared<std::mutex>(); |
| 1830 | - return cacheQueue_.AddTrackQueue(trackId); | 1829 | + return Status::OK; |
| 1831 | } else { | 1830 | } else { |
| 1832 | MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " has been selected", trackId); | 1831 | MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " has been selected", trackId); |
| 1833 | } | 1832 | } |
| @@ -1852,7 +1851,8 @@ Status MPEG4DemuxerPlugin::UnselectTrack(uint32_t trackId) | |||
| 1852 | selectedTrackIds_.erase(index); | 1851 | selectedTrackIds_.erase(index); |
| 1853 | trackMtx_.erase(trackId); | 1852 | trackMtx_.erase(trackId); |
| 1854 | pendingWebVttSamples_.erase(trackId); | 1853 | pendingWebVttSamples_.erase(trackId); |
| 1855 | - return cacheQueue_.RemoveTrackQueue(trackId); | 1854 | + ClearTrackCache(trackId); |
| 1855 | + return Status::OK; | ||
| 1856 | } else { | 1856 | } else { |
| 1857 | MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " is not in selected list", trackId); | 1857 | MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " is not in selected list", trackId); |
| 1858 | } | 1858 | } |
| @@ -2281,8 +2281,7 @@ Status MPEG4DemuxerPlugin::SeekTo(int32_t trackId, int64_t seekTime, SeekMode mo | |||
| 2281 | Status denseRet = EnsureSelectedTracksDense(); | 2281 | Status denseRet = EnsureSelectedTracksDense(); |
| 2282 | FALSE_RETURN_V_MSG_E(denseRet == Status::OK, denseRet, "Build dense sample index failed"); | 2282 | FALSE_RETURN_V_MSG_E(denseRet == Status::OK, denseRet, "Build dense sample index failed"); |
| 2283 | for (const auto& selectedTrackId : selectedTrackIds_) { | 2283 | for (const auto& selectedTrackId : selectedTrackIds_) { |
| 2284 | - cacheQueue_.RemoveTrackQueue(selectedTrackId); | 2284 | + ClearTrackCache(selectedTrackId); |
| 2285 | - cacheQueue_.AddTrackQueue(selectedTrackId); | ||
| 2286 | } | 2285 | } |
| 2287 | cacheSamples_.clear(); | 2286 | cacheSamples_.clear(); |
| 2288 | pendingWebVttSamples_.clear(); | 2287 | pendingWebVttSamples_.clear(); |
| @@ -2535,6 +2534,88 @@ Status MPEG4DemuxerPlugin::ReadSampleData( | |||
| 2535 | return ReadSampleData(sample, sampleInfo); | 2534 | return ReadSampleData(sample, sampleInfo); |
| 2536 | } | 2535 | } |
| 2537 | 2536 | ||
| 2537 | +void MPEG4DemuxerPlugin::ClearTrackCache(uint32_t trackId) | ||
| 2538 | +{ | ||
| 2539 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2540 | + if (track != nullptr && track->cache != nullptr) { | ||
| 2541 | + track->cache->Clear(); | ||
| 2542 | + } | ||
| 2543 | +} | ||
| 2544 | + | ||
| 2545 | +bool MPEG4DemuxerPlugin::HasTrackCache(uint32_t trackId) | ||
| 2546 | +{ | ||
| 2547 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2548 | + return HasTrackCache(track); | ||
| 2549 | +} | ||
| 2550 | + | ||
| 2551 | +bool MPEG4DemuxerPlugin::HasTrackCache(const std::shared_ptr<MPEG4AtomParser::Track>& track) const | ||
| 2552 | +{ | ||
| 2553 | + return track != nullptr && track->cache != nullptr && track->cache->HasCache(); | ||
| 2554 | +} | ||
| 2555 | + | ||
| 2556 | +uint32_t MPEG4DemuxerPlugin::GetTrackCacheDataSize(uint32_t trackId) | ||
| 2557 | +{ | ||
| 2558 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2559 | + return track != nullptr && track->cache != nullptr ? track->cache->GetCacheDataSize() : 0; | ||
| 2560 | +} | ||
| 2561 | + | ||
| 2562 | +uint32_t MPEG4DemuxerPlugin::GetTrackCacheFrameCount(uint32_t trackId) | ||
| 2563 | +{ | ||
| 2564 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2565 | + return track != nullptr && track->cache != nullptr ? track->cache->GetCacheFrameCount() : 0; | ||
| 2566 | +} | ||
| 2567 | + | ||
| 2568 | +bool MPEG4DemuxerPlugin::ResetTrackCacheInfo(const std::shared_ptr<MPEG4Sample>& mpeg4Sample) | ||
| 2569 | +{ | ||
| 2570 | + FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, false, "MPEG4 sample is nullptr"); | ||
| 2571 | + auto track = FindTrackById(static_cast<int32_t>(mpeg4Sample->trackId)); | ||
| 2572 | + return track != nullptr && track->cache != nullptr && track->cache->ResetInfo(mpeg4Sample); | ||
| 2573 | +} | ||
| 2574 | + | ||
| 2575 | +bool MPEG4DemuxerPlugin::SetTrackCacheInfo(const std::shared_ptr<MPEG4Sample>& mpeg4Sample) | ||
| 2576 | +{ | ||
| 2577 | + FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, false, "MPEG4 sample is nullptr"); | ||
| 2578 | + auto track = FindTrackById(static_cast<int32_t>(mpeg4Sample->trackId)); | ||
| 2579 | + return track != nullptr && track->cache != nullptr && track->cache->SetInfo(mpeg4Sample); | ||
| 2580 | +} | ||
| 2581 | + | ||
| 2582 | +bool MPEG4DemuxerPlugin::PushTrackCache(uint32_t trackId, const std::shared_ptr<MPEG4Sample>& mpeg4Sample) | ||
| 2583 | +{ | ||
| 2584 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2585 | + if (track == nullptr || track->cache == nullptr) { | ||
| 2586 | + return false; | ||
| 2587 | + } | ||
| 2588 | + return track->cache->Push(mpeg4Sample); | ||
| 2589 | +} | ||
| 2590 | + | ||
| 2591 | +std::shared_ptr<MPEG4Sample> MPEG4DemuxerPlugin::PopTrackCache(uint32_t trackId) | ||
| 2592 | +{ | ||
| 2593 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2594 | + return track != nullptr && track->cache != nullptr ? track->cache->Pop() : nullptr; | ||
| 2595 | +} | ||
| 2596 | + | ||
| 2597 | +std::shared_ptr<MPEG4Sample> MPEG4DemuxerPlugin::FrontTrackCache(uint32_t trackId) | ||
| 2598 | +{ | ||
| 2599 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2600 | + return track != nullptr && track->cache != nullptr ? track->cache->Front() : nullptr; | ||
| 2601 | +} | ||
| 2602 | + | ||
| 2603 | +std::shared_ptr<MPEG4Sample> MPEG4DemuxerPlugin::BackTrackCache(uint32_t trackId) | ||
| 2604 | +{ | ||
| 2605 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2606 | + return track != nullptr && track->cache != nullptr ? track->cache->Back() : nullptr; | ||
| 2607 | +} | ||
| 2608 | + | ||
| 2609 | +Status MPEG4DemuxerPlugin::GetTrackCacheLastPTS(uint32_t trackId, int64_t& maxPts) | ||
| 2610 | +{ | ||
| 2611 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); | ||
| 2612 | + if (track == nullptr || track->cache == nullptr) { | ||
| 2613 | + maxPts = INT64_MIN; | ||
| 2614 | + return Status::ERROR_NOT_EXISTED; | ||
| 2615 | + } | ||
| 2616 | + return track->cache->GetLastPTS(maxPts); | ||
| 2617 | +} | ||
| 2618 | + | ||
| 2538 | Status MPEG4DemuxerPlugin::AddSampleToCacheQueue(std::shared_ptr<Sample> sample, | 2619 | Status MPEG4DemuxerPlugin::AddSampleToCacheQueue(std::shared_ptr<Sample> sample, |
| 2539 | const uint32_t trackId, uint32_t sampleIndex) | 2620 | const uint32_t trackId, uint32_t sampleIndex) |
| 2540 | { | 2621 | { |
| @@ -2546,15 +2627,16 @@ Status MPEG4DemuxerPlugin::AddSampleToCacheQueue(std::shared_ptr<Sample> sample, | |||
| 2546 | if (cacheSample != nullptr) { | 2627 | if (cacheSample != nullptr) { |
| 2547 | cacheSample->sample = sample; | 2628 | cacheSample->sample = sample; |
| 2548 | cacheSample->offset = 0; | 2629 | cacheSample->offset = 0; |
| 2630 | + cacheSample->trackId = trackId; | ||
| 2549 | if (sampleIndex == UINT32_MAX) { | 2631 | if (sampleIndex == UINT32_MAX) { |
| 2550 | auto track = FindTrackById(static_cast<int32_t>(trackId)); | 2632 | auto track = FindTrackById(static_cast<int32_t>(trackId)); |
| 2551 | cacheSample->sampleIndex = track ? track->currentSampleIndex : 0; | 2633 | cacheSample->sampleIndex = track ? track->currentSampleIndex : 0; |
| 2552 | } else { | 2634 | } else { |
| 2553 | cacheSample->sampleIndex = sampleIndex; | 2635 | cacheSample->sampleIndex = sampleIndex; |
| 2554 | } | 2636 | } |
| 2555 | - cacheQueue_.Push(trackId, cacheSample); | 2637 | + (void)PushTrackCache(trackId, cacheSample); |
(void)PushTrackCache(trackId, cacheSample); 静默丢弃了 Push 失败的返回值。当 track 不存在或 cache 为空(例如某些未走 InitCurrentTrackForTrak/ParseCover 创建缓存的路径)时,sample 会被无声丢弃且无日志。建议至少在失败时 MEDIA_LOG_W 记录 trackId,便于定位丢帧问题。 reviewed by agent ![]() ![]() | |||
| 2556 | ret = CheckCacheDataLimit(trackId); | 2638 | ret = CheckCacheDataLimit(trackId); |
| 2557 | - uint32_t cacheBytes = cacheQueue_.GetCacheDataSize(trackId); | 2639 | + uint32_t cacheBytes = GetTrackCacheDataSize(trackId); |
| 2558 | if (cacheBytes < UINT32_MAX) { | 2640 | if (cacheBytes < UINT32_MAX) { |
| 2559 | MaybeNotifyCachePressure(trackId, cacheBytes); | 2641 | MaybeNotifyCachePressure(trackId, cacheBytes); |
| 2560 | } | 2642 | } |
| @@ -2565,7 +2647,7 @@ Status MPEG4DemuxerPlugin::AddSampleToCacheQueue(std::shared_ptr<Sample> sample, | |||
| 2565 | Status MPEG4DemuxerPlugin::CheckCacheDataLimit(uint32_t trackId) | 2647 | Status MPEG4DemuxerPlugin::CheckCacheDataLimit(uint32_t trackId) |
| 2566 | { | 2648 | { |
| 2567 | if (!outOfLimit_) { | 2649 | if (!outOfLimit_) { |
| 2568 | - auto cacheDataSize = cacheQueue_.GetCacheDataSize(trackId); | 2650 | + auto cacheDataSize = GetTrackCacheDataSize(trackId); |
| 2569 | if (cacheDataSize > cachelimitSize_) { | 2651 | if (cacheDataSize > cachelimitSize_) { |
| 2570 | MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " cache out of limit: " PUBLIC_LOG_U32 "/" PUBLIC_LOG_U32 ", by user " | 2652 | MEDIA_LOG_W("Track " PUBLIC_LOG_U32 " cache out of limit: " PUBLIC_LOG_U32 "/" PUBLIC_LOG_U32 ", by user " |
| 2571 | PUBLIC_LOG_D32, trackId, cacheDataSize, cachelimitSize_, static_cast<int32_t>(setLimitByUser_)); | 2653 | PUBLIC_LOG_D32, trackId, cacheDataSize, cachelimitSize_, static_cast<int32_t>(setLimitByUser_)); |
| @@ -2613,10 +2695,8 @@ Status MPEG4DemuxerPlugin::SetEosSample(std::shared_ptr<AVBuffer> outBuffer) | |||
| 2613 | Status MPEG4DemuxerPlugin::UpdateWebVttCachedSampleDuration(const WebVttReadContext& context, | 2695 | Status MPEG4DemuxerPlugin::UpdateWebVttCachedSampleDuration(const WebVttReadContext& context, |
| 2614 | const std::shared_ptr<MPEG4Sample>& tempSample, uint32_t nextSampleIndex) | 2696 | const std::shared_ptr<MPEG4Sample>& tempSample, uint32_t nextSampleIndex) |
| 2615 | { | 2697 | { |
| 2616 | - if (!cacheQueue_.HasCache(context.trackId)) { | 2698 | + FALSE_RETURN_V_NOLOG(HasTrackCache(context.track), Status::OK); |
| 2617 | - return Status::OK; | 2699 | + std::shared_ptr<MPEG4Sample> cacheSample = BackTrackCache(context.trackId); |
| 2618 | - } | ||
| 2619 | - std::shared_ptr<MPEG4Sample> cacheSample = cacheQueue_.Back(context.trackId); | ||
| 2620 | FALSE_RETURN_V_NOLOG(!(tempSample == nullptr && (cacheSample == nullptr || cacheSample->sample == nullptr)), | 2700 | FALSE_RETURN_V_NOLOG(!(tempSample == nullptr && (cacheSample == nullptr || cacheSample->sample == nullptr)), |
| 2621 | Status::OK); | 2701 | Status::OK); |
| 2622 | FALSE_RETURN_V_MSG_E(cacheSample != nullptr && cacheSample->sample != nullptr, | 2702 | FALSE_RETURN_V_MSG_E(cacheSample != nullptr && cacheSample->sample != nullptr, |
| @@ -2635,6 +2715,8 @@ Status MPEG4DemuxerPlugin::ReadAndCacheWebVttSample(const WebVttReadContext& con | |||
| 2635 | { | 2715 | { |
| 2636 | continueRead = false; | 2716 | continueRead = false; |
| 2637 | std::shared_ptr<MPEG4Sample> tempSample = std::make_shared<MPEG4Sample>(); | 2717 | std::shared_ptr<MPEG4Sample> tempSample = std::make_shared<MPEG4Sample>(); |
| 2718 | + FALSE_RETURN_V_MSG_E(tempSample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate MPEG4Sample"); | ||
| 2719 | + tempSample->trackId = context.trackId; | ||
| 2638 | Status ret = GetSampleBySeekableStatus(context.trackId, tempSample, context.outBuffer); | 2720 | Status ret = GetSampleBySeekableStatus(context.trackId, tempSample, context.outBuffer); |
| 2639 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "GetSampleBySeekableStatus failed"); | 2721 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "GetSampleBySeekableStatus failed"); |
| 2640 | if (context.outBuffer->flag_ & static_cast<uint32_t>(AVBufferFlag::EOS)) { | 2722 | if (context.outBuffer->flag_ & static_cast<uint32_t>(AVBufferFlag::EOS)) { |
| @@ -2653,7 +2735,7 @@ Status MPEG4DemuxerPlugin::ReadAndCacheWebVttSample(const WebVttReadContext& con | |||
| 2653 | ret = UpdateWebVttCachedSampleDuration(context, tempSample, context.track->currentSampleIndex + 1); | 2735 | ret = UpdateWebVttCachedSampleDuration(context, tempSample, context.track->currentSampleIndex + 1); |
| 2654 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Update WebVTT cache duration failed"); | 2736 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Update WebVTT cache duration failed"); |
| 2655 | } | 2737 | } |
| 2656 | - continueRead = tempSample->isVttc || !cacheQueue_.HasCache(context.trackId); | 2738 | + continueRead = tempSample->isVttc || !HasTrackCache(context.track); |
| 2657 | context.track->currentSampleIndex += continueRead ? 1 : 0; | 2739 | context.track->currentSampleIndex += continueRead ? 1 : 0; |
| 2658 | return Status::OK; | 2740 | return Status::OK; |
| 2659 | } | 2741 | } |
| @@ -2743,8 +2825,7 @@ Status MPEG4DemuxerPlugin::GetSampleForWebvtt(uint32_t trackId, | |||
| 2743 | Status ret = ReadAndCacheWebVttSample(context, continueRead); | 2825 | Status ret = ReadAndCacheWebVttSample(context, continueRead); |
| 2744 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Read WebVTT sample failed"); | 2826 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Read WebVTT sample failed"); |
| 2745 | } while (continueRead); | 2827 | } while (continueRead); |
| 2746 | - mpeg4Sample = cacheQueue_.Front(trackId); | 2828 | + mpeg4Sample = PopTrackCache(trackId); |
| 2747 | - cacheQueue_.Pop(trackId); | ||
| 2748 | return Status::OK; | 2829 | return Status::OK; |
| 2749 | } | 2830 | } |
| 2750 | 2831 | ||
| @@ -2770,7 +2851,7 @@ Status MPEG4DemuxerPlugin::GetUnseekableSample( | |||
| 2770 | uint32_t trackId, std::shared_ptr<MPEG4Sample> &mpeg4Sample, std::shared_ptr<AVBuffer> outBuffer) | 2851 | uint32_t trackId, std::shared_ptr<MPEG4Sample> &mpeg4Sample, std::shared_ptr<AVBuffer> outBuffer) |
| 2771 | { | 2852 | { |
| 2772 | Status ret = Status::OK; | 2853 | Status ret = Status::OK; |
| 2773 | - while (!cacheQueue_.HasCache(trackId)) { | 2854 | + while (!HasTrackCache(trackId)) { |
| 2774 | SampleReadInfo sampleInfo; | 2855 | SampleReadInfo sampleInfo; |
| 2775 | ret = GetUnseekableSampleInfo(sampleInfo); | 2856 | ret = GetUnseekableSampleInfo(sampleInfo); |
| 2776 | if (ret == Status::END_OF_STREAM) { | 2857 | if (ret == Status::END_OF_STREAM) { |
| @@ -2793,7 +2874,7 @@ Status MPEG4DemuxerPlugin::GetUnseekableSample( | |||
| 2793 | } | 2874 | } |
| 2794 | } | 2875 | } |
| 2795 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); | 2876 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); |
| 2796 | - mpeg4Sample = cacheQueue_.Front(trackId); | 2877 | + mpeg4Sample = FrontTrackCache(trackId); |
| 2797 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, Status::ERROR_NULL_POINTER, "Cache sample is nullptr"); | 2878 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, Status::ERROR_NULL_POINTER, "Cache sample is nullptr"); |
| 2798 | return Status::OK; | 2879 | return Status::OK; |
| 2799 | } | 2880 | } |
| @@ -2847,13 +2928,13 @@ Status MPEG4DemuxerPlugin::WriteBuffer(uint32_t trackIndex, std::shared_ptr<AVBu | |||
| 2847 | PUBLIC_LOG_U32, outBuffer->pts_, outBuffer->dts_, outBuffer->duration_, trackIndex); | 2928 | PUBLIC_LOG_U32, outBuffer->pts_, outBuffer->dts_, outBuffer->duration_, trackIndex); |
| 2848 | 2929 | ||
| 2849 | CheckResetXPSSendStatus(trackIndex, mpeg4Sample->sample); | 2930 | CheckResetXPSSendStatus(trackIndex, mpeg4Sample->sample); |
| 2850 | - if (cacheQueue_.ResetInfo(mpeg4Sample) == false) { | 2931 | + if (ResetTrackCacheInfo(mpeg4Sample) == false) { |
| 2851 | MEDIA_LOG_D("Reset info failed"); | 2932 | MEDIA_LOG_D("Reset info failed"); |
| 2852 | } | 2933 | } |
| 2853 | int32_t oldSize = mpeg4Sample->sample->size; | 2934 | int32_t oldSize = mpeg4Sample->sample->size; |
| 2854 | Status ret = ConvertSampleToAnnexb(mpeg4Sample, trackIndex); | 2935 | Status ret = ConvertSampleToAnnexb(mpeg4Sample, trackIndex); |
| 2855 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Convert annexb failed"); | 2936 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Convert annexb failed"); |
| 2856 | - if (cacheQueue_.SetInfo(mpeg4Sample) == false) { | 2937 | + if (SetTrackCacheInfo(mpeg4Sample) == false) { |
| 2857 | MEDIA_LOG_D("Set info failed"); | 2938 | MEDIA_LOG_D("Set info failed"); |
| 2858 | } | 2939 | } |
| 2859 | 2940 | ||
| @@ -2916,14 +2997,15 @@ Status MPEG4DemuxerPlugin::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer | |||
| 2916 | auto track = FindTrackById(trackId); | 2997 | auto track = FindTrackById(trackId); |
| 2917 | FALSE_RETURN_V_MSG_E(IsValidTrack(track), Status::ERROR_INVALID_PARAMETER, "Track is invalid"); | 2998 | FALSE_RETURN_V_MSG_E(IsValidTrack(track), Status::ERROR_INVALID_PARAMETER, "Track is invalid"); |
| 2918 | readModeFlags_.fetch_or(ReadModeToFlags(ReadMode::SYNC), std::memory_order_acq_rel); | 2999 | readModeFlags_.fetch_or(ReadModeToFlags(ReadMode::SYNC), std::memory_order_acq_rel); |
| 2919 | - bool useCache = cacheQueue_.HasCache(trackId); | 3000 | + bool useCache = HasTrackCache(track); |
| 2920 | if (!useCache && seekable_ == Seekable::SEEKABLE && !NeedReadPostProcessing(track->sampleHelper->mimeType_) && | 3001 | if (!useCache && seekable_ == Seekable::SEEKABLE && !NeedReadPostProcessing(track->sampleHelper->mimeType_) && |
| 2921 | !track->drmInfo.isEncrypted && outBuffer->memory_->GetCapacity() > 0) { | 3002 | !track->drmInfo.isEncrypted && outBuffer->memory_->GetCapacity() > 0) { |
| 2922 | return GetSeekableSampleDirectly(trackId, outBuffer); | 3003 | return GetSeekableSampleDirectly(trackId, outBuffer); |
| 2923 | } | 3004 | } |
| 2924 | - std::shared_ptr<MPEG4Sample> mpeg4Sample = useCache ? cacheQueue_.Front(trackId) : std::make_shared<MPEG4Sample>(); | 3005 | + std::shared_ptr<MPEG4Sample> mpeg4Sample = useCache ? FrontTrackCache(trackId) : std::make_shared<MPEG4Sample>(); |
| 2925 | FALSE_RETURN_V_MSG_E( | 3006 | FALSE_RETURN_V_MSG_E( |
| 2926 | mpeg4Sample != nullptr, Status::ERROR_NO_MEMORY, "Get mpeg4Sample failed[%{public}d]", useCache); | 3007 | mpeg4Sample != nullptr, Status::ERROR_NO_MEMORY, "Get mpeg4Sample failed[%{public}d]", useCache); |
| 3008 | + mpeg4Sample->trackId = trackId; | ||
| 2927 | Status ret = Status::OK; | 3009 | Status ret = Status::OK; |
| 2928 | if (!useCache) { | 3010 | if (!useCache) { |
| 2929 | if (track->sampleHelper->mimeType_ == MimeType::TEXT_WEBVTT) { | 3011 | if (track->sampleHelper->mimeType_ == MimeType::TEXT_WEBVTT) { |
| @@ -2939,7 +3021,7 @@ Status MPEG4DemuxerPlugin::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer | |||
| 2939 | FALSE_RETURN_V_NOLOG(ret != Status::ERROR_NOT_ENOUGH_DATA, Status::OK); | 3021 | FALSE_RETURN_V_NOLOG(ret != Status::ERROR_NOT_ENOUGH_DATA, Status::OK); |
| 2940 | FALSE_RETURN_V_NOLOG(ret == Status::OK, ret); | 3022 | FALSE_RETURN_V_NOLOG(ret == Status::OK, ret); |
| 2941 | if (seekable_ == Seekable::UNSEEKABLE || useCache) { | 3023 | if (seekable_ == Seekable::UNSEEKABLE || useCache) { |
| 2942 | - cacheQueue_.Pop(trackId); | 3024 | + PopTrackCache(trackId); |
| 2943 | } else { | 3025 | } else { |
| 2944 | cacheSamples_.erase(trackId); | 3026 | cacheSamples_.erase(trackId); |
| 2945 | ++track->currentSampleIndex; | 3027 | ++track->currentSampleIndex; |
| @@ -2962,8 +3044,8 @@ Status MPEG4DemuxerPlugin::GetNextSampleSize(uint32_t trackId, int32_t &sampleSi | |||
| 2962 | auto sample = std::make_shared<Sample>(); | 3044 | auto sample = std::make_shared<Sample>(); |
| 2963 | FALSE_RETURN_V_MSG_E(sample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate sample"); | 3045 | FALSE_RETURN_V_MSG_E(sample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate sample"); |
| 2964 | uint32_t sampleTrackId = trackId; | 3046 | uint32_t sampleTrackId = trackId; |
| 2965 | - if (cacheQueue_.HasCache(trackId)) { | 3047 | + if (HasTrackCache(trackId)) { |
| 2966 | - std::shared_ptr<MPEG4Sample> mpeg4Sample = cacheQueue_.Front(trackId); | 3048 | + std::shared_ptr<MPEG4Sample> mpeg4Sample = FrontTrackCache(trackId); |
| 2967 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, | 3049 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, |
| 2968 | Status::ERROR_NULL_POINTER, "Cache sample is nullptr"); | 3050 | Status::ERROR_NULL_POINTER, "Cache sample is nullptr"); |
| 2969 | sample = mpeg4Sample->sample; | 3051 | sample = mpeg4Sample->sample; |
| @@ -3001,7 +3083,7 @@ Status MPEG4DemuxerPlugin::GetCurrentCacheSize(uint32_t trackId, uint32_t& size) | |||
| 3001 | FALSE_RETURN_V_MSG_E(inited_, Status::ERROR_NULL_POINTER, "Plugin has not been initialized"); | 3083 | FALSE_RETURN_V_MSG_E(inited_, Status::ERROR_NULL_POINTER, "Plugin has not been initialized"); |
| 3002 | FALSE_RETURN_V_MSG_E(!selectedTrackIds_.empty(), Status::ERROR_INVALID_OPERATION, "No track has been selected"); | 3084 | FALSE_RETURN_V_MSG_E(!selectedTrackIds_.empty(), Status::ERROR_INVALID_OPERATION, "No track has been selected"); |
| 3003 | FALSE_RETURN_V_MSG_E(TrackIsSelected(trackId), Status::ERROR_INVALID_PARAMETER, "Track has not been selected"); | 3085 | FALSE_RETURN_V_MSG_E(TrackIsSelected(trackId), Status::ERROR_INVALID_PARAMETER, "Track has not been selected"); |
| 3004 | - uint32_t dataSize = cacheQueue_.GetCacheDataSize(trackId); | 3086 | + uint32_t dataSize = GetTrackCacheDataSize(trackId); |
| 3005 | FALSE_RETURN_V_MSG_E(dataSize < UINT32_MAX, Status::ERROR_WRONG_STATE, "CacheSize is invalid"); | 3087 | FALSE_RETURN_V_MSG_E(dataSize < UINT32_MAX, Status::ERROR_WRONG_STATE, "CacheSize is invalid"); |
| 3006 | size = dataSize; | 3088 | size = dataSize; |
| 3007 | return Status::OK; | 3089 | return Status::OK; |
| @@ -3014,7 +3096,7 @@ Status MPEG4DemuxerPlugin::GetCurrentCacheFrameCount(uint32_t trackId, uint32_t& | |||
| 3014 | FALSE_RETURN_V_MSG_E(!selectedTrackIds_.empty(), Status::ERROR_INVALID_OPERATION, "No track has been selected"); | 3096 | FALSE_RETURN_V_MSG_E(!selectedTrackIds_.empty(), Status::ERROR_INVALID_OPERATION, "No track has been selected"); |
| 3015 | FALSE_RETURN_V_MSG_E(TrackIsSelected(trackId), Status::ERROR_INVALID_PARAMETER, "Track has not been selected"); | 3097 | FALSE_RETURN_V_MSG_E(TrackIsSelected(trackId), Status::ERROR_INVALID_PARAMETER, "Track has not been selected"); |
| 3016 | 3098 | ||
| 3017 | - uint32_t cachedFrames = cacheQueue_.GetCacheFrameCount(trackId); // 返回对应缓存的samplePacket个数 | 3099 | + uint32_t cachedFrames = GetTrackCacheFrameCount(trackId); // 返回对应缓存的samplePacket个数 |
| 3018 | FALSE_RETURN_V_MSG_E(cachedFrames <= UINT32_MAX, Status::ERROR_WRONG_STATE, "FrameCount is invalid"); | 3100 | FALSE_RETURN_V_MSG_E(cachedFrames <= UINT32_MAX, Status::ERROR_WRONG_STATE, "FrameCount is invalid"); |
| 3019 | frameCount = cachedFrames; | 3101 | frameCount = cachedFrames; |
| 3020 | return Status::OK; | 3102 | return Status::OK; |
| @@ -28,7 +28,6 @@ | |||
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | 30 | ||
| 31 | - | ||
| 32 | 31 | ||
| 33 | 32 | ||
| 34 | 33 | ||
| @@ -157,7 +156,6 @@ private: | |||
| 157 | uint32_t currentFragment_ = 0; | 156 | uint32_t currentFragment_ = 0; |
| 158 | Seekable seekable_; | 157 | Seekable seekable_; |
| 159 | std::vector<uint32_t> selectedTrackIds_ = {}; | 158 | std::vector<uint32_t> selectedTrackIds_ = {}; |
| 160 | - Mpeg4BlockQueuePool cacheQueue_; | ||
| 161 | MediaInfo mediaInfo_; | 159 | MediaInfo mediaInfo_; |
| 162 | std::shared_ptr<Meta> userformat_ = nullptr; | 160 | std::shared_ptr<Meta> userformat_ = nullptr; |
| 163 | uint32_t cachelimitSize_ = 0; | 161 | uint32_t cachelimitSize_ = 0; |
| @@ -333,6 +331,18 @@ private: | |||
| 333 | Status ReadSampleData(std::shared_ptr<MPEG4Sample>& mpeg4Sample, const SampleReadInfo& sampleInfo); | 331 | Status ReadSampleData(std::shared_ptr<MPEG4Sample>& mpeg4Sample, const SampleReadInfo& sampleInfo); |
| 334 | Status AddSampleToCacheQueue(std::shared_ptr<Sample> sample, | 332 | Status AddSampleToCacheQueue(std::shared_ptr<Sample> sample, |
| 335 | const uint32_t trackId, uint32_t sampleIndex = UINT32_MAX); | 333 | const uint32_t trackId, uint32_t sampleIndex = UINT32_MAX); |
| 334 | + void ClearTrackCache(uint32_t trackId); | ||
| 335 | + bool HasTrackCache(uint32_t trackId); | ||
| 336 | + bool HasTrackCache(const std::shared_ptr<MPEG4AtomParser::Track>& track) const; | ||
| 337 | + uint32_t GetTrackCacheDataSize(uint32_t trackId); | ||
| 338 | + uint32_t GetTrackCacheFrameCount(uint32_t trackId); | ||
| 339 | + bool ResetTrackCacheInfo(const std::shared_ptr<MPEG4Sample>& mpeg4Sample); | ||
| 340 | + bool SetTrackCacheInfo(const std::shared_ptr<MPEG4Sample>& mpeg4Sample); | ||
| 341 | + bool PushTrackCache(uint32_t trackId, const std::shared_ptr<MPEG4Sample>& mpeg4Sample); | ||
| 342 | + std::shared_ptr<MPEG4Sample> PopTrackCache(uint32_t trackId); | ||
| 343 | + std::shared_ptr<MPEG4Sample> FrontTrackCache(uint32_t trackId); | ||
| 344 | + std::shared_ptr<MPEG4Sample> BackTrackCache(uint32_t trackId); | ||
| 345 | + Status GetTrackCacheLastPTS(uint32_t trackId, int64_t& maxPts); | ||
| 336 | void MaybeNotifyCachePressure(uint32_t trackId, uint32_t cacheBytes); | 346 | void MaybeNotifyCachePressure(uint32_t trackId, uint32_t cacheBytes); |
| 337 | int64_t NowMs() const; | 347 | int64_t NowMs() const; |
| 338 | Status FindFirstSampleIndexByDts(const std::shared_ptr<MPEG4AtomParser::Track>& track, | 348 | Status FindFirstSampleIndexByDts(const std::shared_ptr<MPEG4AtomParser::Track>& track, |
| @@ -406,6 +416,7 @@ private: | |||
| 406 | Status WaitForLoop(uint32_t trackId, uint32_t timeout); | 416 | Status WaitForLoop(uint32_t trackId, uint32_t timeout); |
| 407 | Status EnsureReadLoopStarted(); | 417 | Status EnsureReadLoopStarted(); |
| 408 | bool ShouldWaitForRead(uint32_t trackId); | 418 | bool ShouldWaitForRead(uint32_t trackId); |
| 419 | + bool ShouldWaitForRead(const std::shared_ptr<MPEG4AtomParser::Track>& track); | ||
| 409 | void MPEG4ReadLoop(); | 420 | void MPEG4ReadLoop(); |
| 410 | bool NeedWaitForRead(uint32_t trackId); | 421 | bool NeedWaitForRead(uint32_t trackId); |
| 411 | void HandleReadWait(); | 422 | void HandleReadWait(); |
| @@ -90,8 +90,7 @@ void MPEG4DemuxerPlugin::ResetCacheForSeek() | |||
| 90 | { | 90 | { |
| 91 | ReleaseReadLoop(); | 91 | ReleaseReadLoop(); |
| 92 | for (const auto& selectedTrackId : selectedTrackIds_) { | 92 | for (const auto& selectedTrackId : selectedTrackIds_) { |
| 93 | - cacheQueue_.RemoveTrackQueue(selectedTrackId); | 93 | + ClearTrackCache(selectedTrackId); |
| 94 | - cacheQueue_.AddTrackQueue(selectedTrackId); | ||
| 95 | } | 94 | } |
| 96 | cacheSamples_.clear(); | 95 | cacheSamples_.clear(); |
| 97 | pendingWebVttSamples_.clear(); | 96 | pendingWebVttSamples_.clear(); |
| @@ -159,7 +158,7 @@ Status MPEG4DemuxerPlugin::SeekToStartInternal() | |||
| 159 | for (const auto& selectedTrackId : selectedTrackIds_) { | 158 | for (const auto& selectedTrackId : selectedTrackIds_) { |
| 160 | auto track = FindTrackById(static_cast<int32_t>(selectedTrackId)); | 159 | auto track = FindTrackById(static_cast<int32_t>(selectedTrackId)); |
| 161 | FALSE_RETURN_V_MSG_E(track != nullptr, Status::ERROR_NULL_POINTER, "Track is nullptr"); | 160 | FALSE_RETURN_V_MSG_E(track != nullptr, Status::ERROR_NULL_POINTER, "Track is nullptr"); |
| 162 | - if (track->currentSampleIndex != 0 || cacheQueue_.HasCache(selectedTrackId)) { | 161 | + if (track->currentSampleIndex != 0 || HasTrackCache(track)) { |
| 163 | needSeek = true; | 162 | needSeek = true; |
| 164 | break; | 163 | break; |
| 165 | } | 164 | } |
| @@ -174,8 +173,7 @@ Status MPEG4DemuxerPlugin::SeekToStartInternal() | |||
| 174 | FALSE_RETURN_V_MSG_E(track != nullptr, Status::ERROR_NULL_POINTER, "Track is nullptr"); | 173 | FALSE_RETURN_V_MSG_E(track != nullptr, Status::ERROR_NULL_POINTER, "Track is nullptr"); |
| 175 | track->currentSampleIndex = 0; | 174 | track->currentSampleIndex = 0; |
| 176 | track->currentSamplePos = 0; | 175 | track->currentSamplePos = 0; |
| 177 | - cacheQueue_.RemoveTrackQueue(selectedTrackId); | 176 | + ClearTrackCache(selectedTrackId); |
| 178 | - cacheQueue_.AddTrackQueue(selectedTrackId); | ||
| 179 | } | 177 | } |
| 180 | currentFragment_ = 0; | 178 | currentFragment_ = 0; |
| 181 | minElstInitEmptyEdit_ = INT64_MAX; | 179 | minElstInitEmptyEdit_ = INT64_MAX; |
| @@ -586,12 +584,12 @@ Status MPEG4DemuxerPlugin::WriteSampleMemory(uint32_t trackIndex, std::shared_pt | |||
| 586 | CheckResetXPSSendStatus(trackIndex, mpeg4Sample->sample); | 584 | CheckResetXPSSendStatus(trackIndex, mpeg4Sample->sample); |
| 587 | auto track = FindTrackById(trackIndex); | 585 | auto track = FindTrackById(trackIndex); |
| 588 | int32_t oldSize = mpeg4Sample->sample->size; | 586 | int32_t oldSize = mpeg4Sample->sample->size; |
| 589 | - if (cacheQueue_.ResetInfo(mpeg4Sample) == false) { | 587 | + if (ResetTrackCacheInfo(mpeg4Sample) == false) { |
| 590 | MEDIA_LOG_D("Reset info failed"); | 588 | MEDIA_LOG_D("Reset info failed"); |
| 591 | } | 589 | } |
| 592 | Status ret = ConvertSampleToAnnexb(mpeg4Sample, trackIndex); | 590 | Status ret = ConvertSampleToAnnexb(mpeg4Sample, trackIndex); |
| 593 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Convert annexb failed"); | 591 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Convert annexb failed"); |
| 594 | - if (cacheQueue_.SetInfo(mpeg4Sample) == false) { | 592 | + if (SetTrackCacheInfo(mpeg4Sample) == false) { |
| 595 | MEDIA_LOG_D("Set info failed"); | 593 | MEDIA_LOG_D("Set info failed"); |
| 596 | } | 594 | } |
| 597 | 595 | ||
| @@ -619,7 +617,7 @@ Status MPEG4DemuxerPlugin::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer | |||
| 619 | 617 | ||
| 620 | isPauseReadPacket_.store(false, std::memory_order_release); | 618 | isPauseReadPacket_.store(false, std::memory_order_release); |
| 621 | trackId_.store(trackId, std::memory_order_release); | 619 | trackId_.store(trackId, std::memory_order_release); |
| 622 | - if (!cacheQueue_.HasCache(trackId) && timeout == 0) { | 620 | + if (!HasTrackCache(trackId) && timeout == 0) { |
| 623 | return Status::ERROR_WAIT_TIMEOUT; | 621 | return Status::ERROR_WAIT_TIMEOUT; |
| 624 | } | 622 | } |
| 625 | 623 | ||
| @@ -629,14 +627,14 @@ Status MPEG4DemuxerPlugin::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer | |||
| 629 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Frame reading thread error, ret = " PUBLIC_LOG_D32, ret); | 627 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Frame reading thread error, ret = " PUBLIC_LOG_D32, ret); |
| 630 | 628 | ||
| 631 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); | 629 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); |
| 632 | - auto mpeg4Sample = cacheQueue_.Front(trackId); | 630 | + auto mpeg4Sample = FrontTrackCache(trackId); |
| 633 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, Status::ERROR_NULL_POINTER, | 631 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, Status::ERROR_NULL_POINTER, |
| 634 | "Cache sample is nullptr"); | 632 | "Cache sample is nullptr"); |
| 635 | 633 | ||
| 636 | if ((mpeg4Sample->sample->flag & Sample::SampleFlag::EOS) != 0) { | 634 | if ((mpeg4Sample->sample->flag & Sample::SampleFlag::EOS) != 0) { |
| 637 | ret = SetEosSample(outBuffer, false); | 635 | ret = SetEosSample(outBuffer, false); |
| 638 | if (ret == Status::OK) { | 636 | if (ret == Status::OK) { |
| 639 | - cacheQueue_.Pop(trackId); | 637 | + PopTrackCache(trackId); |
| 640 | cacheSamples_.erase(trackId); | 638 | cacheSamples_.erase(trackId); |
| 641 | } | 639 | } |
| 642 | return ret; | 640 | return ret; |
| @@ -646,7 +644,7 @@ Status MPEG4DemuxerPlugin::ReadSample(uint32_t trackId, std::shared_ptr<AVBuffer | |||
| 646 | if (ret == Status::ERROR_NOT_ENOUGH_DATA) { | 644 | if (ret == Status::ERROR_NOT_ENOUGH_DATA) { |
| 647 | return Status::OK; | 645 | return Status::OK; |
| 648 | } else if (ret == Status::OK) { | 646 | } else if (ret == Status::OK) { |
| 649 | - cacheQueue_.Pop(trackId); | 647 | + PopTrackCache(trackId); |
| 650 | cacheSamples_.erase(trackId); | 648 | cacheSamples_.erase(trackId); |
| 651 | } | 649 | } |
| 652 | return ret; | 650 | return ret; |
| @@ -666,7 +664,7 @@ Status MPEG4DemuxerPlugin::GetNextSampleSize(uint32_t trackId, int32_t &sampleSi | |||
| 666 | 664 | ||
| 667 | isPauseReadPacket_.store(false, std::memory_order_release); | 665 | isPauseReadPacket_.store(false, std::memory_order_release); |
| 668 | trackId_.store(trackId, std::memory_order_release); | 666 | trackId_.store(trackId, std::memory_order_release); |
| 669 | - if (!cacheQueue_.HasCache(trackId) && timeout == 0) { | 667 | + if (!HasTrackCache(trackId) && timeout == 0) { |
| 670 | return Status::ERROR_WAIT_TIMEOUT; | 668 | return Status::ERROR_WAIT_TIMEOUT; |
| 671 | } | 669 | } |
| 672 | 670 | ||
| @@ -676,7 +674,7 @@ Status MPEG4DemuxerPlugin::GetNextSampleSize(uint32_t trackId, int32_t &sampleSi | |||
| 676 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Frame reading thread error, ret = " PUBLIC_LOG_D32, ret); | 674 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Frame reading thread error, ret = " PUBLIC_LOG_D32, ret); |
| 677 | 675 | ||
| 678 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); | 676 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); |
| 679 | - auto mpeg4Sample = cacheQueue_.Front(trackId); | 677 | + auto mpeg4Sample = FrontTrackCache(trackId); |
| 680 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, Status::ERROR_NULL_POINTER, | 678 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, Status::ERROR_NULL_POINTER, |
| 681 | "Cache sample is nullptr"); | 679 | "Cache sample is nullptr"); |
| 682 | if ((mpeg4Sample->sample->flag & Sample::SampleFlag::EOS) != 0) { | 680 | if ((mpeg4Sample->sample->flag & Sample::SampleFlag::EOS) != 0) { |
| @@ -700,12 +698,12 @@ Status MPEG4DemuxerPlugin::GetLastPTSByTrackId(uint32_t trackId, int64_t &lastPT | |||
| 700 | FALSE_RETURN_V_MSG_E(!selectedTrackIds_.empty(), Status::ERROR_INVALID_OPERATION, "No track has been selected"); | 698 | FALSE_RETURN_V_MSG_E(!selectedTrackIds_.empty(), Status::ERROR_INVALID_OPERATION, "No track has been selected"); |
| 701 | FALSE_RETURN_V_MSG_E(TrackIsSelected(trackId), Status::ERROR_INVALID_PARAMETER, "Track has not been selected"); | 699 | FALSE_RETURN_V_MSG_E(TrackIsSelected(trackId), Status::ERROR_INVALID_PARAMETER, "Track has not been selected"); |
| 702 | lastPTS = INT64_MIN; | 700 | lastPTS = INT64_MIN; |
| 703 | - return cacheQueue_.GetLastPTSByTrackId(trackId, lastPTS); | 701 | + return GetTrackCacheLastPTS(trackId, lastPTS); |
| 704 | } | 702 | } |
| 705 | 703 | ||
| 706 | bool MPEG4DemuxerPlugin::ShouldWaitForRead(uint32_t trackId) | 704 | bool MPEG4DemuxerPlugin::ShouldWaitForRead(uint32_t trackId) |
| 707 | { | 705 | { |
| 708 | - return !cacheQueue_.HasCache(trackId); | 706 | + return !HasTrackCache(trackId); |
| 709 | } | 707 | } |
| 710 | 708 | ||
| 711 | Status MPEG4DemuxerPlugin::EnsureReadLoopStarted() | 709 | Status MPEG4DemuxerPlugin::EnsureReadLoopStarted() |
| @@ -724,7 +722,8 @@ Status MPEG4DemuxerPlugin::EnsureReadLoopStarted() | |||
| 724 | Status MPEG4DemuxerPlugin::WaitForLoop(uint32_t trackId, uint32_t timeout) | 722 | Status MPEG4DemuxerPlugin::WaitForLoop(uint32_t trackId, uint32_t timeout) |
| 725 | { | 723 | { |
| 726 | FALSE_RETURN_V_MSG_E(readThread_ != nullptr, Status::ERROR_UNKNOWN, "Read thread is nullptr"); | 724 | FALSE_RETURN_V_MSG_E(readThread_ != nullptr, Status::ERROR_UNKNOWN, "Read thread is nullptr"); |
| 727 | - if (ShouldWaitForRead(trackId)) { | 725 | + auto track = FindTrackById(static_cast<int32_t>(trackId)); |
| 726 | + if (ShouldWaitForRead(track)) { | ||
| 728 | isWaitingForReadThread_.store(true, std::memory_order_release); | 727 | isWaitingForReadThread_.store(true, std::memory_order_release); |
| 729 | if (threadState_.load(std::memory_order_acquire) == ThreadState::WAITING) { | 728 | if (threadState_.load(std::memory_order_acquire) == ThreadState::WAITING) { |
| 730 | std::lock_guard<std::mutex> readLock(readThreadMutex_); | 729 | std::lock_guard<std::mutex> readLock(readThreadMutex_); |
| @@ -733,8 +732,8 @@ Status MPEG4DemuxerPlugin::WaitForLoop(uint32_t trackId, uint32_t timeout) | |||
| 733 | } | 732 | } |
| 734 | { | 733 | { |
| 735 | std::unique_lock<std::mutex> readLock(readSampleMutex_); | 734 | std::unique_lock<std::mutex> readLock(readSampleMutex_); |
| 736 | - if (!readCacheCv_.wait_for(readLock, std::chrono::milliseconds(timeout), [this, trackId] { | 735 | + if (!readCacheCv_.wait_for(readLock, std::chrono::milliseconds(timeout), [this, track] { |
| 737 | - return !ShouldWaitForRead(trackId) || readLoopStatus_.load(std::memory_order_acquire) != Status::OK; | 736 | + return !ShouldWaitForRead(track) || readLoopStatus_.load(std::memory_order_acquire) != Status::OK; |
| 738 | })) { | 737 | })) { |
| 739 | isWaitingForReadThread_.store(false, std::memory_order_release); | 738 | isWaitingForReadThread_.store(false, std::memory_order_release); |
| 740 | FALSE_RETURN_V_MSG_E(readLoopStatus_.load(std::memory_order_acquire) == Status::OK, | 739 | FALSE_RETURN_V_MSG_E(readLoopStatus_.load(std::memory_order_acquire) == Status::OK, |
| @@ -744,26 +743,27 @@ Status MPEG4DemuxerPlugin::WaitForLoop(uint32_t trackId, uint32_t timeout) | |||
| 744 | } | 743 | } |
| 745 | } | 744 | } |
| 746 | isWaitingForReadThread_.store(false, std::memory_order_release); | 745 | isWaitingForReadThread_.store(false, std::memory_order_release); |
| 747 | - if (ShouldWaitForRead(trackId) && readLoopStatus_.load(std::memory_order_acquire) != Status::OK) { | 746 | + if (ShouldWaitForRead(track) && readLoopStatus_.load(std::memory_order_acquire) != Status::OK) { |
| 748 | return readLoopStatus_.load(std::memory_order_acquire); | 747 | return readLoopStatus_.load(std::memory_order_acquire); |
| 749 | } | 748 | } |
| 750 | return Status::OK; | 749 | return Status::OK; |
| 751 | } | 750 | } |
| 752 | 751 | ||
| 752 | +bool MPEG4DemuxerPlugin::ShouldWaitForRead(const std::shared_ptr<MPEG4AtomParser::Track>& track) | ||
| 753 | +{ | ||
| 754 | + return !HasTrackCache(track); | ||
| 755 | +} | ||
| 756 | + | ||
| 753 | bool MPEG4DemuxerPlugin::NeedWaitForRead(uint32_t trackId) | 757 | bool MPEG4DemuxerPlugin::NeedWaitForRead(uint32_t trackId) |
| 754 | { | 758 | { |
| 755 | - return (cacheQueue_.HasCache(trackId) || isPauseReadPacket_.load(std::memory_order_acquire)) && | 759 | + return (HasTrackCache(trackId) || isPauseReadPacket_.load(std::memory_order_acquire)) && |
| 756 | !stopReadThread_.load(std::memory_order_acquire); | 760 | !stopReadThread_.load(std::memory_order_acquire); |
| 757 | } | 761 | } |
| 758 | 762 | ||
| 759 | bool MPEG4DemuxerPlugin::IsWebVTTTrack(const std::shared_ptr<MPEG4AtomParser::Track>& track) const | 763 | bool MPEG4DemuxerPlugin::IsWebVTTTrack(const std::shared_ptr<MPEG4AtomParser::Track>& track) const |
| 760 | { | 764 | { |
| 761 | - if (track == nullptr || track->sampleHelper == nullptr) { | 765 | + return track != nullptr && track->sampleHelper != nullptr && |
| 762 | - return false; | 766 | + track->sampleHelper->mimeType_ == MimeType::TEXT_WEBVTT; |
| 763 | - } | ||
| 764 | - std::string metaMime; | ||
| 765 | - mediaInfo_.tracks[track->trackIndex].Get<Tag::MIME_TYPE>(metaMime); | ||
| 766 | - return track->sampleHelper->mimeType_ == MimeType::TEXT_WEBVTT || metaMime == MimeType::TEXT_WEBVTT; | ||
| 767 | } | 767 | } |
| 768 | 768 | ||
| 769 | void MPEG4DemuxerPlugin::AdvanceSampleIndex(const std::shared_ptr<MPEG4AtomParser::Track>& track) | 769 | void MPEG4DemuxerPlugin::AdvanceSampleIndex(const std::shared_ptr<MPEG4AtomParser::Track>& track) |
| @@ -901,7 +901,7 @@ void MPEG4DemuxerPlugin::HandleReadWait() | |||
| 901 | auto trackId = trackId_.load(std::memory_order_acquire); | 901 | auto trackId = trackId_.load(std::memory_order_acquire); |
| 902 | return threadReady_.load(std::memory_order_acquire) || | 902 | return threadReady_.load(std::memory_order_acquire) || |
| 903 | stopReadThread_.load(std::memory_order_acquire) || | 903 | stopReadThread_.load(std::memory_order_acquire) || |
| 904 | - (!cacheQueue_.HasCache(trackId) && !isPauseReadPacket_.load(std::memory_order_acquire)) || | 904 | + (!HasTrackCache(trackId) && !isPauseReadPacket_.load(std::memory_order_acquire)) || |
| 905 | isWaitingForReadThread_.load(std::memory_order_acquire); | 905 | isWaitingForReadThread_.load(std::memory_order_acquire); |
| 906 | }); | 906 | }); |
| 907 | threadState_.store(ThreadState::READING, std::memory_order_release); | 907 | threadState_.store(ThreadState::READING, std::memory_order_release); |
| @@ -944,7 +944,7 @@ Status MPEG4DemuxerPlugin::ReadSampleToCache(uint32_t trackId) | |||
| 944 | if (readToEnd_) { | 944 | if (readToEnd_) { |
| 945 | return Status::END_OF_STREAM; | 945 | return Status::END_OF_STREAM; |
| 946 | } | 946 | } |
| 947 | - while (!cacheQueue_.HasCache(trackId)) { | 947 | + while (!HasTrackCache(trackId)) { |
| 948 | SampleReadInfo sampleInfo; | 948 | SampleReadInfo sampleInfo; |
| 949 | Status ret = GetUnseekableSampleInfo(sampleInfo); | 949 | Status ret = GetUnseekableSampleInfo(sampleInfo); |
| 950 | FALSE_RETURN_V_MSG_E(ret == Status::OK || ret == Status::END_OF_STREAM, ret, | 950 | FALSE_RETURN_V_MSG_E(ret == Status::OK || ret == Status::END_OF_STREAM, ret, |
| @@ -952,7 +952,7 @@ Status MPEG4DemuxerPlugin::ReadSampleToCache(uint32_t trackId) | |||
| 952 | if (ret == Status::END_OF_STREAM) { | 952 | if (ret == Status::END_OF_STREAM) { |
| 953 | ret = FlushPendingWebVTTSample(trackId); | 953 | ret = FlushPendingWebVTTSample(trackId); |
| 954 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Flush pending WebVTT samples failed"); | 954 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Flush pending WebVTT samples failed"); |
| 955 | - return cacheQueue_.HasCache(trackId) ? Status::OK : Status::END_OF_STREAM; | 955 | + return HasTrackCache(trackId) ? Status::OK : Status::END_OF_STREAM; |
| 956 | } | 956 | } |
| 957 | 957 | ||
| 958 | auto currentTrack = FindTrackById(static_cast<int32_t>(sampleInfo.trackId)); | 958 | auto currentTrack = FindTrackById(static_cast<int32_t>(sampleInfo.trackId)); |
| @@ -962,6 +962,7 @@ Status MPEG4DemuxerPlugin::ReadSampleToCache(uint32_t trackId) | |||
| 962 | auto mpeg4Sample = std::make_shared<MPEG4Sample>(); | 962 | auto mpeg4Sample = std::make_shared<MPEG4Sample>(); |
| 963 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate MPEG4Sample"); | 963 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr, Status::ERROR_NO_MEMORY, "Failed to allocate MPEG4Sample"); |
| 964 | mpeg4Sample->sample = sample; | 964 | mpeg4Sample->sample = sample; |
| 965 | + mpeg4Sample->trackId = sampleInfo.trackId; | ||
| 965 | mpeg4Sample->sampleIndex = sampleInfo.sampleIndex; | 966 | mpeg4Sample->sampleIndex = sampleInfo.sampleIndex; |
| 966 | { | 967 | { |
| 967 | std::unique_lock<std::mutex> sLock(syncMutex_); | 968 | std::unique_lock<std::mutex> sLock(syncMutex_); |
| @@ -983,7 +984,7 @@ Status MPEG4DemuxerPlugin::PushEosToCache(uint32_t trackId) | |||
| 983 | { | 984 | { |
| 984 | (void)trackId; | 985 | (void)trackId; |
| 985 | for (const auto& selectedTrackId : selectedTrackIds_) { | 986 | for (const auto& selectedTrackId : selectedTrackIds_) { |
| 986 | - auto backSample = cacheQueue_.Back(selectedTrackId); | 987 | + auto backSample = BackTrackCache(selectedTrackId); |
| 987 | if (backSample != nullptr && backSample->sample != nullptr && | 988 | if (backSample != nullptr && backSample->sample != nullptr && |
| 988 | (backSample->sample->flag & Sample::SampleFlag::EOS) != 0) { | 989 | (backSample->sample->flag & Sample::SampleFlag::EOS) != 0) { |
| 989 | continue; | 990 | continue; |
| @@ -1107,7 +1108,7 @@ Status MPEG4DemuxerPlugin::ReadSampleZeroCopy(uint32_t trackId, std::shared_ptr< | |||
| 1107 | 1108 | ||
| 1108 | isPauseReadPacket_.store(false, std::memory_order_release); | 1109 | isPauseReadPacket_.store(false, std::memory_order_release); |
| 1109 | trackId_.store(trackId, std::memory_order_release); | 1110 | trackId_.store(trackId, std::memory_order_release); |
| 1110 | - if (!cacheQueue_.HasCache(trackId) && timeout == 0) { | 1111 | + if (!HasTrackCache(trackId) && timeout == 0) { |
| 1111 | return Status::ERROR_WAIT_TIMEOUT; | 1112 | return Status::ERROR_WAIT_TIMEOUT; |
| 1112 | } | 1113 | } |
| 1113 | 1114 | ||
| @@ -1117,14 +1118,14 @@ Status MPEG4DemuxerPlugin::ReadSampleZeroCopy(uint32_t trackId, std::shared_ptr< | |||
| 1117 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Frame reading thread error, ret = " PUBLIC_LOG_D32, ret); | 1118 | FALSE_RETURN_V_MSG_E(ret == Status::OK, ret, "Frame reading thread error, ret = " PUBLIC_LOG_D32, ret); |
| 1118 | 1119 | ||
| 1119 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); | 1120 | std::lock_guard<std::mutex> lockTrack(*trackMtx_[trackId].get()); |
| 1120 | - auto mpeg4Sample = cacheQueue_.Front(trackId); | 1121 | + auto mpeg4Sample = FrontTrackCache(trackId); |
| 1121 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, Status::ERROR_NULL_POINTER, | 1122 | FALSE_RETURN_V_MSG_E(mpeg4Sample != nullptr && mpeg4Sample->sample != nullptr, Status::ERROR_NULL_POINTER, |
| 1122 | "Cache sample is nullptr"); | 1123 | "Cache sample is nullptr"); |
| 1123 | 1124 | ||
| 1124 | if ((mpeg4Sample->sample->flag & Sample::SampleFlag::EOS) != 0) { | 1125 | if ((mpeg4Sample->sample->flag & Sample::SampleFlag::EOS) != 0) { |
| 1125 | ret = SetEosSample(outBuffer, true); | 1126 | ret = SetEosSample(outBuffer, true); |
| 1126 | if (ret == Status::OK) { | 1127 | if (ret == Status::OK) { |
| 1127 | - cacheQueue_.Pop(trackId); | 1128 | + PopTrackCache(trackId); |
| 1128 | cacheSamples_.erase(trackId); | 1129 | cacheSamples_.erase(trackId); |
| 1129 | } | 1130 | } |
| 1130 | return ret; | 1131 | return ret; |
| @@ -1132,7 +1133,7 @@ Status MPEG4DemuxerPlugin::ReadSampleZeroCopy(uint32_t trackId, std::shared_ptr< | |||
| 1132 | 1133 | ||
| 1133 | ret = WriteSampleMemory(trackId, outBuffer, mpeg4Sample); | 1134 | ret = WriteSampleMemory(trackId, outBuffer, mpeg4Sample); |
| 1134 | if (ret == Status::OK) { | 1135 | if (ret == Status::OK) { |
| 1135 | - cacheQueue_.Pop(trackId); | 1136 | + PopTrackCache(trackId); |
| 1136 | cacheSamples_.erase(trackId); | 1137 | cacheSamples_.erase(trackId); |
| 1137 | } | 1138 | } |
| 1138 | return ret; | 1139 | return ret; |
| @@ -516,7 +516,7 @@ Status MPEG4DemuxerPlugin::SelectProGopId() | |||
| 516 | 0); | 516 | 0); |
| 517 | MEDIA_LOG_I("realSeekTime is " PUBLIC_LOG_D64, realSeekTime); | 517 | MEDIA_LOG_I("realSeekTime is " PUBLIC_LOG_D64, realSeekTime); |
| 518 | FALSE_RETURN_V_MSG_E(ret == Status::OK, Status::ERROR_UNKNOWN, "SeekToFrameByDts failed"); | 518 | FALSE_RETURN_V_MSG_E(ret == Status::OK, Status::ERROR_UNKNOWN, "SeekToFrameByDts failed"); |
| 519 | - cacheSample_ = cacheQueue_.Front(refParserTrackIdx_); | 519 | + cacheSample_ = FrontTrackCache(refParserTrackIdx_); |
| 520 | isReadSampleDataFromCache_ = true; | 520 | isReadSampleDataFromCache_ = true; |
| 521 | return Status::OK; | 521 | return Status::OK; |
| 522 | } | 522 | } |
| @@ -0,0 +1,203 @@ | |||
| 1 | +/* | ||
| 2 | + * Copyright (C) 2026 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 | + | ||
| 17 | + | ||
| 18 | + | ||
| 19 | + | ||
| 20 | + | ||
| 21 | + | ||
| 22 | + | ||
| 23 | + | ||
| 24 | + | ||
| 25 | + | ||
| 26 | +namespace OHOS { | ||
| 27 | +namespace Media { | ||
| 28 | +namespace Plugins { | ||
| 29 | +namespace MPEG4 { | ||
| 30 | + | ||
| 31 | +struct Sample { | ||
| 32 | + enum SampleFlag : uint32_t { | ||
| 33 | + NONE = 0, | ||
| 34 | + EOS = 1 << 0, | ||
| 35 | + SYNC_FRAME = 1 << 1, | ||
| 36 | + DISCARD = 1 << 4, | ||
| 37 | + }; | ||
| 38 | + int64_t pts; | ||
| 39 | + int64_t dts; | ||
| 40 | + int64_t duration; | ||
| 41 | + uint32_t flag; | ||
| 42 | + int32_t size; | ||
| 43 | + std::vector<uint8_t> skipSamplesInfo; | ||
| 44 | + std::unique_ptr<uint8_t[]> data; | ||
| 45 | +}; | ||
| 46 | + | ||
| 47 | +struct MPEG4Sample { | ||
| 48 | + int32_t offset = 0; | ||
| 49 | + std::shared_ptr<Sample> sample = nullptr; | ||
| 50 | + bool isAnnexb = false; | ||
| 51 | + bool isVttc = false; | ||
| 52 | + uint32_t trackId = UINT32_MAX; | ||
| 53 | + uint32_t sampleIndex = 0; | ||
| 54 | +}; | ||
| 55 | + | ||
| 56 | +class SampleCache { | ||
| 57 | +public: | ||
| 58 | + bool HasCache() const | ||
| 59 | + { | ||
| 60 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 61 | + return !samples_.empty(); | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + uint32_t GetCacheDataSize() const | ||
| 65 | + { | ||
| 66 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 67 | + return dataSize_ > UINT32_MAX ? UINT32_MAX : static_cast<uint32_t>(dataSize_); | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + uint32_t GetCacheFrameCount() const | ||
| 71 | + { | ||
| 72 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 73 | + return samples_.size() > UINT32_MAX ? UINT32_MAX : static_cast<uint32_t>(samples_.size()); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + bool ResetInfo(const std::shared_ptr<MPEG4Sample>& block) | ||
| 77 | + { | ||
| 78 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 79 | + if (block == nullptr || block->sample == nullptr || samples_.empty()) { | ||
| 80 | + return true; | ||
| 81 | + } | ||
| 82 | + uint64_t blockSize = 0; | ||
| 83 | + if (!GetBlockSize(block, blockSize)) { | ||
| 84 | + return true; | ||
| 85 | + } | ||
| 86 | + dataSize_ = dataSize_ >= blockSize ? dataSize_ - blockSize : 0; | ||
| 87 | + return true; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + bool SetInfo(const std::shared_ptr<MPEG4Sample>& block) | ||
| 91 | + { | ||
| 92 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 93 | + if (block == nullptr || block->sample == nullptr || samples_.empty()) { | ||
| 94 | + return true; | ||
| 95 | + } | ||
| 96 | + uint64_t blockSize = 0; | ||
| 97 | + if (!GetBlockSize(block, blockSize)) { | ||
| 98 | + return true; | ||
| 99 | + } | ||
| 100 | + dataSize_ += blockSize; | ||
| 101 | + return true; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + bool Push(std::shared_ptr<MPEG4Sample> block) | ||
| 105 | + { | ||
| 106 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 107 | + if (block == nullptr || block->sample == nullptr) { | ||
| 108 | + return false; | ||
| 109 | + } | ||
| 110 | + uint64_t blockSize = 0; | ||
| 111 | + if (!GetBlockSize(block, blockSize)) { | ||
| 112 | + return false; | ||
| 113 | + } | ||
| 114 | + samples_.push_back(std::move(block)); | ||
| 115 | + UpdateStatsOnPush(blockSize); | ||
| 116 | + return true; | ||
| 117 | + } | ||
| 118 | + | ||
| 119 | + std::shared_ptr<MPEG4Sample> Pop() | ||
| 120 | + { | ||
| 121 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 122 | + if (samples_.empty()) { | ||
| 123 | + return nullptr; | ||
| 124 | + } | ||
| 125 | + auto block = samples_.front(); | ||
| 126 | + samples_.pop_front(); | ||
| 127 | + UpdateStatsOnPop(block); | ||
| 128 | + return block; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + std::shared_ptr<MPEG4Sample> Front() const | ||
| 132 | + { | ||
| 133 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 134 | + return samples_.empty() ? nullptr : samples_.front(); | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + std::shared_ptr<MPEG4Sample> Back() const | ||
| 138 | + { | ||
| 139 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 140 | + return samples_.empty() ? nullptr : samples_.back(); | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + Status GetLastPTS(int64_t& maxPts) const | ||
| 144 | + { | ||
| 145 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 146 | + if (samples_.empty()) { | ||
| 147 | + maxPts = INT64_MIN; | ||
| 148 | + return Status::ERROR_NOT_EXISTED; | ||
| 149 | + } | ||
| 150 | + bool found = false; | ||
| 151 | + maxPts = INT64_MIN; | ||
| 152 | + for (const auto& block : samples_) { | ||
| 153 | + if (block == nullptr || block->sample == nullptr) { | ||
| 154 | + continue; | ||
| 155 | + } | ||
| 156 | + if (!found || block->sample->pts > maxPts) { | ||
| 157 | + maxPts = block->sample->pts; | ||
| 158 | + found = true; | ||
| 159 | + } | ||
| 160 | + } | ||
| 161 | + return found ? Status::OK : Status::ERROR_NOT_EXISTED; | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + void Clear() | ||
| 165 | + { | ||
| 166 | + std::lock_guard<std::mutex> lock(mutex_); | ||
| 167 | + samples_.clear(); | ||
| 168 | + dataSize_ = 0; | ||
| 169 | + } | ||
| 170 | + | ||
| 171 | +private: | ||
| 172 | + static bool GetBlockSize(const std::shared_ptr<MPEG4Sample>& block, uint64_t& blockSize) | ||
| 173 | + { | ||
| 174 | + if (block == nullptr || block->sample == nullptr || block->sample->size < 0) { | ||
| 175 | + return false; | ||
| 176 | + } | ||
| 177 | + blockSize = static_cast<uint64_t>(block->sample->size); | ||
| 178 | + return true; | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + void UpdateStatsOnPush(uint64_t blockSize) | ||
| 182 | + { | ||
| 183 | + dataSize_ += blockSize; | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + void UpdateStatsOnPop(const std::shared_ptr<MPEG4Sample>& block) | ||
| 187 | + { | ||
| 188 | + uint64_t blockSize = 0; | ||
| 189 | + if (!GetBlockSize(block, blockSize)) { | ||
| 190 | + return; | ||
| 191 | + } | ||
| 192 | + dataSize_ = dataSize_ >= blockSize ? dataSize_ - blockSize : 0; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + mutable std::mutex mutex_; | ||
| 196 | + std::deque<std::shared_ptr<MPEG4Sample>> samples_; | ||
| 197 | + uint64_t dataSize_ {0}; | ||
| 198 | +}; | ||
| 199 | +} // namespace MPEG4 | ||
| 200 | +} // namespace Plugins | ||
| 201 | +} // namespace Media | ||
| 202 | +} // namespace OHOS | ||
| 203 | + | ||
| @@ -24,7 +24,6 @@ | |||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | - | ||
| 28 | 27 | ||
| 29 | 28 | ||
| 30 | 29 | ||
| @@ -19,6 +19,7 @@ | |||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | 21 | ||
| 22 | + | ||
| 22 | 23 | ||
| 23 | 24 | ||
| 24 | namespace { | 25 | namespace { |
| @@ -18,7 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | -#include "block_queue_pool.h" | 21 | +#include "mpeg4_sample.h" |
| 22 | 22 | ||
| 23 | namespace OHOS { | 23 | namespace OHOS { |
| 24 | namespace Media { | 24 | namespace Media { |
| @@ -62,6 +62,7 @@ const std::string TEST_URI_PATH = "http://127.0.0.1:46666/"; | |||
| 62 | const std::string TEST_RELATIVE_PATH = "/data/test/media/"; | 62 | const std::string TEST_RELATIVE_PATH = "/data/test/media/"; |
| 63 | const std::string TEST_DEMUXER_RESOURCE_DIR = "/data/test/media"; | 63 | const std::string TEST_DEMUXER_RESOURCE_DIR = "/data/test/media"; |
| 64 | const std::string FFMPEG_MP4_PLUGIN_NAME = "avdemux_mov,mp4,m4a,3gp,3g2,mj2"; | 64 | const std::string FFMPEG_MP4_PLUGIN_NAME = "avdemux_mov,mp4,m4a,3gp,3g2,mj2"; |
| 65 | +const std::string MPEG4_PLUGIN_NAME = "avdemux_mpeg4"; | ||
| 65 | const std::string WEBVTT_MIME = "text/vtt"; | 66 | const std::string WEBVTT_MIME = "text/vtt"; |
| 66 | const std::string HEVC_LIB_PATH = std::string(AV_CODEC_PATH) + "/libav_codec_hevc_parser.z.so"; | 67 | const std::string HEVC_LIB_PATH = std::string(AV_CODEC_PATH) + "/libav_codec_hevc_parser.z.so"; |
| 67 | constexpr int32_t WAIT_RETRY_TIMES = 20; | 68 | constexpr int32_t WAIT_RETRY_TIMES = 20; |
| @@ -1200,6 +1201,7 @@ std::shared_ptr<Plugins::MPEG4::MPEG4AtomParser::Track> MakeWebVttTrack(uint32_t | |||
| 1200 | auto track = std::make_shared<Plugins::MPEG4::MPEG4AtomParser::Track>(); | 1201 | auto track = std::make_shared<Plugins::MPEG4::MPEG4AtomParser::Track>(); |
| 1201 | track->trackIndex = trackIndex; | 1202 | track->trackIndex = trackIndex; |
| 1202 | track->duration = duration; | 1203 | track->duration = duration; |
| 1204 | + track->cache = std::make_shared<Plugins::MPEG4::SampleCache>(); | ||
| 1203 | track->sampleHelper = std::make_shared<Plugins::MPEG4::MPEG4SampleHelper>(); | 1205 | track->sampleHelper = std::make_shared<Plugins::MPEG4::MPEG4SampleHelper>(); |
| 1204 | track->sampleHelper->mimeType_ = MimeType::TEXT_WEBVTT; | 1206 | track->sampleHelper->mimeType_ = MimeType::TEXT_WEBVTT; |
| 1205 | return track; | 1207 | return track; |
| @@ -1475,13 +1477,17 @@ void Mpeg4DemuxerPluginUnitTest::InitFfmpegPluginURI(const std::string& filePath | |||
| 1475 | 1477 | ||
| 1476 | void Mpeg4DemuxerPluginUnitTest::InitMpeg4Plugin(const std::string& filePath) | 1478 | void Mpeg4DemuxerPluginUnitTest::InitMpeg4Plugin(const std::string& filePath) |
| 1477 | { | 1479 | { |
| 1478 | - mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(std::make_shared<MPEG4DemuxerPlugin>("avdemux_mpeg4")); | 1480 | + auto basePlugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(MPEG4_PLUGIN_NAME); |
| 1481 | + auto mpeg4Plugin = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin); | ||
| 1482 | + mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(mpeg4Plugin); | ||
| 1479 | InitPlugin(filePath, mpeg4Plugin_, mpeg4Fd_, mpeg4MediaInfo_); | 1483 | InitPlugin(filePath, mpeg4Plugin_, mpeg4Fd_, mpeg4MediaInfo_); |
| 1480 | } | 1484 | } |
| 1481 | 1485 | ||
| 1482 | void Mpeg4DemuxerPluginUnitTest::InitMpeg4PluginURI(const std::string& filePath) | 1486 | void Mpeg4DemuxerPluginUnitTest::InitMpeg4PluginURI(const std::string& filePath) |
| 1483 | { | 1487 | { |
| 1484 | - mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(std::make_shared<MPEG4DemuxerPlugin>("avdemux_mpeg4")); | 1488 | + auto basePlugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(MPEG4_PLUGIN_NAME); |
| 1489 | + auto mpeg4Plugin = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin); | ||
| 1490 | + mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(mpeg4Plugin); | ||
| 1485 | InitPluginURI(filePath, mpeg4Plugin_, mpeg4MediaInfo_); | 1491 | InitPluginURI(filePath, mpeg4Plugin_, mpeg4MediaInfo_); |
| 1486 | } | 1492 | } |
| 1487 | 1493 | ||
| @@ -1498,7 +1504,9 @@ void Mpeg4DemuxerPluginUnitTest::InitWeakNetworkFfmpegPlugin( | |||
| 1498 | void Mpeg4DemuxerPluginUnitTest::InitWeakNetworkMpeg4Plugin( | 1504 | void Mpeg4DemuxerPluginUnitTest::InitWeakNetworkMpeg4Plugin( |
| 1499 | const std::string& filePath, int64_t failOffset, size_t maxFailCount) | 1505 | const std::string& filePath, int64_t failOffset, size_t maxFailCount) |
| 1500 | { | 1506 | { |
| 1501 | - mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(std::make_shared<MPEG4DemuxerPlugin>("avdemux_mpeg4")); | 1507 | + auto basePlugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(MPEG4_PLUGIN_NAME); |
| 1508 | + auto mpeg4Plugin = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin); | ||
| 1509 | + mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(mpeg4Plugin); | ||
| 1502 | WeakNetworkPluginContext context {mpeg4Plugin_, mpeg4Fd_, mpeg4MediaInfo_}; | 1510 | WeakNetworkPluginContext context {mpeg4Plugin_, mpeg4Fd_, mpeg4MediaInfo_}; |
| 1503 | InitWeakNetworkPlugin(filePath, context, failOffset, maxFailCount); | 1511 | InitWeakNetworkPlugin(filePath, context, failOffset, maxFailCount); |
| 1504 | } | 1512 | } |
| @@ -1528,7 +1536,9 @@ void Mpeg4DemuxerPluginUnitTest::InitDeferredWeakNetworkMpeg4Plugin( | |||
| 1528 | streamDemuxer->SetDemuxerState(0, DemuxerState::DEMUXER_STATE_PARSE_FRAME); | 1536 | streamDemuxer->SetDemuxerState(0, DemuxerState::DEMUXER_STATE_PARSE_FRAME); |
| 1529 | 1537 | ||
| 1530 | auto dataSource = std::make_shared<DataSourceImpl>(streamDemuxer, 0); | 1538 | auto dataSource = std::make_shared<DataSourceImpl>(streamDemuxer, 0); |
| 1531 | - mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(std::make_shared<MPEG4DemuxerPlugin>("avdemux_mpeg4")); | 1539 | + auto basePlugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(MPEG4_PLUGIN_NAME); |
| 1540 | + auto mpeg4Plugin = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin); | ||
| 1541 | + mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(mpeg4Plugin); | ||
| 1532 | ASSERT_EQ(mpeg4Plugin_->SetDataSource(dataSource), Status::OK); | 1542 | ASSERT_EQ(mpeg4Plugin_->SetDataSource(dataSource), Status::OK); |
| 1533 | ASSERT_EQ(mpeg4Plugin_->GetMediaInfo(mpeg4MediaInfo_), Status::OK); | 1543 | ASSERT_EQ(mpeg4Plugin_->GetMediaInfo(mpeg4MediaInfo_), Status::OK); |
| 1534 | streamDemuxer->ResetFailState(); | 1544 | streamDemuxer->ResetFailState(); |
| @@ -2985,25 +2995,25 @@ HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_WebVttPendingCue_001, Te | |||
| 2985 | plugin->mediaInfo_.tracks[0].Set<Tag::MIME_TYPE>(WEBVTT_MIME); | 2995 | plugin->mediaInfo_.tracks[0].Set<Tag::MIME_TYPE>(WEBVTT_MIME); |
| 2986 | plugin->mediaInfo_.tracks[1].Set<Tag::MIME_TYPE>(WEBVTT_MIME); | 2996 | plugin->mediaInfo_.tracks[1].Set<Tag::MIME_TYPE>(WEBVTT_MIME); |
| 2987 | plugin->mediaInfo_.general.Set<Tag::MEDIA_DURATION>(60000); | 2997 | plugin->mediaInfo_.general.Set<Tag::MEDIA_DURATION>(60000); |
| 2988 | - ASSERT_EQ(plugin->cacheQueue_.AddTrackQueue(0), Status::OK); | ||
| 2989 | - ASSERT_EQ(plugin->cacheQueue_.AddTrackQueue(1), Status::OK); | ||
| 2990 | 2998 | ||
| 2991 | plugin->pendingWebVttSamples_[0] = MakePendingWebVttSample(1000, 2000); | 2999 | plugin->pendingWebVttSamples_[0] = MakePendingWebVttSample(1000, 2000); |
| 2992 | plugin->pendingWebVttSamples_[1] = MakePendingWebVttSample(5000, 1000); | 3000 | plugin->pendingWebVttSamples_[1] = MakePendingWebVttSample(5000, 1000); |
| 2993 | ASSERT_EQ(plugin->FlushPendingWebVTTSample(0), Status::OK); | 3001 | ASSERT_EQ(plugin->FlushPendingWebVTTSample(0), Status::OK); |
| 2994 | EXPECT_EQ(plugin->pendingWebVttSamples_.count(0), 0U); | 3002 | EXPECT_EQ(plugin->pendingWebVttSamples_.count(0), 0U); |
| 2995 | EXPECT_EQ(plugin->pendingWebVttSamples_.count(1), 1U); | 3003 | EXPECT_EQ(plugin->pendingWebVttSamples_.count(1), 1U); |
| 2996 | - ASSERT_TRUE(plugin->cacheQueue_.HasCache(0)); | 3004 | + ASSERT_NE(track0->cache, nullptr); |
| 2997 | - ASSERT_FALSE(plugin->cacheQueue_.HasCache(1)); | 3005 | + ASSERT_NE(track1->cache, nullptr); |
| 2998 | - auto flushedTrack0 = plugin->cacheQueue_.Front(0); | 3006 | + ASSERT_TRUE(track0->cache->HasCache()); |
| 3007 | + ASSERT_FALSE(track1->cache->HasCache()); | ||
| 3008 | + auto flushedTrack0 = track0->cache->Front(); | ||
| 2999 | ASSERT_NE(flushedTrack0, nullptr); | 3009 | ASSERT_NE(flushedTrack0, nullptr); |
| 3000 | ASSERT_NE(flushedTrack0->sample, nullptr); | 3010 | ASSERT_NE(flushedTrack0->sample, nullptr); |
| 3001 | EXPECT_EQ(flushedTrack0->sample->duration, 2000); | 3011 | EXPECT_EQ(flushedTrack0->sample->duration, 2000); |
| 3002 | 3012 | ||
| 3003 | ASSERT_EQ(plugin->FlushPendingWebVTTSamples(), Status::OK); | 3013 | ASSERT_EQ(plugin->FlushPendingWebVTTSamples(), Status::OK); |
| 3004 | EXPECT_TRUE(plugin->pendingWebVttSamples_.empty()); | 3014 | EXPECT_TRUE(plugin->pendingWebVttSamples_.empty()); |
| 3005 | - ASSERT_TRUE(plugin->cacheQueue_.HasCache(1)); | 3015 | + ASSERT_TRUE(track1->cache->HasCache()); |
| 3006 | - auto flushedTrack1 = plugin->cacheQueue_.Front(1); | 3016 | + auto flushedTrack1 = track1->cache->Front(); |
| 3007 | ASSERT_NE(flushedTrack1, nullptr); | 3017 | ASSERT_NE(flushedTrack1, nullptr); |
| 3008 | ASSERT_NE(flushedTrack1->sample, nullptr); | 3018 | ASSERT_NE(flushedTrack1->sample, nullptr); |
| 3009 | EXPECT_EQ(flushedTrack1->sample->duration, 1000); | 3019 | EXPECT_EQ(flushedTrack1->sample->duration, 1000); |
| @@ -3023,15 +3033,15 @@ HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_WebVttContinuousCue_001, | |||
| 3023 | plugin->lastTrack_ = track; | 3033 | plugin->lastTrack_ = track; |
| 3024 | plugin->mediaInfo_.tracks.resize(1); | 3034 | plugin->mediaInfo_.tracks.resize(1); |
| 3025 | plugin->mediaInfo_.tracks[0].Set<Tag::MIME_TYPE>(WEBVTT_MIME); | 3035 | plugin->mediaInfo_.tracks[0].Set<Tag::MIME_TYPE>(WEBVTT_MIME); |
| 3026 | - ASSERT_EQ(plugin->cacheQueue_.AddTrackQueue(0), Status::OK); | ||
| 3027 | 3036 | ||
| 3028 | auto firstCue = MakeWebVttCueSample(1000, 100, "first"); | 3037 | auto firstCue = MakeWebVttCueSample(1000, 100, "first"); |
| 3029 | auto secondCue = MakeWebVttCueSample(2500, 100, "second"); | 3038 | auto secondCue = MakeWebVttCueSample(2500, 100, "second"); |
| 3030 | ASSERT_EQ(plugin->ProcessWebVTTSampleForCache(track, firstCue), Status::OK); | 3039 | ASSERT_EQ(plugin->ProcessWebVTTSampleForCache(track, firstCue), Status::OK); |
| 3031 | - EXPECT_FALSE(plugin->cacheQueue_.HasCache(0)); | 3040 | + ASSERT_NE(track->cache, nullptr); |
| 3041 | + EXPECT_FALSE(track->cache->HasCache()); | ||
| 3032 | ASSERT_EQ(plugin->ProcessWebVTTSampleForCache(track, secondCue), Status::OK); | 3042 | ASSERT_EQ(plugin->ProcessWebVTTSampleForCache(track, secondCue), Status::OK); |
| 3033 | - ASSERT_TRUE(plugin->cacheQueue_.HasCache(0)); | 3043 | + ASSERT_TRUE(track->cache->HasCache()); |
| 3034 | - auto flushedFirstCue = plugin->cacheQueue_.Front(0); | 3044 | + auto flushedFirstCue = track->cache->Front(); |
| 3035 | ASSERT_NE(flushedFirstCue, nullptr); | 3045 | ASSERT_NE(flushedFirstCue, nullptr); |
| 3036 | ASSERT_NE(flushedFirstCue->sample, nullptr); | 3046 | ASSERT_NE(flushedFirstCue->sample, nullptr); |
| 3037 | EXPECT_EQ(flushedFirstCue->sample->pts, 1000); | 3047 | EXPECT_EQ(flushedFirstCue->sample->pts, 1000); |
| @@ -3459,7 +3469,9 @@ HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_ParserRefUpdatePos_0002, | |||
| 3459 | HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_ParserRefUpdatePos_0003, TestSize.Level1) | 3469 | HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_ParserRefUpdatePos_0003, TestSize.Level1) |
| 3460 | { | 3470 | { |
| 3461 | ResetPlugin(mpeg4Plugin_, mpeg4Fd_); | 3471 | ResetPlugin(mpeg4Plugin_, mpeg4Fd_); |
| 3462 | - mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(std::make_shared<MPEG4DemuxerPlugin>("avdemux_mpeg4")); | 3472 | + auto basePlugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(MPEG4_PLUGIN_NAME); |
| 3473 | + auto mpeg4Plugin = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin); | ||
| 3474 | + mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(mpeg4Plugin); | ||
| 3463 | Status ret = mpeg4Plugin_->ParserRefUpdatePos(0, true); | 3475 | Status ret = mpeg4Plugin_->ParserRefUpdatePos(0, true); |
| 3464 | EXPECT_EQ(ret, Status::ERROR_UNSUPPORTED_FORMAT); | 3476 | EXPECT_EQ(ret, Status::ERROR_UNSUPPORTED_FORMAT); |
| 3465 | } | 3477 | } |
| @@ -3543,7 +3555,9 @@ HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_GetIFramePos_0001, TestS | |||
| 3543 | HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_GetIFramePos_0002, TestSize.Level1) | 3555 | HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_GetIFramePos_0002, TestSize.Level1) |
| 3544 | { | 3556 | { |
| 3545 | ResetPlugin(mpeg4Plugin_, mpeg4Fd_); | 3557 | ResetPlugin(mpeg4Plugin_, mpeg4Fd_); |
| 3546 | - mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(std::make_shared<MPEG4DemuxerPlugin>("avdemux_mpeg4")); | 3558 | + auto basePlugin = Plugins::PluginManagerV2::Instance().CreatePluginByName(MPEG4_PLUGIN_NAME); |
| 3559 | + auto mpeg4Plugin = std::reinterpret_pointer_cast<FFmpegDemuxerPlugin>(basePlugin); | ||
| 3560 | + mpeg4Plugin_ = std::static_pointer_cast<BaseDemuxerPlugin>(mpeg4Plugin); | ||
| 3547 | std::vector<uint32_t> IFramePos; | 3561 | std::vector<uint32_t> IFramePos; |
| 3548 | mpeg4Plugin_->GetIFramePos(IFramePos); | 3562 | mpeg4Plugin_->GetIFramePos(IFramePos); |
| 3549 | EXPECT_EQ(IFramePos.size(), 0); | 3563 | EXPECT_EQ(IFramePos.size(), 0); |


上方 581 行已对 nalSize == 0 执行 continue,此处 nalSize < 0x01 的下界判断对无符号 nalSize 恒为 false,已成为死代码。本次实际语义变更是允许 nalSize == 1 通过。建议移除冗余的下界比较或改为注释说明意图,避免误导后续维护者。
reviewed by agent