// Wait until there is space in the buffer.
const base::TimeDelta kBufferQueueReadDelay = base::Milliseconds(100);
+// The difference between the played timestamp and
+// the time stamp of the buffered data.
+const base::TimeDelta kMinWaitTimeForPlayback = base::Milliseconds(500);
+
player_buffer_size_t GetMaxAudioBufferSize() {
return kPlayerAudioBufferSize;
}
if (!ReadFromBufferQueue(type))
return;
+ PerformOperationForData();
+
// Avoid unnecessary or redundant read requests.
if (!ShouldFeed(type) || ReadRequested(type) || IsEos(type) ||
(is_prepared_ && is_paused_ && !is_seeking_)) {
void MediaPlayerESPlusPlayer::OnBufferingStatusChanged(DemuxerStream::Type type,
BufferStatus status) {
- DVLOG(INFO) << __func__ << " " << DemuxerStream::GetTypeName(type) << " : "
- << GetString(status);
-
+ LOG(INFO) << __func__ << " " << DemuxerStream::GetTypeName(type) << " : "
+ << GetString(status);
if (expected_seek_ && is_prepared_) {
LOG(INFO) << "Ignore the buffer updates while seek";
return;
}
}
+void MediaPlayerESPlusPlayer::PerformOperationForData() {
+ if (is_seeking_ || is_preparing_)
+ return;
+
+ OperationForData operation = GetOperationForData();
+ switch (operation) {
+ case OperationForData::PLAY:
+ is_paused_by_buffering_ = false;
+ Play();
+ break;
+ case OperationForData::PAUSE:
+ is_paused_by_buffering_ = true;
+ Pause(true);
+ break;
+ }
+}
+
+MediaPlayerESPlusPlayer::OperationForData
+MediaPlayerESPlusPlayer::GetOperationForData() {
+ bool has_video_media_type = GetMediaType() & MediaType::Video;
+ bool has_audio_media_type = GetMediaType() & MediaType::Audio;
+
+ bool has_video_data =
+ !has_video_media_type ||
+ (last_frames_.get<DemuxerStream::VIDEO>().first != media::kNoTimestamp);
+ bool has_audio_data =
+ !has_audio_media_type ||
+ (last_frames_.get<DemuxerStream::AUDIO>().first != media::kNoTimestamp);
+ if (!has_video_data || !has_audio_data) {
+ LOG(INFO) << __func__
+ << " Video or audio data has not yet been pushed. video "
+ << has_video_data << ", audio " << has_audio_data;
+ return OperationForData::NONE;
+ }
+
+ base::TimeDelta current_position = GetCurrentTime();
+
+ if (is_paused_by_buffering_) {
+ // Get the end position of pushed data.
+ base::TimeDelta pushed_end_position =
+ std::min(has_video_media_type
+ ? last_frames_.get<DemuxerStream::VIDEO>().first +
+ last_frames_.get<DemuxerStream::VIDEO>().second
+ : base::TimeDelta::Max(),
+ has_audio_media_type
+ ? last_frames_.get<DemuxerStream::AUDIO>().first +
+ last_frames_.get<DemuxerStream::AUDIO>().second
+ : base::TimeDelta::Max());
+ base::TimeDelta time_diff = pushed_end_position - current_position;
+
+ // If data has been pushed enough (>= kMinWaitTimeForPlayback)
+ if (time_diff >= kMinWaitTimeForPlayback) {
+ LOG(INFO) << __func__ << " Data is enough to play,";
+ return OperationForData::PLAY;
+ }
+ } else {
+ bool should_pause = false;
+ if (has_video_media_type &&
+ current_position >= last_frames_.get<DemuxerStream::VIDEO>().first) {
+ SetBufferingState(DemuxerStream::VIDEO, BUFFERING_HAVE_NOTHING);
+ should_pause = true;
+ }
+ if (has_audio_media_type &&
+ current_position >= last_frames_.get<DemuxerStream::AUDIO>().first) {
+ SetBufferingState(DemuxerStream::AUDIO, BUFFERING_HAVE_NOTHING);
+ should_pause = true;
+ }
+
+ if (should_pause) {
+ LOG(INFO) << __func__ << " Not enough data to play.";
+ // If pushing pts smaller than current_position, should report
+ // BUFFERING_HAVE_NOTHING to replace BUFFERING_HAVE_ENOUGH
+ GetMediaPlayerClient()->OnBufferingStateChange(
+ BUFFERING_HAVE_NOTHING, BUFFERING_CHANGE_REASON_UNKNOWN);
+ return OperationForData::PAUSE;
+ }
+ }
+
+ return OperationForData::NONE;
+}
+
void MediaPlayerESPlusPlayer::OnReadyToPrepare(
const esplusplayer_stream_type stream_type) {
if (!task_runner_->BelongsToCurrentThread()) {
// This class handles media source extensions for CAPI port.
class MEDIA_EXPORT MediaPlayerESPlusPlayer : public MediaPlayerTizen {
public:
+ enum class OperationForData {
+ NONE,
+ PAUSE,
+ PLAY,
+ };
+
MediaPlayerESPlusPlayer();
~MediaPlayerESPlusPlayer() override;
void SeekInternal(base::TimeDelta time);
void UpdateBufferedDtsDifference();
+ void PerformOperationForData();
+ OperationForData GetOperationForData();
+
ElementryStream& GetElementryStream(DemuxerStream::Type type);
const ElementryStream& GetElementryStream(DemuxerStream::Type type) const;
void SetReadRequested(DemuxerStream::Type type, bool value);
bool should_set_playback_rate_ = false;
+ bool is_paused_by_buffering_ = false;
+
#if defined(TIZEN_VIDEO_HOLE)
gfx::Rect viewport_rect_;
std::unique_ptr<VideoPlaneController> video_plane_controller_;