1 // Copyright 2016 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef MEDIA_BASE_PIPELINE_IMPL_H_
6 #define MEDIA_BASE_PIPELINE_IMPL_H_
10 #include "base/memory/raw_ptr.h"
11 #include "base/memory/scoped_refptr.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/task/sequenced_task_runner.h"
14 #include "base/threading/thread_checker.h"
15 #include "base/time/time.h"
16 #include "media/base/media_export.h"
17 #include "media/base/pipeline.h"
18 #include "media/base/renderer.h"
19 #include "media/base/renderer_factory_selector.h"
20 #include "third_party/abseil-cpp/absl/types/optional.h"
23 class SingleThreadTaskRunner;
30 // Callbacks used for Renderer creation. When the RendererType is nullopt, the
31 // current base one will be created.
32 using CreateRendererCB = base::RepeatingCallback<std::unique_ptr<Renderer>(
33 absl::optional<RendererType>)>;
34 using RendererCreatedCB = base::OnceCallback<void(std::unique_ptr<Renderer>)>;
35 using AsyncCreateRendererCB =
36 base::RepeatingCallback<void(absl::optional<RendererType>,
39 // Pipeline runs the media pipeline. Filters are created and called on the
40 // task runner injected into this object. Pipeline works like a state
41 // machine to perform asynchronous initialization, pausing, seeking and playing.
43 // Here's a state diagram that describes the lifetime of this object.
45 // [ *Created ] [ Any State ]
48 // [ Starting ] [ Stopping ]
51 // [ Playing ] <---------. [ Stopped ]
54 // | | [ Seeking ] ---'
56 // | | *TrackChange() |
58 // | [ Switching ] ----'
68 // [ Resuming ] ---------'
70 // Initialization is a series of state transitions from "Created" through each
71 // filter initialization state. When all filter initialization states have
72 // completed, we simulate a Seek() to the beginning of the media to give filters
73 // a chance to preroll. From then on the normal Seek() transitions are carried
74 // out and we start playing the media.
76 // If Stop() is ever called, this object will transition to "Stopped" state.
77 // Pipeline::Stop() is never called from withing PipelineImpl. It's |client_|'s
78 // responsibility to call stop when appropriate.
80 // TODO(sandersd): It should be possible to pass through Suspended when going
81 // from InitDemuxer to InitRenderer, thereby eliminating the Resuming state.
82 // Some annoying differences between the two paths need to be removed first.
83 class MEDIA_EXPORT PipelineImpl : public Pipeline {
85 // Constructs a pipeline that will execute media tasks on |media_task_runner|.
86 // |create_renderer_cb|: to create renderers when starting and resuming.
87 PipelineImpl(scoped_refptr<base::SequencedTaskRunner> media_task_runner,
88 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
89 CreateRendererCB create_renderer_cb,
90 #if defined(TIZEN_VIDEO_HOLE)
95 PipelineImpl(const PipelineImpl&) = delete;
96 PipelineImpl& operator=(const PipelineImpl&) = delete;
98 ~PipelineImpl() override;
100 // Pipeline implementation.
101 void Start(StartType start_type,
104 PipelineStatusCallback seek_cb) override;
105 void Stop() override;
106 void Seek(base::TimeDelta time, PipelineStatusCallback seek_cb) override;
107 void Suspend(PipelineStatusCallback suspend_cb) override;
108 void Resume(base::TimeDelta time, PipelineStatusCallback seek_cb) override;
109 bool IsRunning() const override;
110 bool IsSuspended() const override;
111 double GetPlaybackRate() const override;
112 void SetPlaybackRate(double playback_rate) override;
113 float GetVolume() const override;
114 void SetVolume(float volume) override;
115 void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint) override;
116 void SetPreservesPitch(bool preserves_pitch) override;
117 void SetWasPlayedWithUserActivation(
118 bool was_played_with_user_activation) override;
119 base::TimeDelta GetMediaTime() const override;
120 Ranges<base::TimeDelta> GetBufferedTimeRanges() const override;
121 base::TimeDelta GetMediaDuration() const override;
122 bool DidLoadingProgress() override;
123 PipelineStatistics GetStatistics() const override;
124 void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb) override;
126 #if defined(TIZEN_MULTIMEDIA)
127 void ToggleFullscreenMode(bool is_fullscreen,
128 ToggledFullscreenCB cb) override;
130 #if defined(TIZEN_VIDEO_HOLE)
131 void SetMediaGeometry(const gfx::RectF rect_f) override;
134 // |enabled_track_ids| contains track ids of enabled audio tracks.
135 void OnEnabledAudioTracksChanged(
136 const std::vector<MediaTrack::Id>& enabled_track_ids,
137 base::OnceClosure change_completed_cb) override;
139 // |selected_track_id| is either empty, which means no video track is
140 // selected, or contains the selected video track id.
141 void OnSelectedVideoTrackChanged(
142 absl::optional<MediaTrack::Id> selected_track_id,
143 base::OnceClosure change_completed_cb) override;
145 void OnExternalVideoFrameRequest() override;
148 friend class MediaLog;
149 class RendererWrapper;
151 // Pipeline states, as described above.
152 // TODO(alokp): Move this to RendererWrapper after removing the references
165 static const char* GetStateString(State state);
167 // Create a Renderer asynchronously. Must be called on the main task runner
168 // and the callback will be called on the main task runner as well.
169 void AsyncCreateRenderer(absl::optional<RendererType> renderer_type,
170 RendererCreatedCB renderer_created_cb);
172 // Notifications from RendererWrapper.
173 void OnError(PipelineStatus error);
174 void OnFallback(PipelineStatus fallback);
176 void OnMetadata(const PipelineMetadata& metadata);
177 #if BUILDFLAG(IS_TIZEN_TV)
178 void SetContentMimeType(const std::string& mime_type) override;
179 void NotifyTrackInfoToBrowser(int active_track_id);
180 void SetParentalRatingResult(bool is_pass) override;
181 void AddTrackInfo(media::MediaTrackInfo trackinfo);
182 void SetActiveTextTrack(int id, bool is_in_band) override;
183 void SetActiveAudioTrack(int index) override;
184 void SetActiveVideoTrack(int index) override;
185 void SetPreferTextLanguage(const std::string& lang) override;
186 double GetStartDate() override;
187 void DestroyPlayerSync(base::OnceClosure cb) override;
189 void OnBufferingStateChange(BufferingState state,
190 BufferingStateChangeReason reason);
191 void OnDurationChange(base::TimeDelta duration);
192 void OnWaiting(WaitingReason reason);
193 void OnAudioConfigChange(const AudioDecoderConfig& config);
194 void OnVideoConfigChange(const VideoDecoderConfig& config);
195 void OnVideoNaturalSizeChange(const gfx::Size& size);
196 void OnVideoOpacityChange(bool opaque);
197 void OnVideoAverageKeyframeDistanceUpdate();
198 void OnAudioPipelineInfoChange(const AudioPipelineInfo& info);
199 void OnVideoPipelineInfoChange(const VideoPipelineInfo& info);
200 void OnRemotePlayStateChange(MediaStatus::State state);
201 void OnVideoFrameRateChange(absl::optional<int> fps);
202 #if defined(TIZEN_MULTIMEDIA)
203 void OnRequestSuspend(bool resource_conflicted);
204 void OnSeekableTimeChange(base::TimeDelta min_time,
205 base::TimeDelta max_time,
207 void OnLivePlaybackComplete();
210 // Task completion callbacks from RendererWrapper.
211 void OnSeekDone(bool is_suspended);
212 void OnSuspendDone();
214 // Parameters passed in the constructor.
215 const scoped_refptr<base::SequencedTaskRunner> media_task_runner_;
216 CreateRendererCB create_renderer_cb_;
217 const raw_ptr<MediaLog> media_log_;
219 // Pipeline client. Valid only while the pipeline is running.
220 raw_ptr<Client> client_;
222 // RendererWrapper instance that runs on the media thread.
223 std::unique_ptr<RendererWrapper> renderer_wrapper_;
225 // Temporary callback used for Start(), Seek(), and Resume().
226 PipelineStatusCallback seek_cb_;
228 // Temporary callback used for Suspend().
229 PipelineStatusCallback suspend_cb_;
231 // Current playback rate (>= 0.0). This value is set immediately via
232 // SetPlaybackRate() and a task is dispatched on the task runner to notify
234 double playback_rate_;
236 // Current volume level (from 0.0f to 1.0f). This value is set immediately
237 // via SetVolume() and a task is dispatched on the task runner to notify the
241 // Current duration as reported by Demuxer.
242 base::TimeDelta duration_;
244 // Set by GetMediaTime(), used to prevent the current media time value as
245 // reported to JavaScript from going backwards in time.
246 mutable base::TimeDelta last_media_time_;
248 // Set by Seek(), used in place of asking the renderer for current media time
249 // while a seek is pending. Renderer's time cannot be trusted until the seek
251 base::TimeDelta seek_time_;
253 // Cached suspension state for the RendererWrapper.
256 // 'external_video_frame_request_signaled_' tracks whether we've called
257 // OnExternalVideoFrameRequest on the current renderer. Calls which may
258 // create a new renderer in the RendererWrapper (Start, Resume, SetCdm) will
259 // reset this member. There is no guarantee to the client that
260 // OnExternalVideoFrameRequest will be called only once.
261 bool external_video_frame_request_signaled_ = false;
263 base::ThreadChecker thread_checker_;
264 base::WeakPtrFactory<PipelineImpl> weak_factory_{this};
269 #endif // MEDIA_BASE_PIPELINE_IMPL_H_