#ifndef MEDIA_CAST_VIDEO_SENDER_VIDEO_SENDER_H_
#define MEDIA_CAST_VIDEO_SENDER_VIDEO_SENDER_H_
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/non_thread_safe.h"
#include "base/time/tick_clock.h"
#include "base/time/time.h"
#include "media/cast/cast_config.h"
#include "media/cast/cast_environment.h"
#include "media/cast/congestion_control/congestion_control.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/rtcp/rtcp.h"
#include "media/cast/rtcp/sender_rtcp_event_subscriber.h"
namespace media {
class VideoFrame;
namespace cast {
class LocalRtcpVideoSenderFeedback;
class LocalVideoEncoderCallback;
class VideoEncoder;
namespace transport {
class CastTransportSender;
}
class VideoSender : public base::NonThreadSafe,
public base::SupportsWeakPtr<VideoSender> {
public:
VideoSender(scoped_refptr<CastEnvironment> cast_environment,
const VideoSenderConfig& video_config,
const CreateVideoEncodeAcceleratorCallback& create_vea_cb,
const CreateVideoEncodeMemoryCallback& create_video_encode_mem_cb,
const CastInitializationCallback& cast_initialization_cb,
transport::CastTransportSender* const transport_sender);
virtual ~VideoSender();
void InsertRawVideoFrame(const scoped_refptr<media::VideoFrame>& video_frame,
const base::TimeTicks& capture_time);
void IncomingRtcpPacket(scoped_ptr<Packet> packet);
void StoreStatistics(const transport::RtcpSenderInfo& sender_info,
base::TimeTicks time_sent,
uint32 rtp_timestamp);
protected:
void OnReceivedCastFeedback(const RtcpCastMessage& cast_feedback);
private:
friend class LocalRtcpVideoSenderFeedback;
void ScheduleNextRtcpReport();
void SendRtcpReport();
void ScheduleNextResendCheck();
void ResendCheck();
void ScheduleNextSkippedFramesCheck();
void SkippedFramesCheck();
void SendEncodedVideoFrame(const transport::EncodedVideoFrame* video_frame,
const base::TimeTicks& capture_time);
void ResendFrame(uint32 resend_frame_id);
void ReceivedAck(uint32 acked_frame_id);
void UpdateFramesInFlight();
void SendEncodedVideoFrameMainThread(
scoped_ptr<transport::EncodedVideoFrame> encoded_frame,
const base::TimeTicks& capture_time);
void InitializeTimers();
base::TimeDelta rtp_max_delay_;
const int max_frame_rate_;
scoped_refptr<CastEnvironment> cast_environment_;
transport::CastTransportSender* const transport_sender_;
SenderRtcpEventSubscriber event_subscriber_;
RtpSenderStatistics rtp_stats_;
scoped_ptr<LocalRtcpVideoSenderFeedback> rtcp_feedback_;
scoped_ptr<VideoEncoder> video_encoder_;
scoped_ptr<Rtcp> rtcp_;
uint8 max_unacked_frames_;
int last_acked_frame_id_;
int last_sent_frame_id_;
int duplicate_ack_;
base::TimeTicks last_send_time_;
base::TimeTicks last_checked_skip_count_time_;
int last_skip_count_;
CongestionControl congestion_control_;
RtpTimestamp frame_id_to_rtp_timestamp_[256];
bool initialized_;
bool active_session_;
base::WeakPtrFactory<VideoSender> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(VideoSender);
};
}
}
#endif