#ifndef MEDIA_CAST_VIDEO_RECEIVER_VIDEO_RECEIVER_H_
#define MEDIA_CAST_VIDEO_RECEIVER_VIDEO_RECEIVER_H_
#include "base/basictypes.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/cast_receiver.h"
#include "media/cast/rtcp/receiver_rtcp_event_subscriber.h"
#include "media/cast/rtcp/rtcp.h"
#include "media/cast/rtp_receiver/rtp_receiver.h"
#include "media/cast/rtp_receiver/rtp_receiver_defines.h"
#include "media/cast/transport/utility/transport_encryption_handler.h"
namespace media {
namespace cast {
class Framer;
class LocalRtpVideoFeedback;
class PeerVideoReceiver;
class Rtcp;
class RtpReceiverStatistics;
class VideoDecoder;
typedef base::Callback<void(base::TimeDelta)> SetTargetDelayCallback;
class VideoReceiver : public base::NonThreadSafe,
public base::SupportsWeakPtr<VideoReceiver>,
public RtpReceiver {
public:
VideoReceiver(scoped_refptr<CastEnvironment> cast_environment,
const VideoReceiverConfig& video_config,
transport::PacedPacketSender* const packet_sender,
const SetTargetDelayCallback& target_delay_cb);
virtual ~VideoReceiver();
void GetRawVideoFrame(const VideoFrameDecodedCallback& callback);
void GetEncodedVideoFrame(const VideoFrameEncodedCallback& callback);
void IncomingPacket(scoped_ptr<Packet> packet);
virtual void OnReceivedPayloadData(const uint8* payload_data,
size_t payload_size,
const RtpCastHeader& rtp_header) OVERRIDE;
protected:
void DecodeVideoFrameThread(
scoped_ptr<transport::EncodedVideoFrame> encoded_frame,
const base::TimeTicks render_time,
const VideoFrameDecodedCallback& frame_decoded_callback);
private:
friend class LocalRtpVideoFeedback;
void CastFeedback(const RtcpCastMessage& cast_message);
void DecodeVideoFrame(const VideoFrameDecodedCallback& callback,
scoped_ptr<transport::EncodedVideoFrame> encoded_frame,
const base::TimeTicks& render_time);
bool DecryptVideoFrame(scoped_ptr<transport::EncodedVideoFrame>* video_frame);
bool PullEncodedVideoFrame(
bool next_frame,
scoped_ptr<transport::EncodedVideoFrame>* encoded_frame,
base::TimeTicks* render_time);
void PlayoutTimeout();
base::TimeTicks GetRenderTime(base::TimeTicks now, uint32 rtp_timestamp);
void InitializeTimers();
void ScheduleNextCastMessage();
void ScheduleNextRtcpReport();
void SendNextCastMessage();
void SendNextRtcpReport();
void UpdateTargetDelay();
scoped_ptr<VideoDecoder> video_decoder_;
scoped_refptr<CastEnvironment> cast_environment_;
ReceiverRtcpEventSubscriber event_subscriber_;
scoped_ptr<Framer> framer_;
const transport::VideoCodec codec_;
base::TimeDelta target_delay_delta_;
base::TimeDelta frame_delay_;
scoped_ptr<LocalRtpVideoFeedback> incoming_payload_feedback_;
scoped_ptr<Rtcp> rtcp_;
base::TimeDelta time_offset_;
int time_offset_counter_;
transport::TransportEncryptionHandler decryptor_;
std::list<VideoFrameEncodedCallback> queued_encoded_callbacks_;
bool time_incoming_packet_updated_;
base::TimeTicks time_incoming_packet_;
uint32 incoming_rtp_timestamp_;
base::TimeTicks last_render_time_;
SetTargetDelayCallback target_delay_cb_;
RtpTimestamp frame_id_to_rtp_timestamp_[256];
base::WeakPtrFactory<VideoReceiver> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(VideoReceiver);
};
}
}
#endif