* Copyright (c) 2023-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MEDIA_SOURCE_H
#define MEDIA_SOURCE_H
#include <memory>
#include <string>
#include <utility>
#include <vector>
#include "osal/task/task.h"
#include "osal/utils/util.h"
#include "common/media_source.h"
#include "plugin/plugin_buffer.h"
#include "plugin/plugin_info.h"
#include "plugin/plugin_base.h"
#include "plugin/plugin_event.h"
#include "plugin/source_plugin.h"
#include "meta/media_types.h"
#include "demuxer/media_demuxer.h"
#include "performance_utils.h"
namespace OHOS {
namespace Media {
using SourceType = OHOS::Media::Plugins::SourceType;
using MediaSource = OHOS::Media::Plugins::MediaSource;
class CallbackImpl : public Plugins::Callback {
public:
void OnEvent(const Plugins::PluginEvent &event) override
{
auto callback = callbackWrap_.lock();
if (callback) {
callback->OnEvent(event);
}
}
void OnDfxEvent(const Plugins::PluginDfxEvent &event) override
{
auto callback = callbackWrap_.lock();
if (callback) {
callback->OnDfxEvent(event);
}
}
void SetSelectBitRateFlag(bool flag, uint32_t desBitRate) override
{
auto callback = callbackWrap_.lock();
if (callback) {
callback->SetSelectBitRateFlag(flag, desBitRate);
}
}
bool CanAutoSelectBitRate() override
{
auto callback = callbackWrap_.lock();
if (callback) {
return callback->CanAutoSelectBitRate();
}
return false;
}
void SetCallbackWrap(const std::shared_ptr<Callback>& callbackWrap)
{
callbackWrap_ = callbackWrap;
}
private:
std::weak_ptr<Callback> callbackWrap_;
};
class Source : public Plugins::Callback, public std::enable_shared_from_this<Source> {
public:
explicit Source();
~Source() override;
Source(const Source&) = delete;
Source& operator=(const Source&) = delete;
virtual Status SetSource(const std::shared_ptr<MediaSource>& source);
void SetBundleName(const std::string& bundleName);
Status Prepare();
Status Start();
Status Stop();
Status Pause();
Status Resume();
Status SetReadBlockingFlag(bool isReadBlockingAllowed);
Plugins::Seekable GetSeekable();
std::vector<Plugins::SeekRange> GetSeekableRanges();
Status GetSize(uint64_t &fileSize);
void OnEvent(const Plugins::PluginEvent &event) override;
void OnDfxEvent(const Plugins::PluginDfxEvent &event) override;
void SetSelectBitRateFlag(bool flag, uint32_t desBitRate) override;
bool CanAutoSelectBitRate() override;
bool IsSeekToTimeSupported();
bool IsLocalFd();
int64_t GetDuration();
std::pair<int64_t, bool> GetStartInfo();
Status SeekToTime(int64_t seekTime, SeekMode mode);
Status MediaSeekTimeByStreamId(int64_t seekTime, SeekMode mode, int32_t streamId);
Status SeekTo(uint64_t offset);
Status GetBitRates(std::vector<uint32_t>& bitRates);
Status SelectBitRate(uint32_t bitRate);
Status AutoSelectBitRate(uint32_t bitRate);
Status SetStartPts(int64_t startPts);
Status SetExtraCache(uint64_t cacheDuration);
Status SetMediaDuration(int64_t mediaDuration);
Status SetCurrentBitRate(int32_t bitRate, int32_t streamID);
void SetCallback(const std::shared_ptr<Callback>& callback);
bool IsNeedPreDownload();
void SetDemuxerState(int32_t streamId);
Status GetStreamInfo(std::vector<StreamInfo>& streams, bool isUpdate = false);
Status Read(int32_t streamID, std::shared_ptr<Buffer>& buffer, uint64_t offset, size_t expectedLen);
void SetInterruptState(bool isInterruptNeeded);
Status GetDownloadInfo(DownloadInfo& downloadInfo);
Status GetPlaybackInfo(PlaybackInfo& playbackInfo);
Status SelectStream(int32_t streamID);
void SetEnableOnlineFdCache(bool isEnableFdCache);
size_t GetSegmentOffset();
bool GetHLSDiscontinuity();
void WaitForBufferingEnd();
bool SetInitialBufferSize(int32_t offset, int32_t size);
Status SetPerfRecEnabled(bool perfRecEnabled);
void NotifyInitSuccess();
uint64_t GetCachedDuration();
void RestartAndClearBuffer();
bool IsFlvLive();
bool IsFlvLiveStream() const;
std::string GetContentType();
bool IsHlsFmp4();
uint64_t GetMemorySize();
Status StopBufferring(bool isAppBackground);
bool IsHlsEnd(int32_t streamId = -1);
bool IsHls();
void SetDefaultStreamId(int32_t &videoStreamId, int32_t &audioStreamId, int32_t &subTitleStreamId);
bool IsCloudFd();
void PauseRead();
private:
Status InitPlugin(const std::shared_ptr<MediaSource>& source);
static std::string GetUriSuffix(const std::string& uri);
bool GetProtocolByUri();
bool ParseProtocol(const std::shared_ptr<MediaSource>& source);
Status FindPlugin(const std::shared_ptr<MediaSource>& source);
void ClearData();
Status ReadWithPerfRecord(int32_t streamID, std::shared_ptr<Buffer>& buffer, uint64_t offset, size_t expectedLen);
void OnMediaDemuxerEvent(const Plugins::PluginEvent& event);
std::string protocol_;
bool seekToTimeFlag_{false};
std::string uri_;
Plugins::Seekable seekable_;
std::shared_ptr<Plugins::SourcePlugin> plugin_;
std::shared_ptr<Plugins::PluginInfo> pluginInfo_{};
bool isPluginReady_ {false};
bool isAboveWaterline_ {false};
std::shared_ptr<CallbackImpl> mediaDemuxerCallback_;
std::atomic<bool> isInterruptNeeded_{false};
std::mutex mutex_;
std::condition_variable seekCond_;
bool isEnableFdCache_{ true };
bool perfRecEnabled_ { false };
PerfRecorder perfRecorder_ {};
bool isFlvLiveStream_ {false};
};
}
}
#endif