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