[M120 Migration][hbbtv] Audio tracks count notification
[platform/framework/web/chromium-efl.git] / media / filters / pipeline_controller.h
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.
4
5 #ifndef MEDIA_FILTERS_PIPELINE_CONTROLLER_H_
6 #define MEDIA_FILTERS_PIPELINE_CONTROLLER_H_
7
8 #include "base/functional/callback.h"
9 #include "base/memory/raw_ptr.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/threading/thread_checker.h"
12 #include "base/time/time.h"
13 #include "media/base/media_export.h"
14 #include "media/base/pipeline.h"
15 #include "third_party/abseil-cpp/absl/types/optional.h"
16
17 namespace media {
18
19 class CdmContext;
20 class Demuxer;
21
22 // PipelineController wraps a Pipeline to expose the one-at-a-time operations
23 // (Seek(), Suspend(), and Resume()) with a simpler API. Internally it tracks
24 // pending operations and dispatches them when possible. Duplicate requests
25 // (such as seeking twice to the same time) may be elided.
26 //
27 // TODO(sandersd/tguilbert):
28 //   - Expose an operation that replaces the Renderer (via Suspend/Resume).
29 //   - Expose an operation that replaces the Demuxer (via Start/Stop). This will
30 //     also implicitly replace the Renderer.
31 //   - Block invalid calls after an error occurs.
32 class MEDIA_EXPORT PipelineController {
33  public:
34   enum class State {
35     STOPPED,
36     STARTING,
37     PLAYING,
38     PLAYING_OR_SUSPENDED,
39     SEEKING,
40     SWITCHING_TRACKS,
41     SUSPENDING,
42     SUSPENDED,
43     RESUMING,
44   };
45
46   using SeekedCB = base::RepeatingCallback<void(bool time_updated)>;
47   using SuspendedCB = base::RepeatingClosure;
48   using BeforeResumeCB = base::RepeatingClosure;
49   using ResumedCB = base::RepeatingClosure;
50   using CdmAttachedCB = base::OnceCallback<void(bool)>;
51
52   // Construct a PipelineController wrapping |pipeline_|.
53   // The callbacks are:
54   //   - |seeked_cb| is called upon reaching a stable state if a seek occurred.
55   //   - |suspended_cb| is called immediately after suspending.
56   //   - |before_resume_cb| is called immediately before resuming.
57   //   - |resumed_cb| is called immediately after resuming.
58   //   - |error_cb| is called if any operation on |pipeline_| does not result
59   //     in PIPELINE_OK or its error callback is called.
60   PipelineController(std::unique_ptr<Pipeline> pipeline,
61                      SeekedCB seeked_cb,
62                      SuspendedCB suspended_cb,
63                      BeforeResumeCB before_resume_cb,
64                      ResumedCB resumed_cb,
65                      PipelineStatusCB error_cb);
66
67   PipelineController(const PipelineController&) = delete;
68   PipelineController& operator=(const PipelineController&) = delete;
69
70   ~PipelineController();
71
72   // Start |pipeline_|. |demuxer| will be retained and StartWaitingForSeek()/
73   // CancelPendingSeek() will be issued to it as necessary.
74   //
75   // When |is_streaming| is true, Resume() will always start at the
76   // beginning of the stream, rather than attempting to seek to the current
77   // time.
78   //
79   // When |is_static| is true, seeks to the current time may be elided.
80   // Otherwise it is assumed that the media data may have changed.
81   //
82   // The remaining parameters are just passed directly to pipeline_.Start().
83   void Start(Pipeline::StartType start_type,
84              Demuxer* demuxer,
85              Pipeline::Client* client,
86              bool is_streaming,
87              bool is_static);
88
89   // Request a seek to |time|. If |time_updated| is true, then the eventual
90   // |seeked_cb| callback will also have |time_updated| set to true; it
91   // indicates that the seek was requested by Blink and a time update is
92   // expected so that Blink can fire the seeked event.
93   //
94   // Note: This will not resume the pipeline if it is in the suspended state; a
95   // call to Resume() is required. |seeked_cb_| will not be called until the
96   // later Resume() completes. The intention is to avoid unnecessary wake-ups
97   // for suspended players.
98   void Seek(base::TimeDelta time, bool time_updated);
99
100   // Request that |pipeline_| be suspended. This is a no-op if |pipeline_| has
101   // been suspended.
102   void Suspend();
103
104   // Request that |pipeline_| be resumed. This is a no-op if |pipeline_| has not
105   // been suspended.
106   void Resume();
107
108   // Called when a decoder in the pipeline lost its state. This requires a seek
109   // so that the decoder can start from a new key frame.
110   void OnDecoderStateLost();
111
112   // Returns true if the current state is stable. This means that |state_| is
113   // PLAYING and there are no pending operations. Requests are processed
114   // immediately when the state is stable, otherwise they are queued.
115   //
116   // Exceptions to the above:
117   //   - Start() is processed immediately while in the CREATED state.
118   //   - Resume() is processed immediately while in the SUSPENDED state.
119   bool IsStable();
120
121   // Returns true if the current target state is suspended.
122   bool IsSuspended();
123
124   // Returns true if Seek() was called and there is a seek operation which has
125   // not yet completed.
126   bool IsPendingSeek();
127
128   // Returns true if |pipeline_| is suspended.
129   bool IsPipelineSuspended();
130
131   // Subset of the Pipeline interface directly exposing |pipeline_|.
132   void Stop();
133   bool IsPipelineRunning() const;
134   double GetPlaybackRate() const;
135   void SetPlaybackRate(double playback_rate);
136   float GetVolume() const;
137   void SetVolume(float volume);
138   void SetLatencyHint(absl::optional<base::TimeDelta> latency_hint);
139   void SetPreservesPitch(bool preserves_pitch);
140   void SetWasPlayedWithUserActivation(bool was_played_with_user_activation);
141   base::TimeDelta GetMediaTime() const;
142   Ranges<base::TimeDelta> GetBufferedTimeRanges() const;
143   base::TimeDelta GetMediaDuration() const;
144   bool DidLoadingProgress();
145   PipelineStatistics GetStatistics() const;
146   void SetCdm(CdmContext* cdm_context, CdmAttachedCB cdm_attached_cb);
147   void OnEnabledAudioTracksChanged(
148       const std::vector<MediaTrack::Id>& enabled_track_ids);
149   void OnSelectedVideoTrackChanged(
150       absl::optional<MediaTrack::Id> selected_track_id);
151   void OnExternalVideoFrameRequest();
152
153   // Used to fire the OnTrackChangeComplete function which is captured in a
154   // OnceCallback, and doesn't play nicely with gmock.
155   void FireOnTrackChangeCompleteForTesting(State set_to);
156
157 #if defined(TIZEN_MULTIMEDIA)
158   using ToggledFullscreenCB = base::OnceCallback<void()>;
159   void ToggleFullscreenMode(bool is_fullscreen, ToggledFullscreenCB cb);
160 #endif
161
162 #if defined(TIZEN_VIDEO_HOLE)
163   void SetMediaGeometry(gfx::RectF rect_f);
164 #endif
165
166 #if BUILDFLAG(IS_TIZEN_TV)
167   void SetContentMimeType(const std::string& mime_type);
168   void AudioTracksCountChanged(unsigned count);
169   void SetParentalRatingResult(bool is_pass);
170   void SetActiveTextTrack(int id, bool is_in_band);
171   void SetActiveAudioTrack(int index);
172   void SetActiveVideoTrack(int index);
173   void SetPreferTextLanguage(const std::string& lang);
174   double GetStartDate() const;
175   void DestroyPlayerSync(base::OnceClosure cb);
176 #endif
177  private:
178   // Attempts to make progress from the current state to the target state.
179   void Dispatch();
180
181   // PipelineStaus callback that also carries the target state.
182   void OnPipelineStatus(State state, PipelineStatus pipeline_status);
183
184   void OnTrackChangeComplete();
185
186   // The Pipeline we are managing state for.
187   std::unique_ptr<Pipeline> pipeline_;
188
189   // Called after seeks (which includes Start()) upon reaching a stable state.
190   // Multiple seeks result in only one callback if no stable state occurs
191   // between them.
192   const SeekedCB seeked_cb_;
193
194   // Called immediately when |pipeline_| completes a suspend operation.
195   const SuspendedCB suspended_cb_;
196
197   // Called immediately before |pipeline_| starts a resume operation.
198   const BeforeResumeCB before_resume_cb_;
199
200   // Called immediately when |pipeline_| completes a resume operation.
201   const ResumedCB resumed_cb_;
202
203   // Called immediately when any operation on |pipeline_| results in an error.
204   const PipelineStatusCB error_cb_;
205
206   // State for handling StartWaitingForSeek()/CancelPendingSeek().
207   raw_ptr<Demuxer> demuxer_ = nullptr;
208   bool waiting_for_seek_ = false;
209
210   // When true, Resume() will start at time zero instead of seeking to the
211   // current time.
212   bool is_streaming_ = false;
213
214   // When true, seeking to the current time may be elided.
215   bool is_static_ = true;
216
217   // Tracks the current state of |pipeline_|.
218   State state_ = State::STOPPED;
219
220   // The previous state of |pipeline_| if it's currently undergoing a track
221   // change.
222   State previous_track_change_state_ = State::STOPPED;
223
224   // Indicates that a seek has occurred. When set, a seeked callback will be
225   // issued at the next stable state.
226   bool pending_seeked_cb_ = false;
227
228   // Indicates that a seek has occurred from an explicit call to Seek() or
229   // OnDecoderStateLost().
230   bool pending_seek_except_start_ = false;
231
232   // Indicates that time has been changed by a seek, which will be reported at
233   // the next seeked callback.
234   bool pending_time_updated_ = false;
235
236   // The target time of the active seek; valid while SEEKING or RESUMING.
237   base::TimeDelta seek_time_;
238
239   // Target state which we will work to achieve.
240   bool pending_seek_ = false;
241   bool pending_suspend_ = false;
242   bool pending_resume_ = false;
243   bool pending_audio_track_change_ = false;
244   bool pending_video_track_change_ = false;
245
246   // |pending_seek_time_| is only valid when |pending_seek_| is true.
247   // |pending_track_change_type_| is only valid when |pending_track_change_|.
248   // |pending_audio_track_change_ids_| is only valid when
249   //   |pending_audio_track_change_|.
250   // |pending_video_track_change_id_| is only valid when
251   //   |pending_video_track_change_|.
252   base::TimeDelta pending_seek_time_;
253   std::vector<MediaTrack::Id> pending_audio_track_change_ids_;
254   absl::optional<MediaTrack::Id> pending_video_track_change_id_;
255
256   // Set to true during Start(). Indicates that |seeked_cb_| must be fired once
257   // we've completed startup.
258   bool pending_startup_ = false;
259
260   base::ThreadChecker thread_checker_;
261   base::WeakPtrFactory<PipelineController> weak_factory_{this};
262 };
263
264 }  // namespace media
265
266 #endif  // MEDIA_FILTERS_PIPELINE_CONTROLLER_H_