summaryrefslogtreecommitdiffstats
path: root/dom/media/mediasink/MediaSink.h
blob: 293f0647729a593451a326aacafcbc396073abb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef MediaSink_h_
#define MediaSink_h_

#include "MediaInfo.h"
#include "mozilla/MozPromise.h"
#include "mozilla/RefPtr.h"
#include "mozilla/dom/MediaDebugInfoBinding.h"
#include "nsISupportsImpl.h"

class AudioDeviceInfo;

namespace mozilla {

class TimeStamp;
class VideoFrameContainer;

/**
 * A consumer of audio/video data which plays audio and video tracks and
 * manages A/V sync between them.
 *
 * A typical sink sends audio/video outputs to the speaker and screen.
 * However, there are also sinks which capture the output of an media element
 * and send the output to a MediaStream.
 *
 * This class is used to move A/V sync management and audio/video rendering
 * out of MDSM so it is possible for subclasses to do external rendering using
 * specific hardware which is required by TV projects and CDM.
 *
 * Note this class is not thread-safe and should be called from the state
 * machine thread only.
 */
class MediaSink {
 public:
  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MediaSink);
  typedef mozilla::TrackInfo::TrackType TrackType;

  // EndedPromise needs to be a non-exclusive promise as it is shared between
  // both the AudioSink and VideoSink.
  typedef MozPromise<bool, nsresult, /* IsExclusive = */ false> EndedPromise;

  // Return a promise which is resolved when the track finishes
  // or null if no such track.
  // Must be called after Start().
  // Returns null if the TrackType does not exist or if Stop() has been called.
  virtual RefPtr<EndedPromise> OnEnded(TrackType aType) = 0;

  // Return the end time of the audio/video data that has been consumed
  // or 0 if no such track.
  // Must be called after playback starts.
  virtual media::TimeUnit GetEndTime(TrackType aType) const = 0;

  // Return playback position for the media data.
  // Since A/V sync is always maintained by this sink, there is no need to
  // specify whether we want to get audio or video position.
  // aTimeStamp returns the timeStamp corresponding to the returned position
  // which is used by the compositor to derive the render time of video frames.
  // Must be called after playback starts.
  virtual media::TimeUnit GetPosition(TimeStamp* aTimeStamp = nullptr) = 0;

  // Return true if there are data consumed but not played yet.
  // Can be called in any state.
  virtual bool HasUnplayedFrames(TrackType aType) const = 0;

  // Return the duration of data consumed but not played yet.
  // Can be called in any state.
  virtual media::TimeUnit UnplayedDuration(TrackType aType) const = 0;

  // Set volume of the audio track.
  // Do nothing if this sink has no audio track.
  // Can be called in any state.
  virtual void SetVolume(double aVolume) {}

  // Set the audio stream name.
  // Does nothing if this sink has no audio stream.
  // Can be called in any state.
  virtual void SetStreamName(const nsAString& aStreamName) {}

  // Set the playback rate.
  // Can be called in any state.
  virtual void SetPlaybackRate(double aPlaybackRate) {}

  // Whether to preserve pitch of the audio track.
  // Do nothing if this sink has no audio track.
  // Can be called in any state.
  virtual void SetPreservesPitch(bool aPreservesPitch) {}

  // Pause/resume the playback. Only work after playback starts.
  virtual void SetPlaying(bool aPlaying) = 0;

  // Set the audio output device.  aDevice == nullptr indicates the default
  // device.  The returned promise is resolved when the previous device is no
  // longer in use and an attempt to open the new device completes
  // (successfully or not) or is deemed unnecessary because the device is not
  // required for output at this time.  The promise will be resolved whether
  // or not opening the cubeb_stream succeeds because the aDevice is
  // considered the new underlying device and will be used when it becomes
  // available.
  virtual RefPtr<GenericPromise> SetAudioDevice(
      RefPtr<AudioDeviceInfo> aDevice) = 0;

  // Get the playback rate.
  // Can be called in any state.
  virtual double PlaybackRate() const = 0;

  // Single frame rendering operation may need to be done before playback
  // started (1st frame) or right after seek completed or playback stopped.
  // Do nothing if this sink has no video track. Can be called in any state.
  virtual void Redraw(const VideoInfo& aInfo){};

  // Begin a playback session with the provided start time in the media data
  // and media info.  Must be called when playback is stopped.  aStartTime is
  // compared with MediaData::mTime and continues to increase when looping,
  // unless decoding is reset.
  virtual nsresult Start(const media::TimeUnit& aStartTime,
                         const MediaInfo& aInfo) = 0;

  // Finish a playback session.
  // Must be called after playback starts.
  virtual void Stop() = 0;

  // Return true if playback has started.
  // Can be called in any state.
  virtual bool IsStarted() const = 0;

  // Return true if playback is started and not paused otherwise false.
  // Can be called in any state.
  virtual bool IsPlaying() const = 0;

  // Called on the state machine thread to shut down the sink. All resources
  // allocated by this sink should be released.
  // Must be called after playback stopped.
  virtual void Shutdown() {}

  virtual void SetSecondaryVideoContainer(VideoFrameContainer* aSecondary) {}

  virtual void GetDebugInfo(dom::MediaSinkDebugInfo& aInfo) {}

 protected:
  virtual ~MediaSink() = default;
};

}  // namespace mozilla

#endif  // MediaSink_h_