// 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 REMOTING_HOST_VIDEO_FRAME_RECORDER_H_ #define REMOTING_HOST_VIDEO_FRAME_RECORDER_H_ #include #include #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/single_thread_task_runner.h" namespace webrtc { class DesktopFrame; } namespace remoting { class VideoEncoder; // Allows sequences of DesktopFrames passed to a VideoEncoder to be recorded. // // VideoFrameRecorder is designed to support applications which use a dedicated // thread for video encoding, but need to manage that process from a "main" // or "control" thread. // // On the control thread: // 1. Create the VideoFrameRecorder. // 2. Specify the amount of memory that may be used for recording. // 3. Call WrapVideoEncoder(), passing the actual VideoEncoder that will be // used to encode frames. // 4. Hand off the returned wrapper VideoEncoder to the video encoding thread, // to call in place of the actual VideoEncoder. // 5. Start/stop frame recording as necessary. // 6. Use NextFrame() to read each recorded frame in sequence. // // The wrapper VideoEncoder is designed to be handed off to the video encoding // thread, and used and torn down there. // // The VideoFrameRecorder and VideoEncoder may be torn down in any order; frame // recording will stop as soon as either is destroyed. class VideoFrameRecorder { public: VideoFrameRecorder(); virtual ~VideoFrameRecorder(); // Wraps the supplied VideoEncoder, returning a replacement VideoEncoder that // will route frames to the recorder, as well as passing them for encoding. // Each VideoFrameRecorder supports at most one wrapper at a time; if a new // wrapper is required then any existing one must be deleted, or detached via // DetachVideoEncoderWrapper(), before WrapVideoEncoder() is called again. scoped_ptr WrapVideoEncoder(scoped_ptr encoder); // Detaches the existing VideoEncoder wrapper, stopping it from recording. // The detached wrapper remains owned by the caller and will continue to // pass-through frames to the wrapped encoder, without recording them. void DetachVideoEncoderWrapper(); // Enables/disables frame recording. Frame recording is initially disabled. void SetEnableRecording(bool enable_recording); // Sets the maximum number of bytes of pixel data that may be recorded. // When this maximum is reached older frames will be discarded to make space // for new ones. void SetMaxContentBytes(int64_t max_content_bytes); // Pops the next recorded frame in the sequence, and returns it. scoped_ptr NextFrame(); private: class RecordingVideoEncoder; friend class RecordingVideoEncoder; void SetEncoderTaskRunner(scoped_refptr task_runner); void RecordFrame(scoped_ptr frame); // The recorded frames, in sequence. std::list recorded_frames_; // Size of the recorded frames' content, in bytes. int64_t content_bytes_; // Size that recorded frames' content must not exceed. int64_t max_content_bytes_; // True if recording is started, false otherwise. bool enable_recording_; // Task runner on which the wrapper VideoEncoder is being run. scoped_refptr encoder_task_runner_; // Weak reference to the wrapper VideoEncoder, to use to control it. base::WeakPtr recording_encoder_; scoped_refptr caller_task_runner_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(VideoFrameRecorder); }; } // namespace remoting #endif // REMOTING_HOST_VIDEO_FRAME_RECORDER_H_