summaryrefslogtreecommitdiffstats
path: root/dom/media/mediasink/VideoSink.h
blob: 2612f0e0799b47f0c30507a42d9ca6ea2715880b (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
151
152
153
154
155
156
157
158
159
160
/* -*- 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 VideoSink_h_
#define VideoSink_h_

#include "FrameStatistics.h"
#include "ImageContainer.h"
#include "MediaEventSource.h"
#include "MediaSink.h"
#include "MediaTimer.h"
#include "mozilla/AbstractThread.h"
#include "mozilla/MozPromise.h"
#include "mozilla/RefPtr.h"
#include "mozilla/TimeStamp.h"
#include "VideoFrameContainer.h"

namespace mozilla {

class VideoFrameContainer;
template <class T> class MediaQueue;

namespace media {

class VideoSink : public MediaSink
{
  typedef mozilla::layers::ImageContainer::ProducerID ProducerID;
public:
  VideoSink(AbstractThread* aThread,
            MediaSink* aAudioSink,
            MediaQueue<MediaData>& aVideoQueue,
            VideoFrameContainer* aContainer,
            FrameStatistics& aFrameStats,
            uint32_t aVQueueSentToCompositerSize);

  const PlaybackParams& GetPlaybackParams() const override;

  void SetPlaybackParams(const PlaybackParams& aParams) override;

  RefPtr<GenericPromise> OnEnded(TrackType aType) override;

  int64_t GetEndTime(TrackType aType) const override;

  int64_t GetPosition(TimeStamp* aTimeStamp = nullptr) const override;

  bool HasUnplayedFrames(TrackType aType) const override;

  void SetPlaybackRate(double aPlaybackRate) override;

  void SetVolume(double aVolume) override;

  void SetPreservesPitch(bool aPreservesPitch) override;

  void SetPlaying(bool aPlaying) override;

  void Redraw(const VideoInfo& aInfo) override;

  void Start(int64_t aStartTime, const MediaInfo& aInfo) override;

  void Stop() override;

  bool IsStarted() const override;

  bool IsPlaying() const override;

  void Shutdown() override;

  void DumpDebugInfo() override;

private:
  virtual ~VideoSink();

  // VideoQueue listener related.
  void OnVideoQueuePushed(RefPtr<MediaData>&& aSample);
  void OnVideoQueueFinished();
  void ConnectListener();
  void DisconnectListener();

  // Sets VideoQueue images into the VideoFrameContainer. Called on the shared
  // state machine thread. The first aMaxFrames (at most) are set.
  // aClockTime and aClockTimeStamp are used as the baseline for deriving
  // timestamps for the frames; when omitted, aMaxFrames must be 1 and
  // a null timestamp is passed to the VideoFrameContainer.
  // If the VideoQueue is empty, this does nothing.
  void RenderVideoFrames(int32_t aMaxFrames, int64_t aClockTime = 0,
                         const TimeStamp& aClickTimeStamp = TimeStamp());

  // Triggered while videosink is started, videosink becomes "playing" status,
  // or VideoQueue event arrived.
  void TryUpdateRenderedVideoFrames();

  // If we have video, display a video frame if it's time for display has
  // arrived, otherwise sleep until it's time for the next frame. Update the
  // current frame time as appropriate, and trigger ready state update.
  // Called on the shared state machine thread.
  void UpdateRenderedVideoFrames();
  void UpdateRenderedVideoFramesByTimer();

  void MaybeResolveEndPromise();

  void AssertOwnerThread() const
  {
    MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
  }

  MediaQueue<MediaData>& VideoQueue() const {
    return mVideoQueue;
  }

  const RefPtr<AbstractThread> mOwnerThread;
  RefPtr<MediaSink> mAudioSink;
  MediaQueue<MediaData>& mVideoQueue;
  VideoFrameContainer* mContainer;

  // Producer ID to help ImageContainer distinguish different streams of
  // FrameIDs. A unique and immutable value per VideoSink.
  const ProducerID mProducerID;

  // Used to notify MediaDecoder's frame statistics
  FrameStatistics& mFrameStats;

  RefPtr<GenericPromise> mEndPromise;
  MozPromiseHolder<GenericPromise> mEndPromiseHolder;
  MozPromiseRequestHolder<GenericPromise> mVideoSinkEndRequest;

  // The presentation end time of the last video frame which has been displayed
  // in microseconds.
  int64_t mVideoFrameEndTime;

  // Event listeners for VideoQueue
  MediaEventListener mPushListener;
  MediaEventListener mFinishListener;

  // True if this sink is going to handle video track.
  bool mHasVideo;

  // Used to trigger another update of rendered frames in next round.
  DelayedScheduler mUpdateScheduler;

  // Max frame number sent to compositor at a time.
  // Based on the pref value obtained in MDSM.
  const uint32_t mVideoQueueSendToCompositorSize;

  // Talos tests for the compositor require at least one frame in the
  // video queue so that the compositor has something to composit during
  // the talos test when the decode is stressed. We have a minimum size
  // on the video queue in order to facilitate this talos test.
  // Note: Normal playback should not have a queue size of more than 0,
  // otherwise A/V sync will be ruined! *Only* make this non-zero for
  // testing purposes.
  const uint32_t mMinVideoQueueSize;
};

} // namespace media
} // namespace mozilla

#endif