• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004--2010, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_SESSION_PHONE_MEDIACHANNEL_H_
29 #define TALK_SESSION_PHONE_MEDIACHANNEL_H_
30 
31 #include <string>
32 #include <vector>
33 
34 #include "talk/base/basictypes.h"
35 #include "talk/base/sigslot.h"
36 #include "talk/base/socket.h"
37 #include "talk/session/phone/codec.h"
38 // TODO: re-evaluate this include
39 #include "talk/session/phone/audiomonitor.h"
40 
41 namespace talk_base {
42 class Buffer;
43 }
44 
45 namespace flute {
46 class MagicCamVideoRenderer;
47 }
48 
49 namespace cricket {
50 
51 const size_t kMinRtpPacketLen = 12;
52 const size_t kMinRtcpPacketLen = 4;
53 const size_t kMaxRtpPacketLen = 2048;
54 
55 enum VoiceMediaChannelOptions {
56   OPT_CONFERENCE = 0x10000,   // tune the audio stream for conference mode
57   OPT_ENERGYLEVEL = 0x20000,  // include the energy level in RTP packets, as
58                               // defined in https://datatracker.ietf.org/drafts/
59                               // draft-lennox-avt-rtp-audio-level-exthdr/
60 
61 };
62 
63 enum VideoMediaChannelOptions {
64   OPT_INTERPOLATE = 0x10000   // Increase the output framerate by 2x by
65                               // interpolating frames
66 };
67 
68 class MediaChannel : public sigslot::has_slots<> {
69  public:
70   class NetworkInterface {
71    public:
72     enum SocketType { ST_RTP, ST_RTCP };
73     virtual bool SendPacket(talk_base::Buffer* packet) = 0;
74     virtual bool SendRtcp(talk_base::Buffer* packet) = 0;
75     virtual int SetOption(SocketType type, talk_base::Socket::Option opt,
76                           int option) = 0;
~NetworkInterface()77     virtual ~NetworkInterface() {}
78   };
79 
MediaChannel()80   MediaChannel() : network_interface_(NULL) {}
~MediaChannel()81   virtual ~MediaChannel() {}
82 
83   // Gets/sets the abstract inteface class for sending RTP/RTCP data.
network_interface()84   NetworkInterface *network_interface() { return network_interface_; }
SetInterface(NetworkInterface * iface)85   virtual void SetInterface(NetworkInterface *iface) {
86     network_interface_ = iface;
87   }
88 
89   // Called when a RTP packet is received.
90   virtual void OnPacketReceived(talk_base::Buffer* packet) = 0;
91   // Called when a RTCP packet is received.
92   virtual void OnRtcpReceived(talk_base::Buffer* packet) = 0;
93   // Sets the SSRC to be used for outgoing data.
94   virtual void SetSendSsrc(uint32 id) = 0;
95   // Set the CNAME of RTCP
96   virtual bool SetRtcpCName(const std::string& cname) = 0;
97   // Mutes the channel.
98   virtual bool Mute(bool on) = 0;
99 
SetRtpExtensionHeaders(bool enable_all)100   virtual bool SetRtpExtensionHeaders(bool enable_all) { return true; }
101   virtual bool SetSendBandwidth(bool autobw, int bps) = 0;
102   virtual bool SetOptions(int options) = 0;
103 
104  protected:
105   NetworkInterface *network_interface_;
106 };
107 
108 enum SendFlags {
109   SEND_NOTHING,
110   SEND_RINGBACKTONE,
111   SEND_MICROPHONE
112 };
113 
114 struct VoiceSenderInfo {
115   uint32 ssrc;
116   int bytes_sent;
117   int packets_sent;
118   int packets_lost;
119   float fraction_lost;
120   int ext_seqnum;
121   int rtt_ms;
122   int jitter_ms;
123   int audio_level;
124 };
125 
126 struct VoiceReceiverInfo {
127   uint32 ssrc;
128   int bytes_rcvd;
129   int packets_rcvd;
130   int packets_lost;
131   float fraction_lost;
132   int ext_seqnum;
133   int jitter_ms;
134   int audio_level;
135 };
136 
137 struct VideoSenderInfo {
138   uint32 ssrc;
139   int bytes_sent;
140   int packets_sent;
141   int packets_cached;
142   int packets_lost;
143   float fraction_lost;
144   int firs_rcvd;
145   int nacks_rcvd;
146   int rtt_ms;
147   int frame_width;
148   int frame_height;
149   int framerate_input;
150   int framerate_sent;
151 };
152 
153 struct VideoReceiverInfo {
154   uint32 ssrc;
155   int bytes_rcvd;
156   // vector<int> layer_bytes_rcvd;
157   int packets_rcvd;
158   int packets_lost;
159   int packets_concealed;
160   float fraction_lost;
161   int firs_sent;
162   int nacks_sent;
163   int frame_width;
164   int frame_height;
165   int framerate_rcvd;
166   int framerate_decoded;
167   int framerate_output;
168 };
169 
170 struct VoiceMediaInfo {
ClearVoiceMediaInfo171   void Clear() {
172     senders.clear();
173     receivers.clear();
174   }
175   std::vector<VoiceSenderInfo> senders;
176   std::vector<VoiceReceiverInfo> receivers;
177 };
178 
179 struct VideoMediaInfo {
ClearVideoMediaInfo180   void Clear() {
181     senders.clear();
182     receivers.clear();
183   }
184   std::vector<VideoSenderInfo> senders;
185   std::vector<VideoReceiverInfo> receivers;
186 };
187 
188 class VoiceMediaChannel : public MediaChannel {
189  public:
190   enum Error {
191     ERROR_NONE = 0,                       // No error.
192     ERROR_OTHER,                          // Other errors.
193     ERROR_REC_DEVICE_OPEN_FAILED = 100,   // Could not open mic.
194     ERROR_REC_DEVICE_MUTED,               // Mic was muted by OS.
195     ERROR_REC_DEVICE_SILENT,              // No background noise picked up.
196     ERROR_REC_DEVICE_SATURATION,          // Mic input is clipping.
197     ERROR_REC_DEVICE_REMOVED,             // Mic was removed while active.
198     ERROR_REC_RUNTIME_ERROR,              // Processing is encountering errors.
199     ERROR_REC_SRTP_ERROR,                 // Generic SRTP failure.
200     ERROR_PLAY_DEVICE_OPEN_FAILED = 200,  // Could not open playout.
201     ERROR_PLAY_DEVICE_MUTED,              // Playout muted by OS.
202     ERROR_PLAY_DEVICE_REMOVED,            // Playout removed while active.
203     ERROR_PLAY_RUNTIME_ERROR,             // Errors in voice processing.
204     ERROR_PLAY_SRTP_ERROR,                // Generic SRTP failure.
205     ERROR_PLAY_SRTP_AUTH_FAILED,          // Failed to authenticate packets.
206   };
207 
VoiceMediaChannel()208   VoiceMediaChannel() {}
~VoiceMediaChannel()209   virtual ~VoiceMediaChannel() {}
210   // Sets the codecs/payload types to be used for incoming media.
211   virtual bool SetRecvCodecs(const std::vector<AudioCodec>& codecs) = 0;
212   // Sets the codecs/payload types to be used for outgoing media.
213   virtual bool SetSendCodecs(const std::vector<AudioCodec>& codecs) = 0;
214   // Starts or stops playout of received audio.
215   virtual bool SetPlayout(bool playout) = 0;
216   // Starts or stops sending (and potentially capture) of local audio.
217   virtual bool SetSend(SendFlags flag) = 0;
218   // Adds a new receive-only stream with the specified SSRC.
219   virtual bool AddStream(uint32 ssrc) = 0;
220   // Removes a stream added with AddStream.
221   virtual bool RemoveStream(uint32 ssrc) = 0;
222   // Gets current energy levels for all incoming streams.
223   virtual bool GetActiveStreams(AudioInfo::StreamList* actives) = 0;
224   // Get the current energy level for the outgoing stream.
225   virtual int GetOutputLevel() = 0;
226   // Specifies a ringback tone to be played during call setup.
227   virtual void SetRingbackTone(const char *buf, int len) = 0;
228   // Plays or stops the aforementioned ringback tone
229   virtual bool PlayRingbackTone(bool play, bool loop) = 0;
230   // Sends a out-of-band DTMF signal using the specified event.
231   virtual bool PressDTMF(int event, bool playout) = 0;
232   // Gets quality stats for the channel.
233   virtual bool GetStats(VoiceMediaInfo* info) = 0;
234   // Gets last reported error for this media channel.
GetLastMediaError(uint32 * ssrc,VoiceMediaChannel::Error * error)235   virtual void GetLastMediaError(uint32* ssrc,
236                                  VoiceMediaChannel::Error* error) {
237     ASSERT(error != NULL);
238     *error = ERROR_NONE;
239   }
240 
241   // Signal errors from MediaChannel.  Arguments are:
242   //     ssrc(uint32), and error(VoiceMediaChannel::Error).
243   sigslot::signal2<uint32, VoiceMediaChannel::Error> SignalMediaError;
244 };
245 
246 // Represents a YUV420 (a.k.a. I420) video frame.
247 class VideoFrame {
248   friend class flute::MagicCamVideoRenderer;
249 
250  public:
VideoFrame()251   VideoFrame() : rendered_(false) {}
252 
~VideoFrame()253   virtual ~VideoFrame() {}
254 
255   virtual size_t GetWidth() const = 0;
256   virtual size_t GetHeight() const = 0;
257   virtual const uint8 *GetYPlane() const = 0;
258   virtual const uint8 *GetUPlane() const = 0;
259   virtual const uint8 *GetVPlane() const = 0;
260   virtual uint8 *GetYPlane() = 0;
261   virtual uint8 *GetUPlane() = 0;
262   virtual uint8 *GetVPlane() = 0;
263   virtual int32 GetYPitch() const = 0;
264   virtual int32 GetUPitch() const = 0;
265   virtual int32 GetVPitch() const = 0;
266 
267   // For retrieving the aspect ratio of each pixel. Usually this is 1x1, but
268   // the aspect_ratio_idc parameter of H.264 can specify non-square pixels.
269   virtual size_t GetPixelWidth() const = 0;
270   virtual size_t GetPixelHeight() const = 0;
271 
272   // TODO: Add a fourcc format here and probably combine VideoFrame
273   // with CapturedFrame.
274   virtual int64 GetElapsedTime() const = 0;
275   virtual int64 GetTimeStamp() const = 0;
276   virtual void SetElapsedTime(int64 elapsed_time) = 0;
277   virtual void SetTimeStamp(int64 time_stamp) = 0;
278 
279   // Make a copy of the frame. The frame buffer itself may not be copied,
280   // in which case both the current and new VideoFrame will share a single
281   // reference-counted frame buffer.
282   virtual VideoFrame *Copy() const = 0;
283 
284   // Writes the frame into the given frame buffer, provided that it is of
285   // sufficient size. Returns the frame's actual size, regardless of whether
286   // it was written or not (like snprintf). If there is insufficient space,
287   // nothing is written.
288   virtual size_t CopyToBuffer(uint8 *buffer, size_t size) const = 0;
289 
290   // Converts the I420 data to RGB of a certain type such as ARGB and ABGR.
291   // Returns the frame's actual size, regardless of whether it was written or
292   // not (like snprintf). Parameters size and pitch_rgb are in units of bytes.
293   // If there is insufficient space, nothing is written.
294   virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, uint8 *buffer,
295                                     size_t size, size_t pitch_rgb) const = 0;
296 
297   // Writes the frame into the given planes, stretched to the given width and
298   // height. The parameter "interpolate" controls whether to interpolate or just
299   // take the nearest-point. The parameter "crop" controls whether to crop this
300   // frame to the aspect ratio of the given dimensions before stretching.
301   virtual void StretchToPlanes(uint8 *y, uint8 *u, uint8 *v,
302                                int32 pitchY, int32 pitchU, int32 pitchV,
303                                size_t width, size_t height,
304                                bool interpolate, bool crop) const = 0;
305 
306   // Writes the frame into the given frame buffer, stretched to the given width
307   // and height, provided that it is of sufficient size. Returns the frame's
308   // actual size, regardless of whether it was written or not (like snprintf).
309   // If there is insufficient space, nothing is written. The parameter
310   // "interpolate" controls whether to interpolate or just take the
311   // nearest-point. The parameter "crop" controls whether to crop this frame to
312   // the aspect ratio of the given dimensions before stretching.
313   virtual size_t StretchToBuffer(size_t w, size_t h, uint8 *buffer, size_t size,
314                                  bool interpolate, bool crop) const = 0;
315 
316   // Writes the frame into the target VideoFrame, stretched to the size of that
317   // frame. The parameter "interpolate" controls whether to interpolate or just
318   // take the nearest-point. The parameter "crop" controls whether to crop this
319   // frame to the aspect ratio of the target frame before stretching.
320   virtual void StretchToFrame(VideoFrame *target, bool interpolate,
321                               bool crop) const = 0;
322 
323   // Stretches the frame to the given size, creating a new VideoFrame object to
324   // hold it. The parameter "interpolate" controls whether to interpolate or
325   // just take the nearest-point. The parameter "crop" controls whether to crop
326   // this frame to the aspect ratio of the given dimensions before stretching.
327   virtual VideoFrame *Stretch(size_t w, size_t h, bool interpolate,
328                               bool crop) const = 0;
329 
330   // Size of an I420 image of given dimensions when stored as a frame buffer.
SizeOf(size_t w,size_t h)331   static size_t SizeOf(size_t w, size_t h) {
332     return w * h + ((w + 1) / 2) * ((h + 1) / 2) * 2;
333   }
334 
335  protected:
336   // The frame needs to be rendered to magiccam only once.
337   // TODO: Remove this flag once magiccam rendering is fully replaced
338   // by client3d rendering.
339   mutable bool rendered_;
340 };
341 
342 // Simple subclass for use in mocks.
343 class NullVideoFrame : public VideoFrame {
344  public:
GetWidth()345   virtual size_t GetWidth() const { return 0; }
GetHeight()346   virtual size_t GetHeight() const { return 0; }
GetYPlane()347   virtual const uint8 *GetYPlane() const { return NULL; }
GetUPlane()348   virtual const uint8 *GetUPlane() const { return NULL; }
GetVPlane()349   virtual const uint8 *GetVPlane() const { return NULL; }
GetYPlane()350   virtual uint8 *GetYPlane() { return NULL; }
GetUPlane()351   virtual uint8 *GetUPlane() { return NULL; }
GetVPlane()352   virtual uint8 *GetVPlane() { return NULL; }
GetYPitch()353   virtual int32 GetYPitch() const { return 0; }
GetUPitch()354   virtual int32 GetUPitch() const { return 0; }
GetVPitch()355   virtual int32 GetVPitch() const { return 0; }
356 
GetPixelWidth()357   virtual size_t GetPixelWidth() const { return 1; }
GetPixelHeight()358   virtual size_t GetPixelHeight() const { return 1; }
GetElapsedTime()359   virtual int64 GetElapsedTime() const { return 0; }
GetTimeStamp()360   virtual int64 GetTimeStamp() const { return 0; }
SetElapsedTime(int64 elapsed_time)361   virtual void SetElapsedTime(int64 elapsed_time) {}
SetTimeStamp(int64 time_stamp)362   virtual void SetTimeStamp(int64 time_stamp) {}
363 
Copy()364   virtual VideoFrame *Copy() const {
365     return NULL;
366   }
367 
CopyToBuffer(uint8 * buffer,size_t size)368   virtual size_t CopyToBuffer(uint8 *buffer, size_t size) const {
369     return 0;
370   }
371 
ConvertToRgbBuffer(uint32 to_fourcc,uint8 * buffer,size_t size,size_t pitch_rgb)372   virtual size_t ConvertToRgbBuffer(uint32 to_fourcc, uint8 *buffer,
373                                     size_t size, size_t pitch_rgb) const {
374     return 0;
375   }
376 
StretchToPlanes(uint8 * y,uint8 * u,uint8 * v,int32 pitchY,int32 pitchU,int32 pitchV,size_t width,size_t height,bool interpolate,bool crop)377   virtual void StretchToPlanes(uint8 *y, uint8 *u, uint8 *v,
378                                int32 pitchY, int32 pitchU, int32 pitchV,
379                                size_t width, size_t height,
380                                bool interpolate, bool crop) const {
381   }
382 
StretchToBuffer(size_t w,size_t h,uint8 * buffer,size_t size,bool interpolate,bool crop)383   virtual size_t StretchToBuffer(size_t w, size_t h, uint8 *buffer, size_t size,
384                                  bool interpolate, bool crop) const {
385     return 0;
386   }
387 
StretchToFrame(VideoFrame * target,bool interpolate,bool crop)388   virtual void StretchToFrame(VideoFrame *target, bool interpolate,
389                               bool crop) const {
390   }
391 
Stretch(size_t w,size_t h,bool interpolate,bool crop)392   virtual VideoFrame *Stretch(size_t w, size_t h, bool interpolate,
393                               bool crop) const {
394     return NULL;
395   }
396 };
397 
398 // Abstract interface for rendering VideoFrames.
399 class VideoRenderer {
400  public:
~VideoRenderer()401   virtual ~VideoRenderer() {}
402   // Called when the video has changed size.
403   virtual bool SetSize(int width, int height, int reserved) = 0;
404   // Called when a new frame is available for display.
405   virtual bool RenderFrame(const VideoFrame *frame) = 0;
406 };
407 
408 // Simple implementation for use in tests.
409 class NullVideoRenderer : public VideoRenderer {
SetSize(int width,int height,int reserved)410   virtual bool SetSize(int width, int height, int reserved) {
411     return true;
412   }
413   // Called when a new frame is available for display.
RenderFrame(const VideoFrame * frame)414   virtual bool RenderFrame(const VideoFrame *frame) {
415     return true;
416   }
417 };
418 
419 class VideoMediaChannel : public MediaChannel {
420  public:
421   enum Error {
422     ERROR_NONE = 0,                       // No error.
423     ERROR_OTHER,                          // Other errors.
424     ERROR_REC_DEVICE_OPEN_FAILED = 100,   // Could not open camera.
425     ERROR_REC_DEVICE_NO_DEVICE,           // No camera.
426     ERROR_REC_DEVICE_IN_USE,              // Device is in already use.
427     ERROR_REC_DEVICE_REMOVED,             // Device is removed.
428     ERROR_REC_SRTP_ERROR,                 // Generic sender SRTP failure.
429     ERROR_PLAY_SRTP_ERROR = 200,          // Generic receiver SRTP failure.
430     ERROR_PLAY_SRTP_AUTH_FAILED,          // Failed to authenticate packets.
431   };
432 
VideoMediaChannel()433   VideoMediaChannel() { renderer_ = NULL; }
~VideoMediaChannel()434   virtual ~VideoMediaChannel() {}
435   // Sets the codecs/payload types to be used for incoming media.
436   virtual bool SetRecvCodecs(const std::vector<VideoCodec> &codecs) = 0;
437   // Sets the codecs/payload types to be used for outgoing media.
438   virtual bool SetSendCodecs(const std::vector<VideoCodec> &codecs) = 0;
439   // Starts or stops playout of received video.
440   virtual bool SetRender(bool render) = 0;
441   // Starts or stops transmission (and potentially capture) of local video.
442   virtual bool SetSend(bool send) = 0;
443   // Adds a new receive-only stream with the specified SSRC.
444   virtual bool AddStream(uint32 ssrc, uint32 voice_ssrc) = 0;
445   // Removes a stream added with AddStream.
446   virtual bool RemoveStream(uint32 ssrc) = 0;
447   // Sets the renderer object to be used for the specified stream.
448   // If SSRC is 0, the renderer is used for the 'default' stream.
449   virtual bool SetRenderer(uint32 ssrc, VideoRenderer* renderer) = 0;
450   // Gets quality stats for the channel.
451   virtual bool GetStats(VideoMediaInfo* info) = 0;
452 
453   // Send an intra frame to the receivers.
454   virtual bool SendIntraFrame() = 0;
455   // Reuqest each of the remote senders to send an intra frame.
456   virtual bool RequestIntraFrame() = 0;
457 
458   sigslot::signal2<uint32, Error> SignalMediaError;
459 
460  protected:
461   VideoRenderer *renderer_;
462 };
463 
464 }  // namespace cricket
465 
466 #endif  // TALK_SESSION_PHONE_MEDIACHANNEL_H_
467