mirror of
https://gitee.com/openharmony/multimedia_av_codec
synced 2024-10-06 21:55:22 +00:00
commit
815fbb5081
@ -69,32 +69,37 @@ constexpr size_t MAX_BUFFERING_TIME_OUT = 30 * 1000;
|
||||
|
||||
// hls manifest, m3u8 --- content get from m3u8 url, we get play list from the content
|
||||
// fragment --- one item in play list, download media data according to the fragment address.
|
||||
HlsMediaDownloader::HlsMediaDownloader() noexcept
|
||||
HlsMediaDownloader::HlsMediaDownloader(const std::map<std::string, std::string>& httpHeader) noexcept
|
||||
{
|
||||
cacheMediaBuffer_ = std::make_shared<CacheMediaChunkBufferHlsImpl>();
|
||||
cacheMediaBuffer_->Init(MAX_CACHE_BUFFER_SIZE, CHUNK_SIZE);
|
||||
isBuffering_ = true;
|
||||
totalBufferSize_ = MAX_CACHE_BUFFER_SIZE;
|
||||
httpHeader_ = httpHeader;
|
||||
MEDIA_LOG_I("HLS setting buffer size: " PUBLIC_LOG_ZU, totalBufferSize_);
|
||||
HlsInit();
|
||||
}
|
||||
|
||||
HlsMediaDownloader::HlsMediaDownloader(int expectBufferDuration)
|
||||
HlsMediaDownloader::HlsMediaDownloader(int expectBufferDuration,
|
||||
const std::map<std::string, std::string>& httpHeader) noexcept
|
||||
{
|
||||
expectDuration_ = static_cast<uint64_t>(expectBufferDuration);
|
||||
userDefinedBufferDuration_ = true;
|
||||
totalBufferSize_ = expectDuration_ * CURRENT_BIT_RATE;
|
||||
httpHeader_ = httpHeader;
|
||||
MEDIA_LOG_I("HLS user define buffer duration.");
|
||||
MEDIA_LOG_I("HLS setting buffer size: " PUBLIC_LOG_ZU, totalBufferSize_);
|
||||
HlsInit();
|
||||
}
|
||||
|
||||
HlsMediaDownloader::HlsMediaDownloader(std::string mimeType)
|
||||
HlsMediaDownloader::HlsMediaDownloader(std::string mimeType,
|
||||
const std::map<std::string, std::string>& httpHeader) noexcept
|
||||
{
|
||||
mimeType_ = mimeType;
|
||||
cacheMediaBuffer_ = std::make_shared<CacheMediaChunkBufferHlsImpl>();
|
||||
cacheMediaBuffer_->Init(MAX_CACHE_BUFFER_SIZE, CHUNK_SIZE);
|
||||
totalBufferSize_ = MAX_CACHE_BUFFER_SIZE;
|
||||
httpHeader_ = httpHeader;
|
||||
MEDIA_LOG_I("HLS setting buffer size: " PUBLIC_LOG_ZU, totalBufferSize_);
|
||||
HlsInit();
|
||||
}
|
||||
@ -106,7 +111,7 @@ void HlsMediaDownloader::HlsInit()
|
||||
dataSave_ = [this] (uint8_t*&& data, uint32_t&& len) {
|
||||
return SaveData(std::forward<decltype(data)>(data), std::forward<decltype(len)>(len));
|
||||
};
|
||||
playlistDownloader_ = std::make_shared<HlsPlayListDownloader>();
|
||||
playlistDownloader_ = std::make_shared<HlsPlayListDownloader>(httpHeader_);
|
||||
playlistDownloader_->SetPlayListCallback(this);
|
||||
writeBitrateCaculator_ = std::make_shared<WriteBitrateCaculator>();
|
||||
waterLineAbove_ = PLAY_WATER_LINE;
|
||||
@ -518,7 +523,7 @@ bool HlsMediaDownloader::SeekToTime(int64_t seekTime, SeekMode mode)
|
||||
isNearSeek_ = true;
|
||||
seekTime_ = static_cast<uint64_t>(seekTime);
|
||||
PrepareToSeek();
|
||||
if (seekTime_ < playlistDownloader_->GetDuration()) {
|
||||
if (seekTime_ < static_cast<uint64_t>(playlistDownloader_->GetDuration())) {
|
||||
SeekToTs(seekTime, mode);
|
||||
} else {
|
||||
readTsIndex_ = backPlayList_.size() > 0 ? backPlayList_.size() - 1 : 0; // 0
|
||||
|
@ -52,9 +52,12 @@ constexpr size_t MIN_BUFFER_SIZE = 5 * 1024 * 1024;
|
||||
|
||||
class HlsMediaDownloader : public MediaDownloader, public PlayListChangeCallback {
|
||||
public:
|
||||
HlsMediaDownloader() noexcept;
|
||||
explicit HlsMediaDownloader(int expectBufferDuration);
|
||||
explicit HlsMediaDownloader(std::string mimeType);
|
||||
explicit HlsMediaDownloader(
|
||||
const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>()) noexcept;
|
||||
explicit HlsMediaDownloader(int expectBufferDuration,
|
||||
const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>()) noexcept;
|
||||
explicit HlsMediaDownloader(std::string mimeType,
|
||||
const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>()) noexcept;
|
||||
~HlsMediaDownloader() override;
|
||||
bool Open(const std::string& url, const std::map<std::string, std::string>& httpHeader) override;
|
||||
void Close(bool isAsync) override;
|
||||
|
@ -160,8 +160,11 @@ void HlsPlayListDownloader::ParseManifest(const std::string& location, bool isPr
|
||||
url_ = location;
|
||||
}
|
||||
if (!master_) {
|
||||
master_ = std::make_shared<M3U8MasterPlaylist>(playList_, url_);
|
||||
master_ = std::make_shared<M3U8MasterPlaylist>(playList_, url_, httpHeader_);
|
||||
currentVariant_ = master_->defaultVariant_;
|
||||
if (currentVariant_ && currentVariant_->m3u8_) {
|
||||
currentVariant_->m3u8_->httpHeader_ = httpHeader_;
|
||||
}
|
||||
if (!master_->isSimple_) {
|
||||
UpdateManifest();
|
||||
} else {
|
||||
@ -170,22 +173,7 @@ void HlsPlayListDownloader::ParseManifest(const std::string& location, bool isPr
|
||||
NotifyListChange();
|
||||
}
|
||||
} else {
|
||||
if (master_->isSimple_) {
|
||||
bool ret = currentVariant_->m3u8_->Update(playList_, isParseFinished_);
|
||||
master_->isParseSuccess_ = ret;
|
||||
if (ret) {
|
||||
UpdateMasterInfo(isPreParse);
|
||||
NotifyListChange();
|
||||
}
|
||||
} else {
|
||||
currentVariant_ = master_->defaultVariant_;
|
||||
bool ret = currentVariant_->m3u8_->Update(playList_, true);
|
||||
if (ret) {
|
||||
UpdateMasterInfo(isPreParse);
|
||||
master_->isSimple_ = true;
|
||||
NotifyListChange();
|
||||
}
|
||||
}
|
||||
UpdateMasterAndNotifyList(isPreParse);
|
||||
}
|
||||
if (!master_->isParseSuccess_ && eventCallback_ != nullptr) {
|
||||
MEDIA_LOG_E("ParseManifest parse failed.");
|
||||
@ -194,6 +182,28 @@ void HlsPlayListDownloader::ParseManifest(const std::string& location, bool isPr
|
||||
}
|
||||
}
|
||||
|
||||
void HlsPlayListDownloader::UpdateMasterAndNotifyList(bool isPreParse)
|
||||
{
|
||||
bool ret = false;
|
||||
if (!master_->isSimple_) {
|
||||
currentVariant_ = master_->defaultVariant_;
|
||||
}
|
||||
if (currentVariant_ && currentVariant_->m3u8_) {
|
||||
currentVariant_->m3u8_->httpHeader_ = httpHeader_;
|
||||
ret = currentVariant_->m3u8_->Update(playList_, true);
|
||||
}
|
||||
if (master_->isSimple_) {
|
||||
master_->isParseSuccess_ = ret;
|
||||
}
|
||||
if (ret) {
|
||||
if (!master_->isSimple_) {
|
||||
master_->isSimple_ = true;
|
||||
}
|
||||
UpdateMasterInfo(isPreParse);
|
||||
NotifyListChange();
|
||||
}
|
||||
}
|
||||
|
||||
void HlsPlayListDownloader::UpdateMasterInfo(bool isPreParse)
|
||||
{
|
||||
master_->bLive_ = currentVariant_->m3u8_->IsLive();
|
||||
@ -346,7 +356,7 @@ void HlsPlayListDownloader::SetMimeType(const std::string& mimeType)
|
||||
mimeType_ = mimeType;
|
||||
}
|
||||
|
||||
size_t HlsPlayListDownloader::GetSegmentOffset(int tsIndex)
|
||||
size_t HlsPlayListDownloader::GetSegmentOffset(uint32_t tsIndex)
|
||||
{
|
||||
if (master_ && master_->segmentOffsets_.size() > tsIndex) {
|
||||
return master_->segmentOffsets_[tsIndex];
|
||||
|
@ -51,11 +51,12 @@ public:
|
||||
std::shared_ptr<M3U8MasterPlaylist> GetMaster();
|
||||
std::shared_ptr<M3U8VariantStream> GetCurrentVariant();
|
||||
std::shared_ptr<M3U8VariantStream> GetNewVariant();
|
||||
size_t GetSegmentOffset(int tsIndex) override;
|
||||
size_t GetSegmentOffset(uint32_t tsIndex) override;
|
||||
bool GetHLSDiscontinuity() override;
|
||||
|
||||
private:
|
||||
void UpdateMasterInfo(bool isPreParse);
|
||||
void UpdateMasterAndNotifyList(bool isPreParse);
|
||||
private:
|
||||
std::string url_ {};
|
||||
PlayListChangeCallback* callback_ {nullptr};
|
||||
|
@ -307,7 +307,10 @@ void M3U8::DownloadKey()
|
||||
statusCallback_(status, downloader_, std::forward<decltype(request)>(request));
|
||||
};
|
||||
std::string realKeyUrl = UriJoin(uri_, *keyUri_);
|
||||
downloadRequest_ = std::make_shared<DownloadRequest>(realKeyUrl, dataSave_, realStatusCallback, true);
|
||||
RequestInfo requestInfo;
|
||||
requestInfo.url = realKeyUrl;
|
||||
requestInfo.httpHeader = httpHeader_;
|
||||
downloadRequest_ = std::make_shared<DownloadRequest>(dataSave_, realStatusCallback, requestInfo, true);
|
||||
downloader_->Download(downloadRequest_, -1);
|
||||
downloader_->Start();
|
||||
}
|
||||
@ -467,10 +470,12 @@ M3U8VariantStream::M3U8VariantStream(std::string name, std::string uri, std::sha
|
||||
{
|
||||
}
|
||||
|
||||
M3U8MasterPlaylist::M3U8MasterPlaylist(const std::string& playList, const std::string& uri)
|
||||
M3U8MasterPlaylist::M3U8MasterPlaylist(const std::string& playList, const std::string& uri,
|
||||
const std::map<std::string, std::string>& httpHeader)
|
||||
{
|
||||
playList_ = playList;
|
||||
uri_ = uri;
|
||||
httpHeader_ = httpHeader;
|
||||
if (!StrHasPrefix(playList_, "#EXTM3U")) {
|
||||
MEDIA_LOG_I("playlist doesn't start with #EXTM3U ");
|
||||
isParseSuccess_ = false;
|
||||
@ -498,6 +503,7 @@ void M3U8MasterPlaylist::UpdateMediaPlaylist()
|
||||
}
|
||||
segmentOffsets_ = m3u8->segmentOffsets_;
|
||||
discontinuity = m3u8->discontinuity;
|
||||
m3u8->httpHeader_ = httpHeader_;
|
||||
isParseSuccess_ = m3u8->Update(playList_, false);
|
||||
duration_ = m3u8->GetDuration();
|
||||
bLive_ = m3u8->IsLive();
|
||||
|
@ -115,6 +115,7 @@ struct M3U8 {
|
||||
std::atomic<bool> isPlayTypeFound_ {false};
|
||||
bool discontinuity { false };
|
||||
std::vector<size_t> segmentOffsets_;
|
||||
std::map<std::string, std::string> httpHeader_ {};
|
||||
};
|
||||
|
||||
struct M3U8Media {
|
||||
@ -144,7 +145,8 @@ struct M3U8VariantStream {
|
||||
};
|
||||
|
||||
struct M3U8MasterPlaylist {
|
||||
M3U8MasterPlaylist(const std::string& playList, const std::string& uri);
|
||||
M3U8MasterPlaylist(const std::string& playList, const std::string& uri,
|
||||
const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>());
|
||||
void UpdateMediaPlaylist();
|
||||
void UpdateMasterPlaylist();
|
||||
void DownloadSessionKey(std::shared_ptr<Tag>& tag);
|
||||
@ -163,6 +165,7 @@ struct M3U8MasterPlaylist {
|
||||
std::atomic<bool> isParseSuccess_ {true};
|
||||
std::vector<size_t> segmentOffsets_;
|
||||
bool discontinuity { false };
|
||||
std::map<std::string, std::string> httpHeader_ {};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -55,15 +55,18 @@ void PlayListDownloader::PlayListDownloaderInit()
|
||||
});
|
||||
}
|
||||
|
||||
PlayListDownloader::PlayListDownloader()
|
||||
PlayListDownloader::PlayListDownloader(const std::map<std::string, std::string>& httpHeader) noexcept
|
||||
{
|
||||
downloader_ = std::make_shared<Downloader>("hlsPlayList");
|
||||
httpHeader_ = httpHeader;
|
||||
PlayListDownloaderInit();
|
||||
}
|
||||
|
||||
PlayListDownloader::PlayListDownloader(std::shared_ptr<Downloader> downloader)
|
||||
PlayListDownloader::PlayListDownloader(std::shared_ptr<Downloader> downloader,
|
||||
const std::map<std::string, std::string>& httpHeader) noexcept
|
||||
{
|
||||
downloader_ = downloader;
|
||||
httpHeader_ = httpHeader;
|
||||
PlayListDownloaderInit();
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,10 @@ struct PlayListChangeCallback {
|
||||
};
|
||||
class PlayListDownloader {
|
||||
public:
|
||||
PlayListDownloader();
|
||||
explicit PlayListDownloader(std::shared_ptr<Downloader> downloader);
|
||||
explicit PlayListDownloader(
|
||||
const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>()) noexcept;
|
||||
explicit PlayListDownloader(std::shared_ptr<Downloader> downloader,
|
||||
const std::map<std::string, std::string>& httpHeader = std::map<std::string, std::string>()) noexcept;
|
||||
virtual ~PlayListDownloader() = default;
|
||||
|
||||
virtual void Open(const std::string& url, const std::map<std::string, std::string>& httpHeader) = 0;
|
||||
@ -74,7 +76,7 @@ public:
|
||||
std::map<std::string, std::string> GetHttpHeader();
|
||||
void SetAppUid(int32_t appUid);
|
||||
void SetCallback(Callback* cb);
|
||||
virtual size_t GetSegmentOffset(int tsIndex)
|
||||
virtual size_t GetSegmentOffset(uint32_t tsIndex)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ ChunkIterator CacheMediaChunkBufferHlsImpl::SplitFragmentCacheBuffer(FragmentIte
|
||||
totalReadSize_ += newReadSizeInit;
|
||||
newFragmentPos->readTime = Clock::now();
|
||||
newFragmentPos->accessPos = newFragmentPos->chunks.begin();
|
||||
currFragmentIter->dataLength = offset > diff ? offset - diff : 0;
|
||||
currFragmentIter->dataLength = static_cast<int64_t>(offset > diff ? offset - diff : 0);
|
||||
currFragmentIter = newFragmentPos;
|
||||
|
||||
lruCache_.Refer(newFragmentPos->offsetBegin, newFragmentPos);
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
}
|
||||
isTiming_ = true;
|
||||
steadyClock_.Reset();
|
||||
startTime_ = steadyClock_.ElapsedMilliseconds();
|
||||
startTime_ = static_cast<uint64_t>(steadyClock_.ElapsedMilliseconds());
|
||||
}
|
||||
void StopClock()
|
||||
{
|
||||
@ -48,7 +48,7 @@ public:
|
||||
CaculateWriteBitrate();
|
||||
writeBytes_ = 0;
|
||||
isTiming_ = false;
|
||||
stopTime_ = steadyClock_.ElapsedMilliseconds();
|
||||
stopTime_ = static_cast<uint64_t>(steadyClock_.ElapsedMilliseconds());
|
||||
}
|
||||
void ResetClock()
|
||||
{
|
||||
@ -56,7 +56,7 @@ public:
|
||||
CaculateWriteBitrate();
|
||||
writeBytes_ = 0;
|
||||
steadyClock_.Reset();
|
||||
startTime_ = steadyClock_.ElapsedMilliseconds();
|
||||
startTime_ = static_cast<uint64_t>(steadyClock_.ElapsedMilliseconds());
|
||||
}
|
||||
uint64_t GetWriteTime()
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user