2015-10-19 12:32:16 +03:00
|
|
|
/* -*- 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_
|
|
|
|
|
2015-10-19 13:08:11 +03:00
|
|
|
#include "FrameStatistics.h"
|
2015-10-19 12:32:16 +03:00
|
|
|
#include "ImageContainer.h"
|
2015-10-19 13:08:11 +03:00
|
|
|
#include "MediaEventSource.h"
|
2015-10-19 12:32:16 +03:00
|
|
|
#include "MediaSink.h"
|
2015-10-19 13:08:11 +03:00
|
|
|
#include "MediaTimer.h"
|
2015-10-19 12:32:16 +03:00
|
|
|
#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
|
|
|
|
{
|
2015-10-19 13:08:11 +03:00
|
|
|
typedef mozilla::layers::ImageContainer::ProducerID ProducerID;
|
2015-10-19 12:32:16 +03:00
|
|
|
public:
|
|
|
|
VideoSink(AbstractThread* aThread,
|
|
|
|
MediaSink* aAudioSink,
|
2017-03-22 06:59:54 +03:00
|
|
|
MediaQueue<VideoData>& aVideoQueue,
|
2015-10-19 12:32:16 +03:00
|
|
|
VideoFrameContainer* aContainer,
|
2015-10-19 13:08:11 +03:00
|
|
|
FrameStatistics& aFrameStats,
|
|
|
|
uint32_t aVQueueSentToCompositerSize);
|
2015-10-19 12:32:16 +03:00
|
|
|
|
|
|
|
const PlaybackParams& GetPlaybackParams() const override;
|
|
|
|
|
|
|
|
void SetPlaybackParams(const PlaybackParams& aParams) override;
|
|
|
|
|
|
|
|
RefPtr<GenericPromise> OnEnded(TrackType aType) override;
|
|
|
|
|
2017-03-27 09:55:05 +03:00
|
|
|
TimeUnit GetEndTime(TrackType aType) const override;
|
2015-10-19 12:32:16 +03:00
|
|
|
|
2017-03-27 09:55:05 +03:00
|
|
|
TimeUnit GetPosition(TimeStamp* aTimeStamp = nullptr) const override;
|
2015-10-19 12:32:16 +03:00
|
|
|
|
|
|
|
bool HasUnplayedFrames(TrackType aType) const override;
|
|
|
|
|
|
|
|
void SetPlaybackRate(double aPlaybackRate) override;
|
|
|
|
|
2015-10-19 13:14:31 +03:00
|
|
|
void SetVolume(double aVolume) override;
|
|
|
|
|
|
|
|
void SetPreservesPitch(bool aPreservesPitch) override;
|
|
|
|
|
2015-10-19 12:32:16 +03:00
|
|
|
void SetPlaying(bool aPlaying) override;
|
|
|
|
|
2016-05-17 05:33:32 +03:00
|
|
|
void Redraw(const VideoInfo& aInfo) override;
|
2015-10-19 13:08:11 +03:00
|
|
|
|
2017-03-27 09:55:05 +03:00
|
|
|
void Start(const TimeUnit& aStartTime, const MediaInfo& aInfo) override;
|
2015-10-19 12:32:16 +03:00
|
|
|
|
|
|
|
void Stop() override;
|
|
|
|
|
|
|
|
bool IsStarted() const override;
|
|
|
|
|
|
|
|
bool IsPlaying() const override;
|
|
|
|
|
|
|
|
void Shutdown() override;
|
|
|
|
|
2017-01-18 12:55:59 +03:00
|
|
|
nsCString GetDebugInfo() override;
|
2016-08-24 02:45:58 +03:00
|
|
|
|
2015-10-19 12:32:16 +03:00
|
|
|
private:
|
|
|
|
virtual ~VideoSink();
|
|
|
|
|
2015-10-19 13:08:11 +03:00
|
|
|
// VideoQueue listener related.
|
2017-03-22 06:59:54 +03:00
|
|
|
void OnVideoQueuePushed(RefPtr<VideoData>&& aSample);
|
2015-12-22 03:42:38 +03:00
|
|
|
void OnVideoQueueFinished();
|
2015-10-19 13:08:11 +03:00
|
|
|
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();
|
|
|
|
|
2016-08-29 15:56:00 +03:00
|
|
|
void MaybeResolveEndPromise();
|
|
|
|
|
2015-10-19 12:32:16 +03:00
|
|
|
void AssertOwnerThread() const
|
|
|
|
{
|
|
|
|
MOZ_ASSERT(mOwnerThread->IsCurrentThreadIn());
|
|
|
|
}
|
|
|
|
|
2017-03-22 06:59:54 +03:00
|
|
|
MediaQueue<VideoData>& VideoQueue() const {
|
2015-10-19 12:32:16 +03:00
|
|
|
return mVideoQueue;
|
|
|
|
}
|
|
|
|
|
|
|
|
const RefPtr<AbstractThread> mOwnerThread;
|
|
|
|
RefPtr<MediaSink> mAudioSink;
|
2017-03-22 06:59:54 +03:00
|
|
|
MediaQueue<VideoData>& mVideoQueue;
|
2015-10-19 12:32:16 +03:00
|
|
|
VideoFrameContainer* mContainer;
|
|
|
|
|
2015-10-19 13:08:11 +03:00
|
|
|
// 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;
|
|
|
|
|
2015-10-19 12:32:16 +03:00
|
|
|
RefPtr<GenericPromise> mEndPromise;
|
|
|
|
MozPromiseHolder<GenericPromise> mEndPromiseHolder;
|
|
|
|
MozPromiseRequestHolder<GenericPromise> mVideoSinkEndRequest;
|
|
|
|
|
2017-03-27 09:35:42 +03:00
|
|
|
// The presentation end time of the last video frame which has been displayed.
|
|
|
|
TimeUnit mVideoFrameEndTime;
|
2015-10-19 13:08:11 +03:00
|
|
|
|
|
|
|
// Event listeners for VideoQueue
|
|
|
|
MediaEventListener mPushListener;
|
2015-12-22 03:42:38 +03:00
|
|
|
MediaEventListener mFinishListener;
|
2015-10-19 13:08:11 +03:00
|
|
|
|
|
|
|
// 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;
|
2016-08-19 12:34:42 +03:00
|
|
|
|
|
|
|
// 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;
|
2015-10-19 12:32:16 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace media
|
|
|
|
} // namespace mozilla
|
|
|
|
|
|
|
|
#endif
|