video_renderer_impl.h revision 116680a4aac90f2aa7413d9095a592090648e557
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"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/pipeline_status.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_decoder.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_frame.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/video_renderer.h"
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "media/filters/decoder_stream.h"
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace base {
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class SingleThreadTaskRunner;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
31f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// VideoRendererImpl creates its own thread for the sole purpose of timing frame
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// presentation.  It handles reading from the VideoFrameStream and stores the
337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// results in a queue of decoded frames and executing a callback when a frame is
347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// ready for rendering.
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)class MEDIA_EXPORT VideoRendererImpl
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public VideoRenderer,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      public base::PlatformThread::Delegate {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  typedef base::Callback<void(const scoped_refptr<VideoFrame>&)> PaintCB;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // |decoders| contains the VideoDecoders to use when initializing.
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  //
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |paint_cb| is executed on the video frame timing thread whenever a new
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // frame is available for painting.
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Implementors should avoid doing any sort of heavy work in this method and
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // instead post a task to a common/worker thread to handle rendering.  Slowing
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // down the video thread may result in losing synchronization with audio.
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Setting |drop_frames_| to true causes the renderer to drop expired frames.
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  VideoRendererImpl(
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      ScopedVector<VideoDecoder> decoders,
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const SetDecryptorReadyCB& set_decryptor_ready_cb,
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const PaintCB& paint_cb,
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      bool drop_frames);
57f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  virtual ~VideoRendererImpl();
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // VideoRenderer implementation.
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  virtual void Initialize(DemuxerStream* stream,
615c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                          bool low_delay,
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& init_cb,
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const StatisticsCB& statistics_cb,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const TimeCB& max_time_cb,
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                          const BufferingStateCB& buffering_state_cb,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const base::Closure& ended_cb,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const PipelineStatusCB& error_cb,
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const TimeDeltaCB& get_time_cb,
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          const TimeDeltaCB& get_duration_cb) OVERRIDE;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Flush(const base::Closure& callback) OVERRIDE;
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void StartPlayingFrom(base::TimeDelta timestamp) OVERRIDE;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Stop(const base::Closure& callback) OVERRIDE;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // PlatformThread::Delegate implementation.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ThreadMain() OVERRIDE;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Callback for |video_frame_stream_| initialization.
79a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch  void OnVideoFrameStreamInitialized(bool success);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Callback for |video_frame_stream_| to deliver decoded video frames and
827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // report video decoding status.
83558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch  void FrameReady(VideoFrameStream::Status status,
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  const scoped_refptr<VideoFrame>& frame);
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Helper method for adding a frame to |ready_frames_|.
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AddReadyFrame_Locked(const scoped_refptr<VideoFrame>& frame);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Helper method that schedules an asynchronous read from the
907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // |video_frame_stream_| as long as there isn't a pending read and we have
917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // capacity.
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void AttemptRead();
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void AttemptRead_Locked();
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Called when VideoFrameStream::Reset() completes.
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnVideoFrameStreamResetDone();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Helper function that flushes the buffers when a Stop() or error occurs.
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DoStopOrError_Locked();
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Runs |paint_cb_| with the next frame from |ready_frames_|.
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A read is scheduled to replace the frame.
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PaintNextReadyFrame_Locked();
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Drops the next frame from |ready_frames_| and runs |statistics_cb_|.
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // A read is scheduled to replace the frame.
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DropNextReadyFrame_Locked();
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Returns true if the renderer has enough data for playback purposes.
112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Note that having enough data may be due to reaching end of stream.
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool HaveEnoughData_Locked();
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void TransitionToHaveEnough_Locked();
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Runs |statistics_cb_| with |frames_decoded_| and |frames_dropped_|, resets
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // them to 0, and then waits on |frame_available_| for up to the
1184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // |wait_duration|.
1194e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  void UpdateStatsAndWait_Locked(base::TimeDelta wait_duration);
1204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used for accessing data members.
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Lock lock_;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
126f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  // Provides video frames to VideoRendererImpl.
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<VideoFrameStream> video_frame_stream_;
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
129010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Flag indicating low-delay mode.
130010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  bool low_delay_;
131010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Queue of incoming frames yet to be painted.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  typedef std::deque<scoped_refptr<VideoFrame> > VideoFrameQueue;
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  VideoFrameQueue ready_frames_;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1360de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // Keeps track of whether we received the end of stream buffer and finished
1370de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  // rendering.
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool received_end_of_stream_;
1390de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)  bool rendered_end_of_stream_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to signal |thread_| as frames are added to |frames_|.  Rule of thumb:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // always check |state_| to see if it was set to STOPPED after waking up!
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::ConditionVariable frame_available_;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Important detail: being in kPlaying doesn't imply that video is being
146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // rendered. Rather, it means that the renderer is ready to go. The actual
147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // rendering of video is controlled by time advancing via |time_cb_|.
148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //   kUninitialized
150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         | Initialize()
151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         V
153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //    kInitializing
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         | Decoders initialized
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |
156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         V            Decoders reset
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //      kFlushed <------------------ kFlushing
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         | StartPlayingFrom()         ^
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |                            |
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         |                            | Flush()
161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //         `---------> kPlaying --------'
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum State {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kUninitialized,
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    kInitializing,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlushing,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kFlushed,
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kPlaying,
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    kStopped,
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  State state_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Video thread handle.
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::PlatformThreadHandle thread_;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // Keep track of the outstanding read on the VideoFrameStream. Flushing can
1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  // only complete once the read has completed.
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool pending_read_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool drop_frames_;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
181116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BufferingState buffering_state_;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Playback operation callbacks.
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure flush_cb_;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Event callbacks.
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB init_cb_;
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  StatisticsCB statistics_cb_;
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeCB max_time_cb_;
190116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  BufferingStateCB buffering_state_cb_;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::Closure ended_cb_;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PipelineStatusCB error_cb_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDeltaCB get_time_cb_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TimeDeltaCB get_duration_cb_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
196116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::TimeDelta start_timestamp_;
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Embedder callback for notifying a new frame is available for painting.
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  PaintCB paint_cb_;
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The timestamp of the last frame removed from the |ready_frames_| queue,
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // either for calling |paint_cb_| or for dropping. Set to kNoTimestamp()
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // during flushing.
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::TimeDelta last_timestamp_;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2064e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // Keeps track of the number of frames decoded and dropped since the
2074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  // last call to |statistics_cb_|. These must be accessed under lock.
2084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int frames_decoded_;
2094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  int frames_dropped_;
2104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
21123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  // NOTE: Weak pointers must be invalidated before all other member variables.
21223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)  base::WeakPtrFactory<VideoRendererImpl> weak_factory_;
21323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)
214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(VideoRendererImpl);
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace media
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif  // MEDIA_FILTERS_VIDEO_RENDERER_IMPL_H_
220