// 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 MEDIA_CAST_SENDER_CODECS_VP8_VP8_ENCODER_H_ #define MEDIA_CAST_SENDER_CODECS_VP8_VP8_ENCODER_H_ #include "base/basictypes.h" #include "base/memory/scoped_ptr.h" #include "base/threading/thread_checker.h" #include "base/time/time.h" #include "media/cast/cast_config.h" #include "media/cast/sender/software_video_encoder.h" #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h" namespace media { class VideoFrame; } // VPX forward declaration. typedef struct vpx_codec_ctx vpx_enc_ctx_t; namespace media { namespace cast { const int kNumberOfVp8VideoBuffers = 3; class Vp8Encoder : public SoftwareVideoEncoder { public: Vp8Encoder(const VideoSenderConfig& video_config, int max_unacked_frames); virtual ~Vp8Encoder(); // Initialize the encoder before Encode() can be called. This method // must be called on the thread that Encode() is called. virtual void Initialize() OVERRIDE; // Encode a raw image (as a part of a video stream). virtual bool Encode(const scoped_refptr& video_frame, EncodedFrame* encoded_image) OVERRIDE; // Update the encoder with a new target bit rate. virtual void UpdateRates(uint32 new_bitrate) OVERRIDE; // Set the next frame to be a key frame. virtual void GenerateKeyFrame() OVERRIDE; virtual void LatestFrameIdToReference(uint32 frame_id) OVERRIDE; private: enum Vp8Buffers { kAltRefBuffer = 0, kGoldenBuffer = 1, kLastBuffer = 2, kNoBuffer = 3 // Note: must be last. }; void InitEncode(int number_of_cores); // Calculate the max target in % for a keyframe. uint32 MaxIntraTarget(uint32 optimal_buffer_size) const; // Calculate which next Vp8 buffers to update with the next frame. Vp8Buffers GetNextBufferToUpdate(); // Calculate which previous frame to reference. uint32 GetLatestFrameIdToReference(); // Get encoder flags for our referenced encoder buffers. void GetCodecReferenceFlags(vpx_codec_flags_t* flags); // Get encoder flags for our encoder buffers to update with next frame. void GetCodecUpdateFlags(Vp8Buffers buffer_to_update, vpx_codec_flags_t* flags); const VideoSenderConfig cast_config_; const bool use_multiple_video_buffers_; const int max_number_of_repeated_buffers_in_a_row_; // VP8 internal objects. scoped_ptr config_; scoped_ptr encoder_; vpx_image_t* raw_image_; bool key_frame_requested_; bool first_frame_received_; base::TimeDelta first_frame_timestamp_; uint32 last_encoded_frame_id_; uint32 used_buffers_frame_id_[kNumberOfVp8VideoBuffers]; bool acked_frame_buffers_[kNumberOfVp8VideoBuffers]; Vp8Buffers last_used_vp8_buffer_; int number_of_repeated_buffers_; // This is bound to the thread where Initialize() is called. base::ThreadChecker thread_checker_; DISALLOW_COPY_AND_ASSIGN(Vp8Encoder); }; } // namespace cast } // namespace media #endif // MEDIA_CAST_SENDER_CODECS_VP8_VP8_ENCODER_H_