已合并
[新需求]: 自研MP4性能优化-插件-优化cachequeue,取消map和多余mutex,fix fastinit meta解析问题,264 nalSize解析边界问题 #9356
[新需求]: 自研MP4性能优化-插件-优化cachequeue,取消map和多余mutex,fix fastinit meta解析问题,264 nalSize解析边界问题 #9356
已合并
杨俊晖创建于 11 天前
16 个文件变更+433-187
Mservices/media_engine/plugins/demuxer/common/avc_parser_impl.cpp+1-1
@@ -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 ||
rchdlee
rchdleerchdlee11 天前

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

reviewed by agent

likedislike
585 static_cast<int64_t>(nalSize) > bufEnd - buf) {585 static_cast<int64_t>(nalSize) > bufEnd - buf) {
586 return false;586 return false;
587 }587 }
Mservices/media_engine/plugins/demuxer/common/block_queue_pool.h+0-44
@@ -43,33 +43,6 @@ struct SamplePacket {
43} // namespace Ffmpeg43} // namespace Ffmpeg
44#endif44#endif
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- 
73template<typename T>46template<typename T>
74struct BlockTraits {47struct 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#endif76#endif
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- 
121template <typename T>78template <typename T>
122class BlockQueuePool {79class BlockQueuePool {
123public:80public:
@@ -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#ifdef USE_FF_DEMUXER523#ifdef USE_FF_DEMUXER
568using FfmpegBlockQueuePool = BlockQueuePool<Ffmpeg::SamplePacket>;524using FfmpegBlockQueuePool = BlockQueuePool<Ffmpeg::SamplePacket>;
569#endif525#endif
Mservices/media_engine/plugins/demuxer/common/multi_stream_parser_manager.cpp+15-13
@@ -258,6 +258,7 @@ bool MultiStreamParserManager::ConvertExtraDataToAnnexb(uint32_t trackId, uint8_
258bool MultiStreamParserManager::ConvertPacketToAnnexb(258bool 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(
266bool MultiStreamParserManager::ConvertPacketToAnnexb(267bool 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 
273void MultiStreamParserManager::ParseAnnexbExtraData(uint32_t trackId, const uint8_t *sample, int32_t size)275void 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 Plugins296} // namespace Plugins
295} // namespace Media297} // namespace Media
Mservices/media_engine/plugins/demuxer/common/multi_stream_parser_manager.h+1-2
@@ -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);
70private:69private:
71 static std::mutex mtx_;70 static std::mutex mtx_;
72 71 
Mservices/media_engine/plugins/demuxer/ffmpeg_demuxer/ffmpeg_demuxer_plugin.cpp+3-1
@@ -2833,7 +2833,9 @@ Status FFmpegDemuxerPlugin::ParseVideoFirstFramesLimited()
2833void FFmpegDemuxerPlugin::ParseHEVCMetadataInfo(const AVStream& avStream, Meta& format)2833void 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 
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_box_parser.cpp+7-33
@@ -26,6 +26,7 @@
26#include <array>26#include <array>
27#include "avc_parser_impl.h"27#include "avc_parser_impl.h"
28#include "avcodec_trace.h"28#include "avcodec_trace.h"
29+#include "common/log.h"
29#include "demuxer_utils.h"30#include "demuxer_utils.h"
30#include "securec.h"31#include "securec.h"
31#include "mpeg4_box_parser.h"32#include "mpeg4_box_parser.h"
@@ -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 // 使用函数指针查找和调用解析函数
rchdlee
rchdleerchdlee11 天前

删除 ShouldParseAtomForFastInit 白名单后,FAST_INIT 模式将解析全部 atom,fastinit 不再“fast”。虽然这能修复 meta 解析遗漏,但属于较粗粒度的改法。建议确认对 fastinit 启动耗时的影响可接受;若影响较大,可改为仅把缺失的 meta 相关 box 加入白名单而非整体移除过滤。

reviewed by agent

likedislike
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- 
5327auto MPEG4AtomParser::FindAtomParser(const MPEG4Atom& atom, ParseContext* ctx) -> ParseFunction5301auto MPEG4AtomParser::FindAtomParser(const MPEG4Atom& atom, ParseContext* ctx) -> ParseFunction
5328{5302{
5329 // 首先查找静态解析函数表5303 // 首先查找静态解析函数表
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_box_parser.h+3-1
@@ -16,12 +16,14 @@
16#ifndef MPEG4_BOX_PARSER_H16#ifndef MPEG4_BOX_PARSER_H
17#define MPEG4_BOX_PARSER_H17#define MPEG4_BOX_PARSER_H
18 18 
19+#include <cstdint>
19#include <memory>20#include <memory>
20#include <set>21#include <set>
21#include <map>22#include <map>
22#include <string>23#include <string>
23#include "converter.h"24#include "converter.h"
24#include "mpeg4_audio_parser.h"25#include "mpeg4_audio_parser.h"
26+#include "mpeg4_sample.h"
25#include "mpeg4_sample_helper.h"27#include "mpeg4_sample_helper.h"
26#include "plugin/plugin_definition.h"28#include "plugin/plugin_definition.h"
27#include "plugin/plugin_info.h"29#include "plugin/plugin_info.h"
@@ -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
149private:152private:
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_;
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_demuxer_plugin.cpp+118-36
@@ -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 tracks1170+ // 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 
1219Status MPEG4DemuxerPlugin::Flush()1218Status 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 
1235void MPEG4DemuxerPlugin::InitBaseInfoByAtomParser(std::shared_ptr<MPEG4AtomParser> parser)1232void 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获取首帧,传入空AVBuffer1448 // 使用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+ 
2538Status MPEG4DemuxerPlugin::AddSampleToCacheQueue(std::shared_ptr<Sample> sample,2619Status 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);
rchdlee
rchdleerchdlee11 天前

(void)PushTrackCache(trackId, cacheSample); 静默丢弃了 Push 失败的返回值。当 track 不存在或 cache 为空(例如某些未走 InitCurrentTrackForTrak/ParseCover 创建缓存的路径)时,sample 会被无声丢弃且无日志。建议至少在失败时 MEDIA_LOG_W 记录 trackId,便于定位丢帧问题。

reviewed by agent

likedislike
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,
2565Status MPEG4DemuxerPlugin::CheckCacheDataLimit(uint32_t trackId)2647Status 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)
2613Status MPEG4DemuxerPlugin::UpdateWebVttCachedSampleDuration(const WebVttReadContext& context,2695Status 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;
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_demuxer_plugin.h+13-2
@@ -28,7 +28,6 @@
28#include "buffer/avbuffer.h"28#include "buffer/avbuffer.h"
29#include "plugin/demuxer_plugin.h"29#include "plugin/demuxer_plugin.h"
30#include "mpeg4_box_parser.h"30#include "mpeg4_box_parser.h"
31-#include "block_queue_pool.h"
32#include "multi_stream_parser_manager.h"31#include "multi_stream_parser_manager.h"
33#include "reference_parser_manager.h"32#include "reference_parser_manager.h"
34#include "common/log.h"33#include "common/log.h"
@@ -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();
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_demuxer_thread.cpp+35-34
@@ -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 
706bool MPEG4DemuxerPlugin::ShouldWaitForRead(uint32_t trackId)704bool MPEG4DemuxerPlugin::ShouldWaitForRead(uint32_t trackId)
707{705{
708- return !cacheQueue_.HasCache(trackId);706+ return !HasTrackCache(trackId);
709}707}
710 708 
711Status MPEG4DemuxerPlugin::EnsureReadLoopStarted()709Status MPEG4DemuxerPlugin::EnsureReadLoopStarted()
@@ -724,7 +722,8 @@ Status MPEG4DemuxerPlugin::EnsureReadLoopStarted()
724Status MPEG4DemuxerPlugin::WaitForLoop(uint32_t trackId, uint32_t timeout)722Status 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+ 
753bool MPEG4DemuxerPlugin::NeedWaitForRead(uint32_t trackId)757bool 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 
759bool MPEG4DemuxerPlugin::IsWebVTTTrack(const std::shared_ptr<MPEG4AtomParser::Track>& track) const763bool 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 
769void MPEG4DemuxerPlugin::AdvanceSampleIndex(const std::shared_ptr<MPEG4AtomParser::Track>& track)769void 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;
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_reference_parser.cpp+1-1
@@ -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}
Aservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_sample.h+203-0
@@ -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+#ifndef MPEG4_SAMPLE_H
17+#define MPEG4_SAMPLE_H
18+ 
19+#include <cstdint>
20+#include <deque>
21+#include <memory>
22+#include <mutex>
23+#include <vector>
24+#include "common/status.h"
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+#endif // MPEG4_SAMPLE_H
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_sample_helper.h+0-1
@@ -24,7 +24,6 @@
24#include <unordered_map>24#include <unordered_map>
25#include <vector>25#include <vector>
26#include "common/status.h"26#include "common/status.h"
27-#include "block_queue_pool.h"
28#include "demuxer_data_reader.h"27#include "demuxer_data_reader.h"
29#include "mpeg4_utils.h"28#include "mpeg4_utils.h"
30 29 
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_sample_helper_index.cpp+1-0
@@ -19,6 +19,7 @@
19#include <limits>19#include <limits>
20 20 
21#include "common/log.h"21#include "common/log.h"
22+#include "mpeg4_sample.h"
22#include "mpeg4_sample_helper.h"23#include "mpeg4_sample_helper.h"
23 24 
24namespace {25namespace {
Mservices/media_engine/plugins/demuxer/mpeg4_demuxer/mpeg4_sample_memory.h+1-1
@@ -18,7 +18,7 @@
18 18 
19#include <memory>19#include <memory>
20#include "buffer/avbuffer.h"20#include "buffer/avbuffer.h"
21-#include "block_queue_pool.h"21+#include "mpeg4_sample.h"
22 22 
23namespace OHOS {23namespace OHOS {
24namespace Media {24namespace Media {
Mtest/unittest/mpeg4_demuxer_plugin_test/mpeg4_demuxer_plugin_unit_test.cpp+31-17
@@ -62,6 +62,7 @@ const std::string TEST_URI_PATH = "http://127.0.0.1:46666/";
62const std::string TEST_RELATIVE_PATH = "/data/test/media/";62const std::string TEST_RELATIVE_PATH = "/data/test/media/";
63const std::string TEST_DEMUXER_RESOURCE_DIR = "/data/test/media";63const std::string TEST_DEMUXER_RESOURCE_DIR = "/data/test/media";
64const std::string FFMPEG_MP4_PLUGIN_NAME = "avdemux_mov,mp4,m4a,3gp,3g2,mj2";64const std::string FFMPEG_MP4_PLUGIN_NAME = "avdemux_mov,mp4,m4a,3gp,3g2,mj2";
65+const std::string MPEG4_PLUGIN_NAME = "avdemux_mpeg4";
65const std::string WEBVTT_MIME = "text/vtt";66const std::string WEBVTT_MIME = "text/vtt";
66const std::string HEVC_LIB_PATH = std::string(AV_CODEC_PATH) + "/libav_codec_hevc_parser.z.so";67const std::string HEVC_LIB_PATH = std::string(AV_CODEC_PATH) + "/libav_codec_hevc_parser.z.so";
67constexpr int32_t WAIT_RETRY_TIMES = 20;68constexpr 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 
1476void Mpeg4DemuxerPluginUnitTest::InitMpeg4Plugin(const std::string& filePath)1478void 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 
1482void Mpeg4DemuxerPluginUnitTest::InitMpeg4PluginURI(const std::string& filePath)1486void 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(
1498void Mpeg4DemuxerPluginUnitTest::InitWeakNetworkMpeg4Plugin(1504void 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,
3459HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_ParserRefUpdatePos_0003, TestSize.Level1)3469HWTEST_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
3543HWTEST_F(Mpeg4DemuxerPluginUnitTest, Mpeg4DemuxerPlugin_GetIFramePos_0002, TestSize.Level1)3555HWTEST_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);