Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / media / cast / audio_receiver / audio_receiver.h
index cbf52f9..6aae136 100644 (file)
 #include "media/cast/cast_config.h"
 #include "media/cast/cast_environment.h"
 #include "media/cast/cast_receiver.h"
+#include "media/cast/framer/framer.h"
 #include "media/cast/rtcp/receiver_rtcp_event_subscriber.h"
-#include "media/cast/rtcp/rtcp.h"                          // RtcpCastMessage
+#include "media/cast/rtcp/rtcp.h"
 #include "media/cast/rtp_receiver/rtp_receiver.h"
-#include "media/cast/rtp_receiver/rtp_receiver_defines.h"  // RtpCastHeader
+#include "media/cast/rtp_receiver/rtp_receiver_defines.h"
 #include "media/cast/transport/utility/transport_encryption_handler.h"
 
 namespace media {
 namespace cast {
 
 class AudioDecoder;
-class Framer;
-class LocalRtpAudioFeedback;
-class RtpReceiver;
-class RtpReceiverStatistics;
-
-struct DecodedAudioCallbackData {
-  DecodedAudioCallbackData();
-  ~DecodedAudioCallbackData();
-  int number_of_10ms_blocks;
-  int desired_frequency;
-  AudioFrameDecodedCallback callback;
-};
 
-// This class is not thread safe. Should only be called from the Main cast
+// AudioReceiver receives packets out-of-order while clients make requests for
+// complete frames in-order.  (A frame consists of one or more packets.)
+//
+// AudioReceiver also includes logic for computing the playout time for each
+// frame, accounting for a constant targeted playout delay.  The purpose of the
+// playout delay is to provide a fixed window of time between the capture event
+// on the sender and the playout on the receiver.  This is important because
+// each step of the pipeline (i.e., encode frame, then transmit/retransmit from
+// the sender, then receive and re-order packets on the receiver, then decode
+// frame) can vary in duration and is typically very hard to predict.
+// Heuristics will determine when the targeted playout delay is insufficient in
+// the current environment; and the receiver can then increase the playout
+// delay, notifying the sender, to account for the extra variance.
+// TODO(miu): Make the last sentence true.  http://crbug.com/360111
+//
+// Two types of frames can be requested: 1) A frame of decoded audio data; or 2)
+// a frame of still-encoded audio data, to be passed into an external audio
+// decoder.  Each request for a frame includes a callback which AudioReceiver
+// guarantees will be called at some point in the future unless the
+// AudioReceiver is destroyed.  Clients should generally limit the number of
+// outstanding requests (perhaps to just one or two).
+//
+// This class is not thread safe.  Should only be called from the Main cast
 // thread.
-class AudioReceiver : public base::NonThreadSafe,
-                      public base::SupportsWeakPtr<AudioReceiver>,
-                      public RtpReceiver {
+class AudioReceiver : public RtpReceiver,
+                      public RtpPayloadFeedback,
+                      public base::NonThreadSafe,
+                      public base::SupportsWeakPtr<AudioReceiver> {
  public:
   AudioReceiver(scoped_refptr<CastEnvironment> cast_environment,
                 const AudioReceiverConfig& audio_config,
@@ -52,58 +64,60 @@ class AudioReceiver : public base::NonThreadSafe,
 
   virtual ~AudioReceiver();
 
-  // Extract a raw audio frame from the cast receiver.
-  // Actual decoding will be preformed on a designated audio_decoder thread.
-  void GetRawAudioFrame(int number_of_10ms_blocks,
-                        int desired_frequency,
-                        const AudioFrameDecodedCallback& callback);
-
-  // Extract an encoded audio frame from the cast receiver.
+  // Request a decoded audio frame.  The audio signal data returned in the
+  // callback will have the sampling rate and number of channels as requested in
+  // the configuration that was passed to the ctor.
+  //
+  // The given |callback| is guaranteed to be run at some point in the future,
+  // even if to respond with NULL at shutdown time.
+  void GetRawAudioFrame(const AudioFrameDecodedCallback& callback);
+
+  // Request an encoded audio frame.
+  //
+  // The given |callback| is guaranteed to be run at some point in the future,
+  // even if to respond with NULL at shutdown time.
   void GetEncodedAudioFrame(const AudioFrameEncodedCallback& callback);
 
-  // Should only be called from the main cast thread.
+  // Deliver another packet, possibly a duplicate, and possibly out-of-order.
   void IncomingPacket(scoped_ptr<Packet> packet);
 
   // Update target audio delay used to compute the playout time. Rtcp
   // will also be updated (will be included in all outgoing reports).
   void SetTargetDelay(base::TimeDelta target_delay);
 
+ protected:
+  friend class AudioReceiverTest;  // Invokes OnReceivedPayloadData().
+
   virtual void OnReceivedPayloadData(const uint8* payload_data,
                                      size_t payload_size,
                                      const RtpCastHeader& rtp_header) OVERRIDE;
 
- private:
-  friend class LocalRtpAudioFeedback;
-
-  void CastFeedback(const RtcpCastMessage& cast_message);
-
-  // Time to pull out the audio even though we are missing data.
-  void PlayoutTimeout();
-
-  bool PostEncodedAudioFrame(
-      const AudioFrameEncodedCallback& callback,
-      bool next_frame,
-      scoped_ptr<transport::EncodedAudioFrame>* encoded_frame);
+  // RtpPayloadFeedback implementation.
+  virtual void CastFeedback(const RtcpCastMessage& cast_message) OVERRIDE;
 
-  // Actual decoding implementation - should be called under the audio decoder
-  // thread.
-  void DecodeAudioFrameThread(int number_of_10ms_blocks,
-                              int desired_frequency,
-                              const AudioFrameDecodedCallback callback);
-  void ReturnDecodedFrameWithPlayoutDelay(
-      scoped_ptr<PcmAudioFrame> audio_frame,
-      uint32 rtp_timestamp,
-      const AudioFrameDecodedCallback callback);
+ private:
+  // Processes ready-to-consume packets from |framer_|, decrypting each packet's
+  // payload data, and then running the enqueued callbacks in order (one for
+  // each packet).  This method may post a delayed task to re-invoke itself in
+  // the future to wait for missing/incomplete frames.
+  void EmitAvailableEncodedFrames();
+
+  // Clears the |is_waiting_for_consecutive_frame_| flag and invokes
+  // EmitAvailableEncodedFrames().
+  void EmitAvailableEncodedFramesAfterWaiting();
+
+  // Feeds an EncodedAudioFrame into |audio_decoder_|.  GetRawAudioFrame() uses
+  // this as a callback for GetEncodedAudioFrame().
+  void DecodeEncodedAudioFrame(
+      const AudioFrameDecodedCallback& callback,
+      scoped_ptr<transport::EncodedAudioFrame> encoded_frame,
+      const base::TimeTicks& playout_time);
 
   // Return the playout time based on the current time and rtp timestamp.
   base::TimeTicks GetPlayoutTime(base::TimeTicks now, uint32 rtp_timestamp);
 
   void InitializeTimers();
 
-  // Decrypts the data within the |audio_frame| and replaces the data with the
-  // decrypted string.
-  bool DecryptAudioFrame(scoped_ptr<transport::EncodedAudioFrame>* audio_frame);
-
   // Schedule the next RTCP report.
   void ScheduleNextRtcpReport();
 
@@ -116,7 +130,21 @@ class AudioReceiver : public base::NonThreadSafe,
   // Actually send the next cast message.
   void SendNextCastMessage();
 
-  scoped_refptr<CastEnvironment> cast_environment_;
+  // Receives an AudioBus from |audio_decoder_|, logs the event, and passes the
+  // data on by running the given |callback|.  This method is static to ensure
+  // it can be called after an AudioReceiver instance is destroyed.
+  // DecodeEncodedAudioFrame() uses this as a callback for
+  // AudioDecoder::DecodeFrame().
+  static void EmitRawAudioFrame(
+      const scoped_refptr<CastEnvironment>& cast_environment,
+      const AudioFrameDecodedCallback& callback,
+      uint32 frame_id,
+      uint32 rtp_timestamp,
+      const base::TimeTicks& playout_time,
+      scoped_ptr<AudioBus> audio_bus,
+      bool is_continuous);
+
+  const scoped_refptr<CastEnvironment> cast_environment_;
 
   // Subscribes to raw events.
   // Processes raw audio events to be sent over to the cast sender via RTCP.
@@ -125,18 +153,20 @@ class AudioReceiver : public base::NonThreadSafe,
   const transport::AudioCodec codec_;
   const int frequency_;
   base::TimeDelta target_delay_delta_;
-  scoped_ptr<Framer> audio_buffer_;
+  Framer framer_;
   scoped_ptr<AudioDecoder> audio_decoder_;
-  scoped_ptr<LocalRtpAudioFeedback> incoming_payload_feedback_;
-  scoped_ptr<Rtcp> rtcp_;
+  Rtcp rtcp_;
   base::TimeDelta time_offset_;
   base::TimeTicks time_first_incoming_packet_;
   uint32 first_incoming_rtp_timestamp_;
   transport::TransportEncryptionHandler decryptor_;
-  base::TimeTicks last_playout_time_;
 
-  std::list<AudioFrameEncodedCallback> queued_encoded_callbacks_;
-  std::list<DecodedAudioCallbackData> queued_decoded_callbacks_;
+  // Outstanding callbacks to run to deliver on client requests for frames.
+  std::list<AudioFrameEncodedCallback> frame_request_queue_;
+
+  // True while there's an outstanding task to re-invoke
+  // EmitAvailableEncodedFrames().
+  bool is_waiting_for_consecutive_frame_;
 
   // This mapping allows us to log kAudioAckSent as a frame event. In addition
   // it allows the event to be transmitted via RTCP.