chromium/chromecast/media/cma/backend/media_pipeline_backend_for_mixer.h

// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMECAST_MEDIA_CMA_BACKEND_MEDIA_PIPELINE_BACKEND_FOR_MIXER_H_
#define CHROMECAST_MEDIA_CMA_BACKEND_MEDIA_PIPELINE_BACKEND_FOR_MIXER_H_

#include <memory>
#include <string>

#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "chromecast/media/cma/backend/video_decoder_for_mixer.h"
#include "chromecast/public/media/media_pipeline_backend.h"
#include "chromecast/public/media/media_pipeline_device_params.h"
#include "chromecast/public/volume_control.h"

namespace base {
class SingleThreadTaskRunner;
}  // namespace base

namespace chromecast {
namespace media {

class AvSync;
class AudioDecoderForMixer;
class VideoDecoderForMixer;

// CMA Backend implementation for audio devices.
class MediaPipelineBackendForMixer : public MediaPipelineBackend,
                                     public VideoDecoderForMixer::Observer {
 public:
  explicit MediaPipelineBackendForMixer(
      const MediaPipelineDeviceParams& params);

  MediaPipelineBackendForMixer(const MediaPipelineBackendForMixer&) = delete;
  MediaPipelineBackendForMixer& operator=(const MediaPipelineBackendForMixer&) =
      delete;

  ~MediaPipelineBackendForMixer() override;

  // MediaPipelineBackend implementation:
  AudioDecoder* CreateAudioDecoder() override;
  VideoDecoder* CreateVideoDecoder() override;
  bool Initialize() override;
  bool Start(int64_t start_pts) override;
  void Stop() override;
  bool Pause() override;
  bool Resume() override;
  bool SetPlaybackRate(float rate) override;
  int64_t GetCurrentPts() override;

  // VideoDecoderForMixer::Observer implementation:
  void VideoReadyToPlay() override;

  bool Primary() const;
  std::string DeviceId() const;
  AudioContentType ContentType() const;
  AudioChannel AudioChannel() const;
  const scoped_refptr<base::SingleThreadTaskRunner>& GetTaskRunner() const;
  VideoDecoderForMixer* video_decoder() const { return video_decoder_.get(); }
  AudioDecoderForMixer* audio_decoder() const { return audio_decoder_.get(); }
  void OnAudioReadyForPlayback();
  void NewAudioPlaybackRateInEffect(float rate);

  // Gets current time on the same clock as the rendering delay timestamp.
  virtual int64_t MonotonicClockNow() const;

  int64_t GetPlaybackStartTimeForTesting() const {
    return start_playback_timestamp_us_;
  }
  int64_t GetPlaybackStartPtsForTesting() const {
    return start_playback_pts_us_;
  }

 protected:
  std::unique_ptr<VideoDecoderForMixer> video_decoder_;
  std::unique_ptr<AudioDecoderForMixer> audio_decoder_;

 private:
  // State variable for DCHECKing caller correctness.
  enum State {
    kStateUninitialized,
    kStateInitialized,
    kStatePlaying,
    kStatePaused,
  };
  State state_;

  void OnVideoReadyToPlay();
  bool IsIgnorePtsMode() const;
  void TryStartPlayback();

  const MediaPipelineDeviceParams params_;

  std::unique_ptr<AvSync> av_sync_;
  int64_t start_playback_timestamp_us_ = INT64_MIN;
  int64_t start_playback_pts_us_ = INT64_MIN;

  // The media pipeline doesn't start playback until these 3 conditions are
  // met.
  bool audio_ready_to_play_ = false;
  bool video_ready_to_play_ = false;
  bool playback_started_ = false;
  float starting_playback_rate_ = 1.0;

  base::WeakPtr<MediaPipelineBackendForMixer> weak_this_;
  base::WeakPtrFactory<MediaPipelineBackendForMixer> weak_factory_;
};

}  // namespace media
}  // namespace chromecast

#endif  // CHROMECAST_MEDIA_CMA_BACKEND_MEDIA_PIPELINE_BACKEND_FOR_MIXER_H_