text: // Copyright 2014 The Chromium Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style license that can be
  // found in the LICENSE file.
  
  #ifndef CHROMECAST_MEDIA_CMA_FILTERS_CMA_RENDERER_H_
  #define CHROMECAST_MEDIA_CMA_FILTERS_CMA_RENDERER_H_
  
  #include "base/macros.h"
  #include "base/memory/scoped_ptr.h"
  #include "base/memory/weak_ptr.h"
  #include "base/synchronization/lock.h"
  #include "base/threading/thread_checker.h"
  #include "base/time/default_tick_clock.h"
  #include "media/base/buffering_state.h"
  #include "media/base/renderer.h"
  #include "ui/gfx/geometry/size.h"
  
  namespace base {
  class MessageLoopProxy;
  }
  
  namespace media {
  class DemuxerStreamProvider;
  class TimeDeltaInterpolator;
  class VideoFrame;
  }
  
  namespace chromecast {
  namespace media {
  class AudioPipeline;
  class BalancedMediaTaskRunnerFactory;
  class MediaPipeline;
  class VideoPipeline;
  
  class CmaRenderer : public ::media::Renderer {
   public:
    explicit CmaRenderer(scoped_ptr<MediaPipeline> media_pipeline);
    ~CmaRenderer() override;
  
    // ::media::Renderer implementation:
    void Initialize(
        ::media::DemuxerStreamProvider* demuxer_stream_provider,
        const base::Closure& init_cb,
        const ::media::StatisticsCB& statistics_cb,
        const ::media::BufferingStateCB& buffering_state_cb,
        const PaintCB& paint_cb,
        const base::Closure& ended_cb,
        const ::media::PipelineStatusCB& error_cb) override;
    void Flush(const base::Closure& flush_cb) override;
    void StartPlayingFrom(base::TimeDelta time) override;
    void SetPlaybackRate(float playback_rate) override;
    void SetVolume(float volume) override;
    base::TimeDelta GetMediaTime() override;
    bool HasAudio() override;
    bool HasVideo() override;
    void SetCdm(::media::CdmContext* cdm_context,
                const ::media::CdmAttachedCB& cdm_attached_cb) override;
  
   private:
    enum State {
      kUninitialized,
      kPlaying,
      kFlushed,
      kError,
    };
  
    // Asynchronous initialization sequence. These four methods are invoked in
    // the order below, with a successful initialization making it to
    // OnVideoPipelineInitializeDone, regardless of which streams are present.
    void InitializeAudioPipeline();
    void OnAudioPipelineInitializeDone(::media::PipelineStatus status);
    void InitializeVideoPipeline();
    void OnVideoPipelineInitializeDone(::media::PipelineStatus status);
  
    // Callbacks for AvPipelineClient.
    void OnEosReached(bool is_audio);
    void OnStatisticsUpdated(const ::media::PipelineStatistics& stats);
    void OnNaturalSizeChanged(const gfx::Size& size);
  
    // Callbacks for MediaPipelineClient.
    void OnPlaybackTimeUpdated(base::TimeDelta time,
                               base::TimeDelta max_time,
                               base::TimeTicks capture_time);
    void OnBufferingNotification(::media::BufferingState state);
  
    void OnFlushDone(::media::PipelineStatus status);
    void OnError(::media::PipelineStatus status);
  
    void FireAllPendingCallbacks();
  
    // Begin a state transition.
    // Return true if delayed because of a pending state transition.
    void BeginStateTransition();
    void CompleteStateTransition(State new_state);
  
    base::ThreadChecker thread_checker_;
  
    scoped_refptr<BalancedMediaTaskRunnerFactory> media_task_runner_factory_;
    scoped_ptr<MediaPipeline> media_pipeline_;
    AudioPipeline* audio_pipeline_;
    VideoPipeline* video_pipeline_;
  
    ::media::DemuxerStreamProvider* demuxer_stream_provider_;
  
    // Set of callbacks.
    PaintCB paint_cb_;
    base::Closure init_cb_;
    ::media::StatisticsCB statistics_cb_;
    base::Closure ended_cb_;
    ::media::PipelineStatusCB error_cb_;
    ::media::BufferingStateCB buffering_state_cb_;
    base::Closure flush_cb_;
  
    // Renderer state.
    // Used mostly for checking that transitions are correct.
    State state_;
    bool is_pending_transition_;
  
    bool has_audio_;
    bool has_video_;
  
    bool received_audio_eos_;
    bool received_video_eos_;
  
    // Data members for helping the creation of the initial video hole frame.
    gfx::Size initial_natural_size_;
    bool initial_video_hole_created_;
  
    // Lock protecting access to |time_interpolator_|.
    base::Lock time_interpolator_lock_;
  
    // base::TickClock used by |time_interpolator_|.
    base::DefaultTickClock default_tick_clock_;
  
    // Tracks the most recent media time update and provides interpolated values
    // as playback progresses.
    scoped_ptr< ::media::TimeDeltaInterpolator> time_interpolator_;
  
    float playback_rate_;
  
    base::WeakPtr<CmaRenderer> weak_this_;
    base::WeakPtrFactory<CmaRenderer> weak_factory_;
  
    DISALLOW_COPY_AND_ASSIGN(CmaRenderer);
  };
  
  }  // namespace media
  }  // namespace chromecast
  
  #endif  // CHROMECAST_MEDIA_CMA_FILTERS_CMA_RENDERER_H_
  