// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef MEDIA_FILTERS_ESPLUSPLAYER_BUFFER_OBSERVER_H_
-#define MEDIA_FILTERS_ESPLUSPLAYER_BUFFER_OBSERVER_H_
-
-#include <esplusplayer_capi.h>
+#ifndef MEDIA_FILTERS_BUFFER_OBSERVER_H_
+#define MEDIA_FILTERS_BUFFER_OBSERVER_H_
#include "media/base/demuxer_stream.h"
namespace media {
-
-using espp_buffer_size_t = uint64_t;
+using player_buffer_size_t = unsigned long long;
// Buffering level in percent.
-const int kUnderrunBufferThreshold = 1;
-const int kMinBufferThreshold = 30;
-const int kMaxBufferThreshold = 80;
-const int kOverflowBufferThreshold = 95;
-const int kMediaStreamBufferMinThreshold = 100;
+constexpr int kUnderrunBufferThreshold = 1;
+constexpr int kMinBufferThreshold = 30;
+constexpr int kMaxBufferThreshold = 80;
+constexpr int kOverflowBufferThreshold = 95;
+constexpr int kMediaStreamBufferMinThreshold = 100;
// Limit of platform player's audio or video buffer in milliseconds
-const int kMaxBufferTime = 3000;
+constexpr int kMaxBufferTime = 3000;
// Minimum platform player buffer fill to keep
-const int kMinBufferTimePercent = 80;
+constexpr int kMinBufferTimePercent = 80;
enum BufferStatus {
kBufferNone,
kBufferEos,
};
+// An interface for processing media buffering-related callback from player.
class BufferObserver {
public:
using BufferingCallback =
base::RepeatingCallback<void(DemuxerStream::Type, BufferStatus)>;
- static BufferObserver* CreateBufferObserver();
-
virtual ~BufferObserver() = default;
- virtual void SetBufferSize(DemuxerStream::Type, espp_buffer_size_t) = 0;
+ virtual void SetBufferSize(DemuxerStream::Type, player_buffer_size_t) = 0;
virtual void SetBufferingCallback(const BufferingCallback&) = 0;
virtual void SetEos(DemuxerStream::Type) = 0;
- virtual void UpdateBufferedSize(DemuxerStream::Type, espp_buffer_size_t) = 0;
virtual void ResetBufferStatus() = 0;
- virtual void ResetBufferStatusCallbacks(esplusplayer_handle) = 0;
- virtual int SetMediaStreamStatusCallback(
- esplusplayer_handle,
- esplusplayer_stream_type stream_type) = 0;
+ virtual void ResetBufferStatusCallbacks() = 0;
+ virtual int SetMediaStreamStatusCallback(DemuxerStream::Type type) = 0;
virtual BufferStatus GetAudioStatus() const = 0;
virtual BufferStatus GetVideoStatus() const = 0;
virtual void SetAudioVideoDtsDifference(int diff) = 0;
};
} // namespace media
-#endif // MEDIA_FILTERS_ESPLUSPLAYER_BUFFER_OBSERVER_H_
+#endif // MEDIA_FILTERS_BUFFER_OBSERVER_H_
namespace media {
// static
-BufferObserver* BufferObserver::CreateBufferObserver() {
- return new BufferObserverImpl();
-}
-
-// static
-void BufferObserverImpl::OnBufferedSizeChanged(
+void ESPlusPlayerBufferObserverImpl::OnBufferedSizeChanged(
const esplusplayer_stream_type stream_type,
const esplusplayer_buffer_status status,
- espp_buffer_size_t bytes,
+ player_buffer_size_t bytes,
void* user_data) {
if (stream_type == ESPLUSPLAYER_STREAM_TYPE_VIDEO) {
- static_cast<BufferObserver*>(user_data)->UpdateBufferedSize(
+ static_cast<ESPlusPlayerBufferObserverImpl*>(user_data)->UpdateBufferedSize(
DemuxerStream::VIDEO, bytes);
} else if (stream_type == ESPLUSPLAYER_STREAM_TYPE_AUDIO) {
- static_cast<BufferObserver*>(user_data)->UpdateBufferedSize(
+ static_cast<ESPlusPlayerBufferObserverImpl*>(user_data)->UpdateBufferedSize(
DemuxerStream::AUDIO, bytes);
}
}
// static
-void BufferObserverImpl::OnBufferedTimeChanged(
+void ESPlusPlayerBufferObserverImpl::OnBufferedTimeChanged(
const esplusplayer_stream_type stream_type,
const esplusplayer_buffer_status status,
uint64_t time,
void* user_data) {
if (stream_type == ESPLUSPLAYER_STREAM_TYPE_AUDIO) {
- static_cast<BufferObserverImpl*>(user_data)->SetNewStatusFromTime(
- DemuxerStream::AUDIO, time);
+ static_cast<ESPlusPlayerBufferObserverImpl*>(user_data)
+ ->SetNewStatusFromTime(DemuxerStream::AUDIO, time);
} else if (stream_type == ESPLUSPLAYER_STREAM_TYPE_VIDEO) {
- static_cast<BufferObserverImpl*>(user_data)->SetNewStatusFromTime(
- DemuxerStream::VIDEO, time);
+ static_cast<ESPlusPlayerBufferObserverImpl*>(user_data)
+ ->SetNewStatusFromTime(DemuxerStream::VIDEO, time);
}
}
// static
-int BufferObserverImpl::ToPercent(uint64_t value, uint64_t max) {
+int ESPlusPlayerBufferObserverImpl::ToPercent(uint64_t value, uint64_t max) {
return (value * 100 / max) ?: (value > 0);
}
-void BufferObserverImpl::SetBufferSize(DemuxerStream::Type type,
- espp_buffer_size_t size) {
+ESPlusPlayerBufferObserverImpl::ESPlusPlayerBufferObserverImpl(
+ void* esplusplayer_handle)
+ : player_handle_(esplusplayer_handle),
+ task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
+ weak_factory_(this) {}
+
+ESPlusPlayerBufferObserverImpl::~ESPlusPlayerBufferObserverImpl() {}
+
+void ESPlusPlayerBufferObserverImpl::SetBufferSize(DemuxerStream::Type type,
+ player_buffer_size_t size) {
GetBuffer(type).buffer_size = size;
}
-// |handler| will be invoked from capi-player's thread.
-void BufferObserverImpl::SetBufferingCallback(
+void ESPlusPlayerBufferObserverImpl::SetBufferingCallback(
const BufferingCallback& handler) {
buffering_callback_ = handler;
}
-void BufferObserverImpl::SetEos(DemuxerStream::Type type) {
+void ESPlusPlayerBufferObserverImpl::SetEos(DemuxerStream::Type type) {
if (GetBuffer(type).last_buffer_status != kBufferEos) {
CallbackIfNeed(type, kBufferEos);
}
}
-void BufferObserverImpl::UpdateBufferedSize(DemuxerStream::Type type,
- espp_buffer_size_t bytes) {
+void ESPlusPlayerBufferObserverImpl::UpdateBufferedSize(
+ DemuxerStream::Type type,
+ player_buffer_size_t bytes) {
auto& buffer = GetBuffer(type);
DCHECK(buffer.buffer_size != 0);
CallbackIfNeed(type, buffer_status);
}
-void BufferObserverImpl::ResetBufferStatus() {
+void ESPlusPlayerBufferObserverImpl::ResetBufferStatus() {
for (auto& buffer : buffers_) {
buffer.last_buffer_status = kBufferNone;
}
}
-int BufferObserverImpl::SetMediaStreamStatusCallback(
- esplusplayer_handle player,
- esplusplayer_stream_type stream_type) {
+int ESPlusPlayerBufferObserverImpl::SetMediaStreamStatusCallback(
+ DemuxerStream::Type type) {
const BufferStatusCallbacks callbacks = {
- BufferObserverImpl::OnBufferedSizeChanged,
- BufferObserverImpl::OnBufferedTimeChanged};
- return SetBufferStatusCallbacks(player, stream_type, callbacks);
+ ESPlusPlayerBufferObserverImpl::OnBufferedSizeChanged,
+ ESPlusPlayerBufferObserverImpl::OnBufferedTimeChanged};
+ return SetBufferStatusCallbacks(GetESPlusPlayerStreamType(type), callbacks);
}
-BufferStatus BufferObserverImpl::GetAudioStatus() const {
+BufferStatus ESPlusPlayerBufferObserverImpl::GetAudioStatus() const {
return GetBuffer(DemuxerStream::AUDIO).last_buffer_status;
}
-BufferStatus BufferObserverImpl::GetVideoStatus() const {
+BufferStatus ESPlusPlayerBufferObserverImpl::GetVideoStatus() const {
return GetBuffer(DemuxerStream::VIDEO).last_buffer_status;
}
-void BufferObserverImpl::SetAudioVideoDtsDifference(int diff) {
+void ESPlusPlayerBufferObserverImpl::SetAudioVideoDtsDifference(int diff) {
av_diff_ = diff;
if (!EnsureSimilarBufferedDuration()) {
const auto& audio = GetBuffer(DemuxerStream::AUDIO);
}
}
-void BufferObserverImpl::CallbackIfNeed(DemuxerStream::Type type,
- BufferStatus status) {
+void ESPlusPlayerBufferObserverImpl::CallbackIfNeed(DemuxerStream::Type type,
+ BufferStatus status) {
if (buffering_callback_.is_null()) {
LOG(WARNING) << "buffering_callback_ is null, return";
return;
buffer.last_buffer_status = status;
task_runner_->PostTask(
FROM_HERE,
- base::BindOnce(&BufferObserverImpl::TriggerStatusChangeCallback,
- weak_factory_.GetWeakPtr(), type,
- buffer.last_buffer_status));
+ base::BindOnce(
+ &ESPlusPlayerBufferObserverImpl::TriggerStatusChangeCallback,
+ weak_factory_.GetWeakPtr(), type, buffer.last_buffer_status));
}
-void BufferObserverImpl::TriggerStatusChangeCallback(
+void ESPlusPlayerBufferObserverImpl::TriggerStatusChangeCallback(
DemuxerStream::Type type,
BufferStatus status) const {
if (!buffering_callback_.is_null())
buffering_callback_.Run(type, status);
}
-BufferStatus BufferObserverImpl::GetBufferStatusFromSize(int buffered_percent) {
+BufferStatus ESPlusPlayerBufferObserverImpl::GetBufferStatusFromSize(
+ int buffered_percent) {
if (buffered_percent < kUnderrunBufferThreshold) {
return kBufferUnderrun;
} else if (buffered_percent < kMinBufferThreshold) {
return kBufferNormal;
}
-BufferStatus BufferObserverImpl::GetBufferStatusFromTime(
- const BufferObserverImpl::BufferDescriptor& buffer) {
+BufferStatus ESPlusPlayerBufferObserverImpl::GetBufferStatusFromTime(
+ const ESPlusPlayerBufferObserverImpl::BufferDescriptor& buffer) {
if (buffer.has_size_overflow)
return kBufferOverflow;
if (buffer.duration_percent < kUnderrunBufferThreshold)
return kBufferNormal;
}
-void BufferObserverImpl::SetNewStatusFromTime(DemuxerStream::Type type,
- uint64_t time) {
+void ESPlusPlayerBufferObserverImpl::SetNewStatusFromTime(
+ DemuxerStream::Type type,
+ uint64_t time) {
auto& buffer = GetBuffer(type);
if (buffer.last_buffer_status == kBufferEos)
return;
CallbackIfNeed(type, GetBufferStatusFromTime(buffer));
}
-bool BufferObserverImpl::EnsureSimilarBufferedDuration() {
+bool ESPlusPlayerBufferObserverImpl::EnsureSimilarBufferedDuration() {
const auto& audio = GetBuffer(DemuxerStream::AUDIO);
const auto& video = GetBuffer(DemuxerStream::VIDEO);
const bool has_both_av = (audio.last_buffer_status != kBufferNone) &&
}
}
-void BufferObserverImpl::ResetBufferStatusCallbacks(
- esplusplayer_handle player) {
- esplusplayer_set_buffer_byte_status_cb(player, nullptr, this);
- esplusplayer_set_buffer_time_status_cb(player, nullptr, this);
+void ESPlusPlayerBufferObserverImpl::ResetBufferStatusCallbacks() {
+ esplusplayer_set_buffer_byte_status_cb(player_handle_, nullptr, this);
+ esplusplayer_set_buffer_time_status_cb(player_handle_, nullptr, this);
buffering_callback_.Reset();
}
-int BufferObserverImpl::SetBufferStatusCallbacks(
- esplusplayer_handle player,
+int ESPlusPlayerBufferObserverImpl::SetBufferStatusCallbacks(
esplusplayer_stream_type type,
const BufferStatusCallbacks& callbacks) {
int ret{ESPLUSPLAYER_ERROR_TYPE_NONE};
? ESPLUSPLAYER_BUFFER_VIDEO_MIN_BYTE_THRESHOLD
: ESPLUSPLAYER_BUFFER_AUDIO_MIN_BYTE_THRESHOLD;
- if ((ret = esplusplayer_set_buffer_size(player, option,
+ if ((ret = esplusplayer_set_buffer_size(player_handle_, option,
kMediaStreamBufferMinThreshold)) !=
ESPLUSPLAYER_ERROR_TYPE_NONE) {
LOG(WARNING) << "Failed setting buffer size threshold: " << ret;
}
if ((ret = esplusplayer_set_buffer_byte_status_cb(
- player, callbacks.size_status_cb, this)) !=
+ player_handle_, callbacks.size_status_cb, this)) !=
ESPLUSPLAYER_ERROR_TYPE_NONE) {
LOG(WARNING) << "Failed setting buffer size status callback: " << ret;
}
option = (type == ESPLUSPLAYER_STREAM_TYPE_VIDEO)
? ESPLUSPLAYER_BUFFER_VIDEO_MAX_TIME_SIZE
: ESPLUSPLAYER_BUFFER_AUDIO_MAX_TIME_SIZE;
- if ((ret = esplusplayer_set_buffer_size(player, option, kMaxBufferTime)) !=
+ if ((ret = esplusplayer_set_buffer_size(player_handle_, option,
+ kMaxBufferTime)) !=
ESPLUSPLAYER_ERROR_TYPE_NONE) {
LOG(WARNING) << "Failed setting buffer time limit: " << ret;
}
// Due to bug in MMPlayer if threshold != 100 then it stops accepting data
// when the threshold is reached instead of when max is reached. Also status
// callbacks stop arriving after this.
- if ((ret = esplusplayer_set_buffer_size(player, option,
+ if ((ret = esplusplayer_set_buffer_size(player_handle_, option,
kMediaStreamBufferMinThreshold)) !=
ESPLUSPLAYER_ERROR_TYPE_NONE) {
LOG(WARNING) << "Failed setting buffer time threshold: " << ret;
// FIXME: TM1 is giving wrong time size for pipeline.
#if BUILDFLAG(IS_TIZEN_TV)
if ((ret = esplusplayer_set_buffer_time_status_cb(
- player, callbacks.time_status_cb, this)) !=
+ player_handle_, callbacks.time_status_cb, this)) !=
ESPLUSPLAYER_ERROR_TYPE_NONE) {
LOG(WARNING) << "Failed setting buffer time status callback: " << ret;
}
return ret;
}
-BufferObserverImpl::BufferDescriptor& BufferObserverImpl::GetBuffer(
- DemuxerStream::Type type) {
+ESPlusPlayerBufferObserverImpl::BufferDescriptor&
+ESPlusPlayerBufferObserverImpl::GetBuffer(DemuxerStream::Type type) {
return buffers_[GetElementryStreamIndex(type)];
}
-const BufferObserverImpl::BufferDescriptor& BufferObserverImpl::GetBuffer(
- DemuxerStream::Type type) const {
+const ESPlusPlayerBufferObserverImpl::BufferDescriptor&
+ESPlusPlayerBufferObserverImpl::GetBuffer(DemuxerStream::Type type) const {
return buffers_[GetElementryStreamIndex(type)];
}
} // namespace media
#ifndef MEDIA_FILTERS_ESPLUSPLAYER_BUFFER_OBSERVER_IMPL_H_
#define MEDIA_FILTERS_ESPLUSPLAYER_BUFFER_OBSERVER_IMPL_H_
-#include "tizen_src/chromium_impl/media/filters/esplusplayer_buffer_observer.h"
+#include "tizen_src/chromium_impl/media/filters/buffer_observer.h"
+
+#include <esplusplayer_capi.h>
#include "base/task/single_thread_task_runner.h"
#include "tizen_src/chromium_impl/media/filters/esplusplayer_util.h"
// (size / time overflow). However only time underrun will be propagated. This
// way buffer fill is generally controlled on time basis.
// This makes it independent of stream bitrate.
-class BufferObserverImpl : public BufferObserver {
+class ESPlusPlayerBufferObserverImpl : public BufferObserver {
public:
- BufferObserverImpl()
- : task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()),
- weak_factory_(this) {}
-
- void SetBufferSize(DemuxerStream::Type, espp_buffer_size_t) final;
+ ESPlusPlayerBufferObserverImpl(void* esplusplayer_handle);
+ ~ESPlusPlayerBufferObserverImpl() override;
- // |handler| will be invoked from player's thread.
+ // BufferObserver Implementation.
+ void SetBufferSize(DemuxerStream::Type, player_buffer_size_t) final;
void SetBufferingCallback(const BufferingCallback&) final;
- void ResetBufferStatusCallbacks(esplusplayer_handle player) final;
void SetEos(DemuxerStream::Type) final;
- void UpdateBufferedSize(DemuxerStream::Type, espp_buffer_size_t) final;
void ResetBufferStatus() final;
- int SetMediaStreamStatusCallback(esplusplayer_handle,
- esplusplayer_stream_type stream_type) final;
+ void ResetBufferStatusCallbacks() final;
+ int SetMediaStreamStatusCallback(DemuxerStream::Type type) final;
BufferStatus GetAudioStatus() const final;
BufferStatus GetVideoStatus() const final;
void SetAudioVideoDtsDifference(int diff) final;
+ void UpdateBufferedSize(DemuxerStream::Type, player_buffer_size_t);
+
private:
struct BufferStatusCallbacks {
esplusplayer_buffer_byte_status_cb size_status_cb;
struct BufferDescriptor {
BufferDescriptor() {}
- espp_buffer_size_t buffer_size{};
+ player_buffer_size_t buffer_size{};
int buffer_percent{};
int duration_percent{};
BufferStatus last_buffer_status{kBufferNone};
static int ToPercent(uint64_t value, uint64_t max);
static void OnBufferedSizeChanged(const esplusplayer_stream_type stream_type,
const esplusplayer_buffer_status status,
- espp_buffer_size_t bytes,
+ player_buffer_size_t bytes,
void* user_data);
static void OnBufferedTimeChanged(const esplusplayer_stream_type stream_type,
const esplusplayer_buffer_status status,
void SetNewStatusFromTime(DemuxerStream::Type type, uint64_t time);
bool EnsureSimilarBufferedDuration();
- int SetBufferStatusCallbacks(esplusplayer_handle player,
- esplusplayer_stream_type type,
+ int SetBufferStatusCallbacks(esplusplayer_stream_type type,
const BufferStatusCallbacks& callbacks);
BufferDescriptor& GetBuffer(DemuxerStream::Type type);
std::atomic<int> av_diff_{};
+ esplusplayer_handle player_handle_;
+
const scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
- base::WeakPtrFactory<BufferObserverImpl> weak_factory_;
+ base::WeakPtrFactory<ESPlusPlayerBufferObserverImpl> weak_factory_;
};
} // namespace media
#include "media/base/decoder_buffer.h"
#include "media/base/renderer_client.h"
#include "third_party/libyuv/include/libyuv/convert.h"
+#include "tizen_src/chromium_impl/media/filters/esplusplayer_buffer_observer_impl.h"
#if defined(TIZEN_VIDEO_HOLE)
#include <Ecore_Wl2.h>
// Wait until there is space in the buffer.
const base::TimeDelta kBufferQueueReadDelay = base::Milliseconds(100);
-espp_buffer_size_t GetMaxAudioBufferSize() {
+player_buffer_size_t GetMaxAudioBufferSize() {
return kPlayerAudioBufferSize;
}
last_frames_.get<DemuxerStream::VIDEO>().first = media::kNoTimestamp;
last_frames_.get<DemuxerStream::VIDEO>().second = media::kNoTimestamp;
- buffer_observer_.reset(BufferObserver::CreateBufferObserver());
+ buffer_observer_.reset(new ESPlusPlayerBufferObserverImpl(esplayer_));
#if defined(TIZEN_VIDEO_HOLE)
LOG(INFO) << __func__ << " is_video_hole_: " << is_video_hole_;
esplusplayer_set_error_cb(esplayer_, nullptr, this);
buffer_observer_->ResetBufferStatus();
- buffer_observer_->ResetBufferStatusCallbacks(esplayer_);
+ buffer_observer_->ResetBufferStatusCallbacks();
volume_ = 1.0;
playback_rate_ = 0.0;
: ESPLUSPLAYER_STATE_NONE);
}
-espp_buffer_size_t MediaPlayerESPlusPlayer::GetMaxVideoBufferSize(
+player_buffer_size_t MediaPlayerESPlusPlayer::GetMaxVideoBufferSize(
media::VideoDecoderConfig video_config) {
return kPlayerTotalBufferSize - kPlayerAudioBufferSize;
}
GetRendererClient(type)->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
return;
}
- buffer_observer_->SetMediaStreamStatusCallback(
- esplayer_, ESPLUSPLAYER_STREAM_TYPE_AUDIO);
+ buffer_observer_->SetMediaStreamStatusCallback(DemuxerStream::AUDIO);
}
- espp_buffer_size_t max_buffer_size = GetMaxAudioBufferSize();
+ player_buffer_size_t max_buffer_size = GetMaxAudioBufferSize();
buffer_observer_->SetBufferSize(type, max_buffer_size);
LOG(INFO) << "Audio Max buffer size " << max_buffer_size;
error = esplusplayer_set_buffer_size(
GetRendererClient(type)->OnError(PIPELINE_ERROR_INITIALIZATION_FAILED);
return;
}
- buffer_observer_->SetMediaStreamStatusCallback(
- esplayer_, ESPLUSPLAYER_STREAM_TYPE_VIDEO);
+ buffer_observer_->SetMediaStreamStatusCallback(DemuxerStream::VIDEO);
}
- espp_buffer_size_t max_buffer_size = GetMaxVideoBufferSize(video_config);
+ player_buffer_size_t max_buffer_size = GetMaxVideoBufferSize(video_config);
buffer_observer_->SetBufferSize(type, max_buffer_size);
LOG(INFO) << "Video Max buffer size " << max_buffer_size;
error = esplusplayer_set_buffer_size(