text: // Copyright 2013 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_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 LocalRtpVideoData;
  class LocalRtpVideoFeedback;
  class PeerVideoReceiver;
  class Rtcp;
  class RtpReceiverStatistics;
  class VideoDecoder;
  
  // Should only be called from the Main cast thread.
  class VideoReceiver : public base::NonThreadSafe,
                        public base::SupportsWeakPtr<VideoReceiver> {
   public:
    VideoReceiver(scoped_refptr<CastEnvironment> cast_environment,
                  const VideoReceiverConfig& video_config,
                  transport::PacedPacketSender* const packet_sender);
  
    virtual ~VideoReceiver();
  
    // Request a raw frame. Will return frame via callback when available.
    void GetRawVideoFrame(const VideoFrameDecodedCallback& callback);
  
    // Request an encoded frame. Will return frame via callback when available.
    void GetEncodedVideoFrame(const VideoFrameEncodedCallback& callback);
  
    // Insert a RTP packet to the video receiver.
    void IncomingPacket(scoped_ptr<Packet> packet);
  
   protected:
    void IncomingParsedRtpPacket(const uint8* payload_data,
                                 size_t payload_size,
                                 const RtpCastHeader& rtp_header);
  
    void DecodeVideoFrameThread(
        scoped_ptr<transport::EncodedVideoFrame> encoded_frame,
        const base::TimeTicks render_time,
        const VideoFrameDecodedCallback& frame_decoded_callback);
  
   private:
    friend class LocalRtpVideoData;
    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();
  
    // Returns Render time based on current time and the rtp timestamp.
    base::TimeTicks GetRenderTime(base::TimeTicks now, uint32 rtp_timestamp);
  
    void InitializeTimers();
  
    // Schedule timing for the next cast message.
    void ScheduleNextCastMessage();
  
    // Schedule timing for the next RTCP report.
    void ScheduleNextRtcpReport();
  
    // Actually send the next cast message.
    void SendNextCastMessage();
  
    // Actually send the next RTCP report.
    void SendNextRtcpReport();
  
    scoped_ptr<VideoDecoder> video_decoder_;
    scoped_refptr<CastEnvironment> cast_environment_;
  
    // Subscribes to raw events.
    // Processes raw audio events to be sent over to the cast sender via RTCP.
    ReceiverRtcpEventSubscriber event_subscriber_;
  
    scoped_ptr<Framer> framer_;
    const transport::VideoCodec codec_;
    base::TimeDelta target_delay_delta_;
    base::TimeDelta frame_delay_;
    scoped_ptr<LocalRtpVideoData> incoming_payload_callback_;
    scoped_ptr<LocalRtpVideoFeedback> incoming_payload_feedback_;
    RtpReceiver rtp_receiver_;
    scoped_ptr<Rtcp> rtcp_;
    scoped_ptr<RtpReceiverStatistics> rtp_video_receiver_statistics_;
    base::TimeDelta time_offset_;  // Sender-receiver offset estimation.
    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_;
  
    base::WeakPtrFactory<VideoReceiver> weak_factory_;
  
    DISALLOW_COPY_AND_ASSIGN(VideoReceiver);
  };
  
  }  // namespace cast
  }  // namespace media
  
  #endif  // MEDIA_CAST_VIDEO_RECEIVER_VIDEO_RECEIVER_H_
  