[go: nahoru, domu]

blob: d50c92881ead37083595af10a10d80db25086014 [file] [log] [blame]
xhwangbe9da702014-08-23 21:44:551// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
servolkf54f5c8f2015-02-24 20:32:395#ifndef MEDIA_RENDERERS_RENDERER_IMPL_H_
6#define MEDIA_RENDERERS_RENDERER_IMPL_H_
xhwangbe9da702014-08-23 21:44:557
servolkbff54a22017-01-11 01:39:008#include <list>
danakj4d43bc22016-04-26 03:36:049#include <memory>
dalecurtise92934582015-05-12 06:38:0010#include <vector>
11
dalecurtisc11e7bb2015-04-03 05:07:0812#include "base/cancelable_callback.h"
avia82b9b52015-12-19 04:27:0813#include "base/macros.h"
xhwangbe9da702014-08-23 21:44:5514#include "base/memory/ref_counted.h"
xhwangbe9da702014-08-23 21:44:5515#include "base/memory/weak_ptr.h"
16#include "base/synchronization/lock.h"
17#include "base/time/clock.h"
18#include "base/time/default_tick_clock.h"
19#include "base/time/time.h"
Chris Cunningham038548b2017-07-10 22:36:3020#include "media/base/audio_decoder_config.h"
xhwangbe9da702014-08-23 21:44:5521#include "media/base/buffering_state.h"
xhwang97de4202014-11-25 08:44:0122#include "media/base/decryptor.h"
alokp16bbeea2016-05-12 23:32:3623#include "media/base/demuxer_stream.h"
xhwangbe9da702014-08-23 21:44:5524#include "media/base/media_export.h"
25#include "media/base/pipeline_status.h"
26#include "media/base/renderer.h"
Chris Cunningham038548b2017-07-10 22:36:3027#include "media/base/video_decoder_config.h"
alokp5d86e9b2016-05-17 20:20:4128#include "ui/gfx/geometry/size.h"
xhwangbe9da702014-08-23 21:44:5529
30namespace base {
31class SingleThreadTaskRunner;
32}
33
34namespace media {
35
36class AudioRenderer;
servolkcfc91f152017-02-02 05:11:2337class MediaResource;
xhwangbe9da702014-08-23 21:44:5538class TimeSource;
39class VideoRenderer;
scherkusece89452014-09-09 23:13:3840class WallClockTimeSource;
xhwangbe9da702014-08-23 21:44:5541
42class MEDIA_EXPORT RendererImpl : public Renderer {
43 public:
xhwangabd95fd2014-10-03 07:10:0144 // Renders audio/video streams using |audio_renderer| and |video_renderer|
45 // provided. All methods except for GetMediaTime() run on the |task_runner|.
46 // GetMediaTime() runs on the render main thread because it's part of JS sync
47 // API.
xhwangbe9da702014-08-23 21:44:5548 RendererImpl(const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
danakj4d43bc22016-04-26 03:36:0449 std::unique_ptr<AudioRenderer> audio_renderer,
50 std::unique_ptr<VideoRenderer> video_renderer);
xhwangbe9da702014-08-23 21:44:5551
xhwang97de4202014-11-25 08:44:0152 ~RendererImpl() final;
xhwangbe9da702014-08-23 21:44:5553
54 // Renderer implementation.
servolkcfc91f152017-02-02 05:11:2355 void Initialize(MediaResource* media_resource,
alokp16bbeea2016-05-12 23:32:3656 RendererClient* client,
57 const PipelineStatusCB& init_cb) final;
xhwang97de4202014-11-25 08:44:0158 void SetCdm(CdmContext* cdm_context,
59 const CdmAttachedCB& cdm_attached_cb) final;
60 void Flush(const base::Closure& flush_cb) final;
61 void StartPlayingFrom(base::TimeDelta time) final;
a.berwal338bf002015-04-22 11:14:5062 void SetPlaybackRate(double playback_rate) final;
xhwang97de4202014-11-25 08:44:0163 void SetVolume(float volume) final;
64 base::TimeDelta GetMediaTime() final;
Ted Meyerda82b602018-04-19 00:36:5665 void OnSelectedVideoTracksChanged(
66 const std::vector<DemuxerStream*>& enabled_tracks,
67 base::OnceClosure change_completed_cb) override;
68 void OnEnabledAudioTracksChanged(
69 const std::vector<DemuxerStream*>& enabled_tracks,
70 base::OnceClosure change_completed_cb) override;
xhwangbe9da702014-08-23 21:44:5571
72 // Helper functions for testing purposes. Must be called before Initialize().
73 void DisableUnderflowForTesting();
scherkusece89452014-09-09 23:13:3874 void EnableClocklessVideoPlaybackForTesting();
dalecurtisc11e7bb2015-04-03 05:07:0875 void set_time_source_for_testing(TimeSource* time_source) {
76 time_source_ = time_source;
77 }
78 void set_video_underflow_threshold_for_testing(base::TimeDelta threshold) {
79 video_underflow_threshold_ = threshold;
80 }
xhwangbe9da702014-08-23 21:44:5581
82 private:
alokp16bbeea2016-05-12 23:32:3683 class RendererClientInternal;
84
xhwangbe9da702014-08-23 21:44:5585 enum State {
86 STATE_UNINITIALIZED,
xhwanga935e442016-02-11 02:22:4587 STATE_INIT_PENDING_CDM, // Initialization is waiting for the CDM to be set.
88 STATE_INITIALIZING, // Initializing audio/video renderers.
servolka1597ec2017-04-06 19:49:1989 STATE_FLUSHING, // Flushing is in progress.
90 STATE_FLUSHED, // After initialization or after flush completed.
91 STATE_PLAYING, // After StartPlayingFrom has been called.
xhwangbe9da702014-08-23 21:44:5592 STATE_ERROR
93 };
94
dalecurtise92934582015-05-12 06:38:0095 bool GetWallClockTimes(const std::vector<base::TimeDelta>& media_timestamps,
96 std::vector<base::TimeTicks>* wall_clock_times);
xhwangbe9da702014-08-23 21:44:5597
xhwanga935e442016-02-11 02:22:4598 bool HasEncryptedStream();
99
100 void FinishInitialization(PipelineStatus status);
xhwang97de4202014-11-25 08:44:01101
xhwangbe9da702014-08-23 21:44:55102 // Helper functions and callbacks for Initialize().
103 void InitializeAudioRenderer();
104 void OnAudioRendererInitializeDone(PipelineStatus status);
105 void InitializeVideoRenderer();
106 void OnVideoRendererInitializeDone(PipelineStatus status);
107
108 // Helper functions and callbacks for Flush().
servolk16e8bdf82017-04-11 17:00:39109 void FlushInternal();
xhwangbe9da702014-08-23 21:44:55110 void FlushAudioRenderer();
111 void OnAudioRendererFlushDone();
112 void FlushVideoRenderer();
113 void OnVideoRendererFlushDone();
114
servolk16e8bdf82017-04-11 17:00:39115 // Reinitialize audio/video renderer during a demuxer stream switching. The
116 // renderer must be flushed first, and when the re-init is completed the
117 // corresponding callback will be invoked to restart playback.
118 // The |stream| parameter specifies the new demuxer stream, and the |time|
119 // parameter specifies the time on media timeline where the switch occured.
Ted Meyerda82b602018-04-19 00:36:56120 void ReinitializeAudioRenderer(DemuxerStream* stream,
121 base::TimeDelta time,
122 base::OnceClosure reinitialize_completed_cb);
servolk16e8bdf82017-04-11 17:00:39123 void OnAudioRendererReinitialized(DemuxerStream* stream,
124 base::TimeDelta time,
Ted Meyerda82b602018-04-19 00:36:56125 base::OnceClosure reinitialize_completed_cb,
servolk16e8bdf82017-04-11 17:00:39126 PipelineStatus status);
Ted Meyerda82b602018-04-19 00:36:56127 void ReinitializeVideoRenderer(DemuxerStream* stream,
128 base::TimeDelta time,
129 base::OnceClosure restart_completed_cb);
servolk16e8bdf82017-04-11 17:00:39130 void OnVideoRendererReinitialized(DemuxerStream* stream,
131 base::TimeDelta time,
Ted Meyerda82b602018-04-19 00:36:56132 base::OnceClosure restart_completed_cb,
servolk16e8bdf82017-04-11 17:00:39133 PipelineStatus status);
134
135 // Restart audio/video renderer playback after a demuxer stream switch or
136 // after a demuxer stream has been disabled and re-enabled. The |stream|
137 // parameter specifies which stream needs to be restarted. The |time|
138 // parameter specifies the position on the media timeline where the playback
139 // needs to be restarted. It is necessary for demuxers with independent
140 // streams (e.g. MSE / ChunkDemuxer) to synchronize data reading between those
141 // streams.
Ted Meyerda82b602018-04-19 00:36:56142 void RestartAudioRenderer(DemuxerStream* stream,
143 base::TimeDelta time,
144 base::OnceClosure restart_completed_cb);
145 void RestartVideoRenderer(DemuxerStream* stream,
146 base::TimeDelta time,
147 base::OnceClosure restart_completed_cb);
148
149 // Fix state booleans after the stream switching is finished.
150 void CleanUpTrackChange(base::RepeatingClosure on_finished,
151 bool* pending_change,
152 bool* ended,
153 bool* playing);
servolkf25ceed2016-07-01 03:44:38154
xhwangbe9da702014-08-23 21:44:55155 // Callback executed by filters to update statistics.
alokp16bbeea2016-05-12 23:32:36156 void OnStatisticsUpdate(const PipelineStatistics& stats);
xhwangbe9da702014-08-23 21:44:55157
158 // Collection of callback methods and helpers for tracking changes in
159 // buffering state and transition from paused/underflow states and playing
160 // states.
161 //
162 // While in the kPlaying state:
163 // - A waiting to non-waiting transition indicates preroll has completed
164 // and StartPlayback() should be called
165 // - A non-waiting to waiting transition indicates underflow has occurred
166 // and PausePlayback() should be called
alokp16bbeea2016-05-12 23:32:36167 void OnBufferingStateChange(DemuxerStream::Type type,
168 BufferingState new_buffering_state);
servolk16e8bdf82017-04-11 17:00:39169
servolkf25ceed2016-07-01 03:44:38170 // Handles the buffering notifications that we might get while an audio or a
171 // video stream is being restarted. In those cases we don't want to report
172 // underflows immediately and instead give decoders a chance to catch up with
173 // currently playing stream. Returns true if the buffering nofication has been
174 // handled and no further processing is necessary, returns false to indicate
175 // that we should fall back to the regular OnBufferingStateChange logic.
176 bool HandleRestartedStreamBufferingChanges(
177 DemuxerStream::Type type,
178 BufferingState new_buffering_state);
servolk16e8bdf82017-04-11 17:00:39179
xhwangbe9da702014-08-23 21:44:55180 bool WaitingForEnoughData() const;
181 void PausePlayback();
182 void StartPlayback();
183
xhwangbe9da702014-08-23 21:44:55184 // Callbacks executed when a renderer has ended.
alokp16bbeea2016-05-12 23:32:36185 void OnRendererEnded(DemuxerStream::Type type);
scherkusece89452014-09-09 23:13:38186 bool PlaybackHasEnded() const;
xhwangbe9da702014-08-23 21:44:55187 void RunEndedCallbackIfNeeded();
188
189 // Callback executed when a runtime error happens.
190 void OnError(PipelineStatus error);
Chris Cunningham038548b2017-07-10 22:36:30191
alokp16bbeea2016-05-12 23:32:36192 void OnWaitingForDecryptionKey();
alokp5d86e9b2016-05-17 20:20:41193 void OnVideoNaturalSizeChange(const gfx::Size& size);
Chris Cunningham038548b2017-07-10 22:36:30194 void OnAudioConfigChange(const AudioDecoderConfig& config);
195 void OnVideoConfigChange(const VideoDecoderConfig& config);
alokp5d86e9b2016-05-17 20:20:41196 void OnVideoOpacityChange(bool opaque);
xhwangbe9da702014-08-23 21:44:55197
servolkbff54a22017-01-11 01:39:00198 void OnStreamRestartCompleted();
199
xhwangbe9da702014-08-23 21:44:55200 State state_;
201
202 // Task runner used to execute pipeline tasks.
203 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
204
servolkcfc91f152017-02-02 05:11:23205 MediaResource* media_resource_;
alokp16bbeea2016-05-12 23:32:36206 RendererClient* client_;
xhwangbe9da702014-08-23 21:44:55207
208 // Temporary callback used for Initialize() and Flush().
dalecurtis47046112015-01-23 22:58:20209 PipelineStatusCB init_cb_;
xhwangbe9da702014-08-23 21:44:55210 base::Closure flush_cb_;
211
alokp16bbeea2016-05-12 23:32:36212 std::unique_ptr<RendererClientInternal> audio_renderer_client_;
213 std::unique_ptr<RendererClientInternal> video_renderer_client_;
danakj4d43bc22016-04-26 03:36:04214 std::unique_ptr<AudioRenderer> audio_renderer_;
215 std::unique_ptr<VideoRenderer> video_renderer_;
xhwangbe9da702014-08-23 21:44:55216
servolk16e8bdf82017-04-11 17:00:39217 DemuxerStream* current_audio_stream_;
218 DemuxerStream* current_video_stream_;
219
xhwangbe9da702014-08-23 21:44:55220 // Renderer-provided time source used to control playback.
221 TimeSource* time_source_;
danakj4d43bc22016-04-26 03:36:04222 std::unique_ptr<WallClockTimeSource> wall_clock_time_source_;
scherkusece89452014-09-09 23:13:38223 bool time_ticking_;
a.berwal338bf002015-04-22 11:14:50224 double playback_rate_;
xhwangbe9da702014-08-23 21:44:55225
226 // The time to start playback from after starting/seeking has completed.
227 base::TimeDelta start_time_;
228
229 BufferingState audio_buffering_state_;
230 BufferingState video_buffering_state_;
231
232 // Whether we've received the audio/video ended events.
233 bool audio_ended_;
234 bool video_ended_;
Ted Meyerda82b602018-04-19 00:36:56235 bool audio_playing_;
236 bool video_playing_;
xhwangbe9da702014-08-23 21:44:55237
xhwang97de4202014-11-25 08:44:01238 CdmContext* cdm_context_;
xhwang97de4202014-11-25 08:44:01239
xhwangbe9da702014-08-23 21:44:55240 bool underflow_disabled_for_testing_;
scherkusece89452014-09-09 23:13:38241 bool clockless_video_playback_enabled_for_testing_;
xhwangbe9da702014-08-23 21:44:55242
dalecurtisc11e7bb2015-04-03 05:07:08243 // Used to defer underflow for video when audio is present.
servolkf25ceed2016-07-01 03:44:38244 base::CancelableClosure deferred_video_underflow_cb_;
245
246 // Used to defer underflow for audio when restarting audio playback.
247 base::CancelableClosure deferred_audio_restart_underflow_cb_;
dalecurtisc11e7bb2015-04-03 05:07:08248
249 // The amount of time to wait before declaring underflow if the video renderer
250 // runs out of data but the audio renderer still has enough.
251 base::TimeDelta video_underflow_threshold_;
252
servolk9dd6cc82017-05-24 05:39:02253 // Lock used to protect access to the |restarting_audio_| flag and
254 // |restarting_audio_time_|.
255 // TODO(servolk): Get rid of the lock and replace restarting_audio_ with
256 // std::atomic<bool> when atomics are unbanned in Chromium.
257 base::Lock restarting_audio_lock_;
Ted Meyerda82b602018-04-19 00:36:56258 bool pending_audio_track_change_ = false;
servolk9dd6cc82017-05-24 05:39:02259 base::TimeDelta restarting_audio_time_ = kNoTimestamp;
260
Ted Meyerda82b602018-04-19 00:36:56261 bool pending_video_track_change_ = false;
Dale Curtis3defa542017-11-07 00:52:32262
xhwangbe9da702014-08-23 21:44:55263 base::WeakPtr<RendererImpl> weak_this_;
dmichael284c5e92014-12-09 20:02:47264 base::WeakPtrFactory<RendererImpl> weak_factory_;
xhwangbe9da702014-08-23 21:44:55265
266 DISALLOW_COPY_AND_ASSIGN(RendererImpl);
267};
268
269} // namespace media
270
servolkf54f5c8f2015-02-24 20:32:39271#endif // MEDIA_RENDERERS_RENDERER_IMPL_H_