OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright 2004 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 | 95 |
96 RtpTransceiverDirection Reversed() const { | 96 RtpTransceiverDirection Reversed() const { |
97 return RtpTransceiverDirection(recv, send); | 97 return RtpTransceiverDirection(recv, send); |
98 } | 98 } |
99 }; | 99 }; |
100 | 100 |
101 RtpTransceiverDirection | 101 RtpTransceiverDirection |
102 NegotiateRtpTransceiverDirection(RtpTransceiverDirection offer, | 102 NegotiateRtpTransceiverDirection(RtpTransceiverDirection offer, |
103 RtpTransceiverDirection wants); | 103 RtpTransceiverDirection wants); |
104 | 104 |
105 struct SenderOptions { | |
106 std::string track_id; | |
107 std::string stream_id; | |
108 int num_sim_layers; | |
109 }; | |
110 | |
111 // Options for an individual media description/"m=" section. | |
112 struct MediaDescriptionOptions { | |
113 MediaDescriptionOptions(MediaType type, | |
114 const std::string& mid, | |
115 RtpTransceiverDirection direction, | |
116 bool stopped) | |
117 : type(type), mid(mid), direction(direction), stopped(stopped) {} | |
118 | |
119 // TODO(deadbeef): When we don't support Plan B, there will only be one | |
120 // sender per transceiver and this can be simplified. | |
Taylor Brandstetter
2017/07/28 01:19:39
nit: Can change this comment to say "per media des
Zhi Huang
2017/08/02 04:38:35
Done.
| |
121 void AddAudioSender(const std::string& track_id, | |
122 const std::string& stream_id); | |
123 void AddVideoSender(const std::string& track_id, | |
124 const std::string& stream_id, | |
125 int num_sim_layers); | |
126 | |
127 // Internally just uses sender_options. | |
128 void AddRtpDataChannel(const std::string& track_id, | |
129 const std::string& stream_id); | |
130 | |
131 MediaType type; | |
132 // TODO: Stop using mid for identification, doesn't work for endpoints that | |
133 // don't use MID. | |
Taylor Brandstetter
2017/07/28 01:19:39
Can this TODO be removed? Are the tests for "endpo
Zhi Huang
2017/08/02 04:38:35
Done.
| |
134 std::string mid; | |
135 RtpTransceiverDirection direction; | |
136 bool stopped; | |
137 TransportOptions transport_options; | |
138 // Note: There's no equivalent "RtpReceiverOptions" because only send | |
139 // stream information goes in local descriptions. | |
Taylor Brandstetter
2017/07/28 01:19:39
nit: Add "the" before "local descriptions".
Zhi Huang
2017/08/02 04:38:35
Done.
| |
140 std::vector<SenderOptions> sender_options; | |
141 | |
142 private: | |
143 // Doesn't DCHECK on |type|. | |
144 void AddSenderInternal(const std::string& track_id, | |
145 const std::string& stream_id, | |
146 int num_sim_layers); | |
147 }; | |
148 | |
149 // Provides a mechanism for describing how m= sections should be generated. | |
150 // The m= section with index X will use media_description_options[X]. If no such | |
151 // MediaDescriptionOptions exists, the m= section will just be rejected (port of | |
152 // 0). If |data_channel_type| is not DCT_NONE, a data m= section will be | |
153 // generated in the next available space. | |
Taylor Brandstetter
2017/07/28 01:19:39
Is this comment about data_channel_type still vali
Zhi Huang
2017/08/02 04:38:35
The comments should be updated.
| |
105 struct MediaSessionOptions { | 154 struct MediaSessionOptions { |
106 MediaSessionOptions() | 155 MediaSessionOptions() {} |
107 : recv_audio(true), | |
108 recv_video(false), | |
109 data_channel_type(DCT_NONE), | |
110 is_muc(false), | |
111 vad_enabled(true), // When disabled, removes all CN codecs from SDP. | |
112 rtcp_mux_enabled(true), | |
113 bundle_enabled(false), | |
114 video_bandwidth(kAutoBandwidth), | |
115 data_bandwidth(kDataMaxBandwidth), | |
116 rtcp_cname(kDefaultRtcpCname) {} | |
117 | 156 |
118 bool has_audio() const { | 157 bool has_audio() const { return HasMediaDescription(MEDIA_TYPE_AUDIO); } |
119 return recv_audio || HasSendMediaStream(MEDIA_TYPE_AUDIO); | 158 bool has_video() const { return HasMediaDescription(MEDIA_TYPE_VIDEO); } |
120 } | 159 bool has_data() const { return HasMediaDescription(MEDIA_TYPE_DATA); } |
121 bool has_video() const { | |
122 return recv_video || HasSendMediaStream(MEDIA_TYPE_VIDEO); | |
123 } | |
124 bool has_data() const { return data_channel_type != DCT_NONE; } | |
125 | 160 |
126 // Add a stream with MediaType type and id. | 161 bool HasMediaDescription(MediaType type) const; |
127 // All streams with the same sync_label will get the same CNAME. | |
128 // All ids must be unique. | |
129 void AddSendStream(MediaType type, | |
130 const std::string& id, | |
131 const std::string& sync_label); | |
132 void AddSendVideoStream(const std::string& id, | |
133 const std::string& sync_label, | |
134 int num_sim_layers); | |
135 void RemoveSendStream(MediaType type, const std::string& id); | |
136 | 162 |
163 // They're not stored in a map in the first place because the order matters. | |
164 // TODO: make index-based | |
Taylor Brandstetter
2017/07/28 01:19:39
Is this method even still used?
Zhi Huang
2017/08/02 04:38:35
Since MID is not the identification, I think we ca
| |
165 std::vector<MediaDescriptionOptions>::iterator FindMediaDescription( | |
166 const std::string& mid); | |
137 | 167 |
138 // Helper function. | 168 DataChannelType data_channel_type = DCT_NONE; |
139 void AddSendStreamInternal(MediaType type, | 169 bool is_muc = false; |
140 const std::string& id, | 170 bool vad_enabled = true; // When disabled, removes all CN codecs from SDP. |
141 const std::string& sync_label, | 171 bool rtcp_mux_enabled = true; |
142 int num_sim_layers); | 172 bool bundle_enabled = false; |
143 | 173 std::string rtcp_cname = kDefaultRtcpCname; |
144 bool HasSendMediaStream(MediaType type) const; | |
145 | |
146 // TODO(deadbeef): Put all the audio/video/data-specific options into a map | |
147 // structure (content name -> options). | |
148 // MediaSessionDescriptionFactory assumes there will never be more than one | |
149 // audio/video/data content, but this will change with unified plan. | |
150 bool recv_audio; | |
151 bool recv_video; | |
152 DataChannelType data_channel_type; | |
153 bool is_muc; | |
154 bool vad_enabled; | |
155 bool rtcp_mux_enabled; | |
156 bool bundle_enabled; | |
157 // bps. -1 == auto. | |
158 int video_bandwidth; | |
159 int data_bandwidth; | |
160 bool enable_ice_renomination = false; | |
161 // content name ("mid") => options. | |
162 std::map<std::string, TransportOptions> transport_options; | |
163 std::string rtcp_cname; | |
164 rtc::CryptoOptions crypto_options; | 174 rtc::CryptoOptions crypto_options; |
165 | 175 // List of media description options in the same order that the media |
166 struct Stream { | 176 // descriptions will be generated. |
167 Stream(MediaType type, | 177 std::vector<MediaDescriptionOptions> media_description_options; |
168 const std::string& id, | |
169 const std::string& sync_label, | |
170 int num_sim_layers) | |
171 : type(type), id(id), sync_label(sync_label), | |
172 num_sim_layers(num_sim_layers) { | |
173 } | |
174 MediaType type; | |
175 std::string id; | |
176 std::string sync_label; | |
177 int num_sim_layers; | |
178 }; | |
179 | |
180 typedef std::vector<Stream> Streams; | |
181 Streams streams; | |
182 }; | 178 }; |
183 | 179 |
184 // "content" (as used in XEP-0166) descriptions for voice and video. | 180 // "content" (as used in XEP-0166) descriptions for voice and video. |
185 class MediaContentDescription : public ContentDescription { | 181 class MediaContentDescription : public ContentDescription { |
186 public: | 182 public: |
187 MediaContentDescription() {} | 183 MediaContentDescription() {} |
188 | 184 |
189 virtual MediaType type() const = 0; | 185 virtual MediaType type() const = 0; |
190 virtual bool has_codecs() const = 0; | 186 virtual bool has_codecs() const = 0; |
191 | 187 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
270 // Legacy streams have an ssrc, but nothing else. | 266 // Legacy streams have an ssrc, but nothing else. |
271 void AddLegacyStream(uint32_t ssrc) { | 267 void AddLegacyStream(uint32_t ssrc) { |
272 streams_.push_back(StreamParams::CreateLegacy(ssrc)); | 268 streams_.push_back(StreamParams::CreateLegacy(ssrc)); |
273 } | 269 } |
274 void AddLegacyStream(uint32_t ssrc, uint32_t fid_ssrc) { | 270 void AddLegacyStream(uint32_t ssrc, uint32_t fid_ssrc) { |
275 StreamParams sp = StreamParams::CreateLegacy(ssrc); | 271 StreamParams sp = StreamParams::CreateLegacy(ssrc); |
276 sp.AddFidSsrc(ssrc, fid_ssrc); | 272 sp.AddFidSsrc(ssrc, fid_ssrc); |
277 streams_.push_back(sp); | 273 streams_.push_back(sp); |
278 } | 274 } |
279 // Sets the CNAME of all StreamParams if it have not been set. | 275 // Sets the CNAME of all StreamParams if it have not been set. |
280 // This can be used to set the CNAME of legacy streams. | |
281 void SetCnameIfEmpty(const std::string& cname) { | 276 void SetCnameIfEmpty(const std::string& cname) { |
282 for (cricket::StreamParamsVec::iterator it = streams_.begin(); | 277 for (cricket::StreamParamsVec::iterator it = streams_.begin(); |
283 it != streams_.end(); ++it) { | 278 it != streams_.end(); ++it) { |
284 if (it->cname.empty()) | 279 if (it->cname.empty()) |
285 it->cname = cname; | 280 it->cname = cname; |
286 } | 281 } |
287 } | 282 } |
288 uint32_t first_ssrc() const { | 283 uint32_t first_ssrc() const { |
289 if (streams_.empty()) { | 284 if (streams_.empty()) { |
290 return 0; | 285 return 0; |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
462 void set_video_rtp_header_extensions(const RtpHeaderExtensions& extensions) { | 457 void set_video_rtp_header_extensions(const RtpHeaderExtensions& extensions) { |
463 video_rtp_extensions_ = extensions; | 458 video_rtp_extensions_ = extensions; |
464 } | 459 } |
465 const RtpHeaderExtensions& video_rtp_header_extensions() const { | 460 const RtpHeaderExtensions& video_rtp_header_extensions() const { |
466 return video_rtp_extensions_; | 461 return video_rtp_extensions_; |
467 } | 462 } |
468 const DataCodecs& data_codecs() const { return data_codecs_; } | 463 const DataCodecs& data_codecs() const { return data_codecs_; } |
469 void set_data_codecs(const DataCodecs& codecs) { data_codecs_ = codecs; } | 464 void set_data_codecs(const DataCodecs& codecs) { data_codecs_ = codecs; } |
470 SecurePolicy secure() const { return secure_; } | 465 SecurePolicy secure() const { return secure_; } |
471 void set_secure(SecurePolicy s) { secure_ = s; } | 466 void set_secure(SecurePolicy s) { secure_ = s; } |
472 // Decides if a StreamParams shall be added to the audio and video media | |
473 // content in SessionDescription when CreateOffer and CreateAnswer is called | |
474 // even if |options| don't include a Stream. This is needed to support legacy | |
475 // applications. |add_legacy_| is true per default. | |
476 void set_add_legacy_streams(bool add_legacy) { add_legacy_ = add_legacy; } | |
477 | 467 |
478 void set_enable_encrypted_rtp_header_extensions(bool enable) { | 468 void set_enable_encrypted_rtp_header_extensions(bool enable) { |
479 enable_encrypted_rtp_header_extensions_ = enable; | 469 enable_encrypted_rtp_header_extensions_ = enable; |
480 } | 470 } |
481 | 471 |
482 SessionDescription* CreateOffer( | 472 SessionDescription* CreateOffer( |
483 const MediaSessionOptions& options, | 473 const MediaSessionOptions& options, |
484 const SessionDescription* current_description) const; | 474 const SessionDescription* current_description) const; |
485 SessionDescription* CreateAnswer( | 475 SessionDescription* CreateAnswer( |
486 const SessionDescription* offer, | 476 const SessionDescription* offer, |
487 const MediaSessionOptions& options, | 477 const MediaSessionOptions& options, |
488 const SessionDescription* current_description) const; | 478 const SessionDescription* current_description) const; |
489 | 479 |
490 private: | 480 private: |
491 const AudioCodecs& GetAudioCodecsForOffer( | 481 const AudioCodecs& GetAudioCodecsForOffer( |
492 const RtpTransceiverDirection& direction) const; | 482 const RtpTransceiverDirection& direction) const; |
493 const AudioCodecs& GetAudioCodecsForAnswer( | 483 const AudioCodecs& GetAudioCodecsForAnswer( |
494 const RtpTransceiverDirection& offer, | 484 const RtpTransceiverDirection& offer, |
495 const RtpTransceiverDirection& answer) const; | 485 const RtpTransceiverDirection& answer) const; |
496 void GetCodecsToOffer(const SessionDescription* current_description, | 486 void GetCodecsForOffer(const SessionDescription* current_description, |
497 const AudioCodecs& supported_audio_codecs, | 487 AudioCodecs* audio_codecs, |
498 const VideoCodecs& supported_video_codecs, | 488 VideoCodecs* video_codecs, |
499 const DataCodecs& supported_data_codecs, | 489 DataCodecs* data_codecs) const; |
500 AudioCodecs* audio_codecs, | 490 void GetCodecsForAnswer(const SessionDescription* current_description, |
501 VideoCodecs* video_codecs, | 491 const SessionDescription* remote_offer, |
502 DataCodecs* data_codecs) const; | 492 AudioCodecs* audio_codecs, |
493 VideoCodecs* video_codecs, | |
494 DataCodecs* data_codecs) const; | |
503 void GetRtpHdrExtsToOffer(const SessionDescription* current_description, | 495 void GetRtpHdrExtsToOffer(const SessionDescription* current_description, |
504 RtpHeaderExtensions* audio_extensions, | 496 RtpHeaderExtensions* audio_extensions, |
505 RtpHeaderExtensions* video_extensions) const; | 497 RtpHeaderExtensions* video_extensions) const; |
506 bool AddTransportOffer( | 498 bool AddTransportOffer( |
507 const std::string& content_name, | 499 const std::string& content_name, |
508 const TransportOptions& transport_options, | 500 const TransportOptions& transport_options, |
509 const SessionDescription* current_desc, | 501 const SessionDescription* current_desc, |
510 SessionDescription* offer) const; | 502 SessionDescription* offer) const; |
511 | 503 |
512 TransportDescription* CreateTransportAnswer( | 504 TransportDescription* CreateTransportAnswer( |
513 const std::string& content_name, | 505 const std::string& content_name, |
514 const SessionDescription* offer_desc, | 506 const SessionDescription* offer_desc, |
515 const TransportOptions& transport_options, | 507 const TransportOptions& transport_options, |
516 const SessionDescription* current_desc, | 508 const SessionDescription* current_desc, |
517 bool require_transport_attributes) const; | 509 bool require_transport_attributes) const; |
518 | 510 |
519 bool AddTransportAnswer( | 511 bool AddTransportAnswer( |
520 const std::string& content_name, | 512 const std::string& content_name, |
521 const TransportDescription& transport_desc, | 513 const TransportDescription& transport_desc, |
522 SessionDescription* answer_desc) const; | 514 SessionDescription* answer_desc) const; |
523 | 515 |
524 // Helpers for adding media contents to the SessionDescription. Returns true | 516 // Helpers for adding media contents to the SessionDescription. Returns true |
525 // it succeeds or the media content is not needed, or false if there is any | 517 // it succeeds or the media content is not needed, or false if there is any |
526 // error. | 518 // error. |
527 | 519 |
528 bool AddAudioContentForOffer( | 520 bool AddAudioContentForOffer( |
529 const MediaSessionOptions& options, | 521 const MediaDescriptionOptions& media_description_options, |
522 const MediaSessionOptions& session_options, | |
523 const ContentInfo* current_content, | |
530 const SessionDescription* current_description, | 524 const SessionDescription* current_description, |
531 const RtpHeaderExtensions& audio_rtp_extensions, | 525 const RtpHeaderExtensions& audio_rtp_extensions, |
532 const AudioCodecs& audio_codecs, | 526 const AudioCodecs& audio_codecs, |
533 StreamParamsVec* current_streams, | 527 StreamParamsVec* current_streams, |
534 SessionDescription* desc) const; | 528 SessionDescription* desc) const; |
535 | 529 |
536 bool AddVideoContentForOffer( | 530 bool AddVideoContentForOffer( |
537 const MediaSessionOptions& options, | 531 const MediaDescriptionOptions& media_description_options, |
532 const MediaSessionOptions& session_options, | |
533 const ContentInfo* current_content, | |
538 const SessionDescription* current_description, | 534 const SessionDescription* current_description, |
539 const RtpHeaderExtensions& video_rtp_extensions, | 535 const RtpHeaderExtensions& video_rtp_extensions, |
540 const VideoCodecs& video_codecs, | 536 const VideoCodecs& video_codecs, |
541 StreamParamsVec* current_streams, | 537 StreamParamsVec* current_streams, |
542 SessionDescription* desc) const; | 538 SessionDescription* desc) const; |
543 | 539 |
544 bool AddDataContentForOffer( | 540 bool AddDataContentForOffer( |
545 const MediaSessionOptions& options, | 541 const MediaDescriptionOptions& media_description_options, |
542 const MediaSessionOptions& session_options, | |
543 const ContentInfo* current_content, | |
546 const SessionDescription* current_description, | 544 const SessionDescription* current_description, |
547 DataCodecs* data_codecs, | 545 const DataCodecs& data_codecs, |
548 StreamParamsVec* current_streams, | 546 StreamParamsVec* current_streams, |
549 SessionDescription* desc) const; | 547 SessionDescription* desc) const; |
550 | 548 |
551 bool AddAudioContentForAnswer(const SessionDescription* offer, | 549 bool AddAudioContentForAnswer( |
552 const MediaSessionOptions& options, | 550 const MediaDescriptionOptions& media_description_options, |
553 const SessionDescription* current_description, | 551 const MediaSessionOptions& session_options, |
554 const TransportInfo* bundle_transport, | 552 const ContentInfo* offer_content, |
555 StreamParamsVec* current_streams, | 553 const SessionDescription* offer_description, |
556 SessionDescription* answer) const; | 554 const ContentInfo* current_content, |
555 const SessionDescription* current_description, | |
556 const TransportInfo* bundle_transport, | |
557 const AudioCodecs& audio_codecs, | |
558 StreamParamsVec* current_streams, | |
559 SessionDescription* answer) const; | |
557 | 560 |
558 bool AddVideoContentForAnswer(const SessionDescription* offer, | 561 bool AddVideoContentForAnswer( |
559 const MediaSessionOptions& options, | 562 const MediaDescriptionOptions& media_description_options, |
560 const SessionDescription* current_description, | 563 const MediaSessionOptions& session_options, |
561 const TransportInfo* bundle_transport, | 564 const ContentInfo* offer_content, |
562 StreamParamsVec* current_streams, | 565 const SessionDescription* offer_description, |
563 SessionDescription* answer) const; | 566 const ContentInfo* current_content, |
567 const SessionDescription* current_description, | |
568 const TransportInfo* bundle_transport, | |
569 const VideoCodecs& video_codecs, | |
570 StreamParamsVec* current_streams, | |
571 SessionDescription* answer) const; | |
564 | 572 |
565 bool AddDataContentForAnswer(const SessionDescription* offer, | 573 bool AddDataContentForAnswer( |
566 const MediaSessionOptions& options, | 574 const MediaDescriptionOptions& media_description_options, |
567 const SessionDescription* current_description, | 575 const MediaSessionOptions& session_options, |
568 const TransportInfo* bundle_transport, | 576 const ContentInfo* offer_content, |
569 StreamParamsVec* current_streams, | 577 const SessionDescription* offer_description, |
570 SessionDescription* answer) const; | 578 const ContentInfo* current_content, |
579 const SessionDescription* current_description, | |
580 const TransportInfo* bundle_transport, | |
581 const DataCodecs& data_codecs, | |
582 StreamParamsVec* current_streams, | |
583 SessionDescription* answer) const; | |
584 | |
585 void ComputeAudioCodecsIntersectionAndUnion(); | |
571 | 586 |
572 AudioCodecs audio_send_codecs_; | 587 AudioCodecs audio_send_codecs_; |
573 AudioCodecs audio_recv_codecs_; | 588 AudioCodecs audio_recv_codecs_; |
589 // Intersection of send and recv. | |
574 AudioCodecs audio_sendrecv_codecs_; | 590 AudioCodecs audio_sendrecv_codecs_; |
591 // Union of send and recv. | |
592 AudioCodecs all_audio_codecs_; | |
575 RtpHeaderExtensions audio_rtp_extensions_; | 593 RtpHeaderExtensions audio_rtp_extensions_; |
576 VideoCodecs video_codecs_; | 594 VideoCodecs video_codecs_; |
577 RtpHeaderExtensions video_rtp_extensions_; | 595 RtpHeaderExtensions video_rtp_extensions_; |
578 DataCodecs data_codecs_; | 596 DataCodecs data_codecs_; |
579 SecurePolicy secure_; | |
580 bool add_legacy_; | |
581 bool enable_encrypted_rtp_header_extensions_ = false; | 597 bool enable_encrypted_rtp_header_extensions_ = false; |
598 SecurePolicy secure_ = SEC_DISABLED; | |
582 std::string lang_; | 599 std::string lang_; |
583 const TransportDescriptionFactory* transport_desc_factory_; | 600 const TransportDescriptionFactory* transport_desc_factory_; |
584 }; | 601 }; |
585 | 602 |
586 // Convenience functions. | 603 // Convenience functions. |
587 bool IsMediaContent(const ContentInfo* content); | 604 bool IsMediaContent(const ContentInfo* content); |
588 bool IsAudioContent(const ContentInfo* content); | 605 bool IsAudioContent(const ContentInfo* content); |
589 bool IsVideoContent(const ContentInfo* content); | 606 bool IsVideoContent(const ContentInfo* content); |
590 bool IsDataContent(const ContentInfo* content); | 607 bool IsDataContent(const ContentInfo* content); |
591 const ContentInfo* GetFirstMediaContent(const ContentInfos& contents, | 608 const ContentInfo* GetFirstMediaContent(const ContentInfos& contents, |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
631 void GetSupportedVideoSdesCryptoSuiteNames( | 648 void GetSupportedVideoSdesCryptoSuiteNames( |
632 const rtc::CryptoOptions& crypto_options, | 649 const rtc::CryptoOptions& crypto_options, |
633 std::vector<std::string>* crypto_suite_names); | 650 std::vector<std::string>* crypto_suite_names); |
634 void GetSupportedDataSdesCryptoSuiteNames( | 651 void GetSupportedDataSdesCryptoSuiteNames( |
635 const rtc::CryptoOptions& crypto_options, | 652 const rtc::CryptoOptions& crypto_options, |
636 std::vector<std::string>* crypto_suite_names); | 653 std::vector<std::string>* crypto_suite_names); |
637 | 654 |
638 } // namespace cricket | 655 } // namespace cricket |
639 | 656 |
640 #endif // WEBRTC_PC_MEDIASESSION_H_ | 657 #endif // WEBRTC_PC_MEDIASESSION_H_ |
OLD | NEW |