1f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifndef MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#define MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <deque>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/memory/scoped_ptr.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/memory/scoped_vector.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/condition_variable.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/decryptor.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/demuxer_stream.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/base/media_log.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/pipeline_status.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_decoder.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_frame.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_renderer.h"
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/filters/decoder_stream.h"
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner;
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
32f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// VideoRendererImpl creates its own thread for the sole purpose of timing frame
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// presentation.  It handles reading from the VideoFrameStream and stores the
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// results in a queue of decoded frames and executing a callback when a frame is
357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// ready for rendering.
36f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MEDIA_EXPORT VideoRendererImpl
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public VideoRenderer,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::PlatformThread::Delegate {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |decoders| contains the VideoDecoders to use when initializing.
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |paint_cb| is executed on the video frame timing thread whenever a new
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame is available for painting.
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementors should avoid doing any sort of heavy work in this method and
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead post a task to a common/worker thread to handle rendering.  Slowing
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down the video thread may result in losing synchronization with audio.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting |drop_frames_| to true causes the renderer to drop expired frames.
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VideoRendererImpl(
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScopedVector<VideoDecoder> decoders,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const SetDecryptorReadyCB& set_decryptor_ready_cb,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const PaintCB& paint_cb,
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      bool drop_frames,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const scoped_refptr<MediaLog>& media_log);
59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~VideoRendererImpl();
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // VideoRenderer implementation.
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Initialize(DemuxerStream* stream,
635c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                          bool low_delay,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& init_cb,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const StatisticsCB& statistics_cb,
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          const BufferingStateCB& buffering_state_cb,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& ended_cb,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& error_cb,
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          const TimeDeltaCB& get_time_cb) OVERRIDE;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Flush(const base::Closure& callback) OVERRIDE;
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual void StartPlayingFrom(base::TimeDelta timestamp) OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PlatformThread::Delegate implementation.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ThreadMain() OVERRIDE;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback for |video_frame_stream_| initialization.
78a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  void OnVideoFrameStreamInitialized(bool success);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Callback for |video_frame_stream_| to deliver decoded video frames and
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // report video decoding status.
82558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void FrameReady(VideoFrameStream::Status status,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const scoped_refptr<VideoFrame>& frame);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper method for adding a frame to |ready_frames_|.
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddReadyFrame_Locked(const scoped_refptr<VideoFrame>& frame);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Helper method that schedules an asynchronous read from the
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // |video_frame_stream_| as long as there isn't a pending read and we have
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // capacity.
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AttemptRead();
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AttemptRead_Locked();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when VideoFrameStream::Reset() completes.
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnVideoFrameStreamResetDone();
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Runs |paint_cb_| with the next frame from |ready_frames_|.
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A read is scheduled to replace the frame.
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PaintNextReadyFrame_Locked();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Drops the next frame from |ready_frames_| and runs |statistics_cb_|.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A read is scheduled to replace the frame.
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DropNextReadyFrame_Locked();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns true if the renderer has enough data for playback purposes.
108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Note that having enough data may be due to reaching end of stream.
109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool HaveEnoughData_Locked();
110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void TransitionToHaveEnough_Locked();
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Runs |statistics_cb_| with |frames_decoded_| and |frames_dropped_|, resets
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // them to 0, and then waits on |frame_available_| for up to the
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |wait_duration|.
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void UpdateStatsAndWait_Locked(base::TimeDelta wait_duration);
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for accessing data members.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock lock_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
122f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Provides video frames to VideoRendererImpl.
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<VideoFrameStream> video_frame_stream_;
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Flag indicating low-delay mode.
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool low_delay_;
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Queue of incoming frames yet to be painted.
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VideoFrameQueue ready_frames_;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1320de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Keeps track of whether we received the end of stream buffer and finished
1330de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // rendering.
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_end_of_stream_;
1350de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  bool rendered_end_of_stream_;
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to signal |thread_| as frames are added to |frames_|.  Rule of thumb:
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // always check |state_| to see if it was set to STOPPED after waking up!
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ConditionVariable frame_available_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Important detail: being in kPlaying doesn't imply that video is being
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // rendered. Rather, it means that the renderer is ready to go. The actual
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // rendering of video is controlled by time advancing via |get_time_cb_|.
144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //   kUninitialized
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         | Initialize()
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         V
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //    kInitializing
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         | Decoders initialized
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         V            Decoders reset
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //      kFlushed <------------------ kFlushing
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //         | StartPlayingFrom()         ^
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |                            |
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |                            | Flush()
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         `---------> kPlaying --------'
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUninitialized,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kInitializing,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlushing,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlushed,
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    kPlaying
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State state_;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video thread handle.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThreadHandle thread_;
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep track of the outstanding read on the VideoFrameStream. Flushing can
1717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // only complete once the read has completed.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool pending_read_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool drop_frames_;
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
176116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BufferingState buffering_state_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Playback operation callbacks.
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure flush_cb_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Event callbacks.
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB init_cb_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StatisticsCB statistics_cb_;
184116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BufferingStateCB buffering_state_cb_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure ended_cb_;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB error_cb_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDeltaCB get_time_cb_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
189116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeDelta start_timestamp_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Embedder callback for notifying a new frame is available for painting.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PaintCB paint_cb_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The timestamp of the last frame removed from the |ready_frames_| queue,
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // either for calling |paint_cb_| or for dropping. Set to kNoTimestamp()
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during flushing.
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta last_timestamp_;
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The timestamp of the last successfully painted frame. Set to kNoTimestamp()
2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // during flushing.
2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::TimeDelta last_painted_timestamp_;
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Keeps track of the number of frames decoded and dropped since the
2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // last call to |statistics_cb_|. These must be accessed under lock.
2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int frames_decoded_;
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int frames_dropped_;
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  bool is_shutting_down_;
2095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
21023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: Weak pointers must be invalidated before all other member variables.
21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::WeakPtrFactory<VideoRendererImpl> weak_factory_;
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
219