Skip to content

Commit 374b892

Browse files
Harald AlvestrandWebRTC LUCI CQ
authored andcommitted
Revert "Assign supported codecs per section, not globally."
This reverts commit c92fc76. Reason for revert: Gerritt submitted patch set #10 not #12 - this broke Original change's description: > Assign supported codecs per section, not globally. > > This uses the PayloadTypeSuggester for PT disambiguation, > ensuring that conficts are managed across the transport. > > Bug: webrtc:360058654 > Change-Id: Ic8f0569d0d96d97c13765169903929ec8a110104 > Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/383400 > Commit-Queue: Harald Alvestrand <[email protected]> > Reviewed-by: Evan Shrubsole <[email protected]> > Reviewed-by: Henrik Boström <[email protected]> > Cr-Commit-Position: refs/heads/main@{#44284} Bug: webrtc:360058654 No-Presubmit: true No-Tree-Checks: true No-Try: true Change-Id: I16d0d92fb9a1ecc65eda060f81d41faefcca1e4c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/384000 Commit-Queue: Harald Alvestrand <[email protected]> Reviewed-by: Danil Chapovalov <[email protected]> Bot-Commit: [email protected] <[email protected]> Reviewed-by: Mirko Bonadei <[email protected]> Cr-Commit-Position: refs/heads/main@{#44285}
1 parent c92fc76 commit 374b892

8 files changed

+218
-161
lines changed

pc/codec_vendor.cc

Lines changed: 160 additions & 140 deletions
Original file line numberDiff line numberDiff line change
@@ -166,94 +166,6 @@ const Codec* GetAssociatedCodecForRed(const CodecList& codec_list,
166166
// Adds all codecs from `reference_codecs` to `offered_codecs` that don't
167167
// already exist in `offered_codecs` and ensure the payload types don't
168168
// collide.
169-
RTCError MergeCodecs(const CodecList& reference_codecs,
170-
const std::string& mid,
171-
CodecList& offered_codecs,
172-
PayloadTypeSuggester& pt_suggester) {
173-
// Add all new codecs that are not RTX/RED codecs.
174-
// The two-pass splitting of the loops means preferring payload types
175-
// of actual codecs with respect to collisions.
176-
for (const Codec& reference_codec : reference_codecs) {
177-
if (reference_codec.GetResiliencyType() != Codec::ResiliencyType::kRtx &&
178-
reference_codec.GetResiliencyType() != Codec::ResiliencyType::kRed &&
179-
!FindMatchingCodec(reference_codecs, offered_codecs, reference_codec)) {
180-
Codec codec = reference_codec;
181-
RTCErrorOr<webrtc::PayloadType> suggestion =
182-
pt_suggester.SuggestPayloadType(mid, codec);
183-
if (!suggestion.ok()) {
184-
return suggestion.MoveError();
185-
}
186-
codec.id = suggestion.value();
187-
offered_codecs.push_back(codec);
188-
}
189-
}
190-
191-
// Add all new RTX or RED codecs.
192-
for (const Codec& reference_codec : reference_codecs) {
193-
if (reference_codec.GetResiliencyType() == Codec::ResiliencyType::kRtx &&
194-
!FindMatchingCodec(reference_codecs, offered_codecs, reference_codec)) {
195-
Codec rtx_codec = reference_codec;
196-
const Codec* associated_codec =
197-
GetAssociatedCodecForRtx(reference_codecs, rtx_codec);
198-
if (!associated_codec) {
199-
continue;
200-
}
201-
// Find a codec in the offered list that matches the reference codec.
202-
// Its payload type may be different than the reference codec.
203-
std::optional<Codec> matching_codec = FindMatchingCodec(
204-
reference_codecs, offered_codecs, *associated_codec);
205-
if (!matching_codec) {
206-
RTC_LOG(LS_WARNING)
207-
<< "Couldn't find matching " << associated_codec->name << " codec.";
208-
continue;
209-
}
210-
211-
rtx_codec.params[kCodecParamAssociatedPayloadType] =
212-
rtc::ToString(matching_codec->id);
213-
RTCErrorOr<webrtc::PayloadType> suggestion =
214-
pt_suggester.SuggestPayloadType(mid, rtx_codec);
215-
if (!suggestion.ok()) {
216-
return suggestion.MoveError();
217-
}
218-
rtx_codec.id = suggestion.value();
219-
offered_codecs.push_back(rtx_codec);
220-
} else if (reference_codec.GetResiliencyType() ==
221-
Codec::ResiliencyType::kRed &&
222-
!FindMatchingCodec(reference_codecs, offered_codecs,
223-
reference_codec)) {
224-
Codec red_codec = reference_codec;
225-
const Codec* associated_codec =
226-
GetAssociatedCodecForRed(reference_codecs, red_codec);
227-
if (associated_codec) {
228-
std::optional<Codec> matching_codec = FindMatchingCodec(
229-
reference_codecs, offered_codecs, *associated_codec);
230-
if (!matching_codec) {
231-
RTC_LOG(LS_WARNING) << "Couldn't find matching "
232-
<< associated_codec->name << " codec.";
233-
continue;
234-
}
235-
236-
red_codec.params[kCodecParamNotInNameValueFormat] =
237-
rtc::ToString(matching_codec->id) + "/" +
238-
rtc::ToString(matching_codec->id);
239-
}
240-
RTCErrorOr<webrtc::PayloadType> suggestion =
241-
pt_suggester.SuggestPayloadType(mid, red_codec);
242-
if (!suggestion.ok()) {
243-
return suggestion.MoveError();
244-
}
245-
red_codec.id = suggestion.value();
246-
offered_codecs.push_back(red_codec);
247-
}
248-
}
249-
offered_codecs.CheckConsistency();
250-
return RTCError::OK();
251-
}
252-
253-
// Adds all codecs from `reference_codecs` to `offered_codecs` that don't
254-
// already exist in `offered_codecs` and ensure the payload types don't
255-
// collide.
256-
// OLD VERSION - uses UsedPayloadTypes
257169
void MergeCodecs(const CodecList& reference_codecs,
258170
CodecList& offered_codecs,
259171
UsedPayloadTypes* used_pltypes) {
@@ -405,6 +317,43 @@ CodecList MatchCodecPreference(
405317
return filtered_codecs;
406318
}
407319

320+
// Compute the union of `codecs1` and `codecs2`.
321+
CodecList ComputeCodecsUnion(const CodecList codecs1, const CodecList codecs2) {
322+
CodecList all_codecs;
323+
UsedPayloadTypes used_payload_types;
324+
for (const Codec& codec : codecs1) {
325+
Codec codec_mutable = codec;
326+
used_payload_types.FindAndSetIdUsed(&codec_mutable);
327+
all_codecs.push_back(codec_mutable);
328+
}
329+
330+
// Use MergeCodecs to merge the second half of our list as it already checks
331+
// and fixes problems with duplicate payload types.
332+
MergeCodecs(codecs2, all_codecs, &used_payload_types);
333+
334+
return all_codecs;
335+
}
336+
337+
RTCError MergeCodecsFromDescription(
338+
const std::vector<const webrtc::ContentInfo*>& current_active_contents,
339+
CodecList& audio_codecs,
340+
CodecList& video_codecs,
341+
UsedPayloadTypes* used_pltypes) {
342+
for (const ContentInfo* content : current_active_contents) {
343+
RTCErrorOr<CodecList> checked_codec_list =
344+
CodecList::Create(content->media_description()->codecs());
345+
if (!checked_codec_list.ok()) {
346+
RTC_LOG(LS_ERROR) << checked_codec_list.error();
347+
}
348+
if (IsMediaContentOfType(content, webrtc::MediaType::AUDIO)) {
349+
MergeCodecs(checked_codec_list.value(), audio_codecs, used_pltypes);
350+
} else if (IsMediaContentOfType(content, webrtc::MediaType::VIDEO)) {
351+
MergeCodecs(checked_codec_list.value(), video_codecs, used_pltypes);
352+
}
353+
}
354+
return RTCError::OK();
355+
}
356+
408357
void NegotiatePacketization(const Codec& local_codec,
409358
const Codec& remote_codec,
410359
Codec* negotiated_codec) {
@@ -624,25 +573,8 @@ webrtc::RTCErrorOr<std::vector<Codec>> CodecVendor::GetNegotiatedCodecsForOffer(
624573
const MediaDescriptionOptions& media_description_options,
625574
const MediaSessionOptions& session_options,
626575
const webrtc::ContentInfo* current_content,
627-
PayloadTypeSuggester& pt_suggester) {
628-
CodecList codecs;
629-
std::string mid = media_description_options.mid;
630-
// If current content exists and is not being recycled, use its codecs.
631-
if (current_content && current_content->mid() == mid) {
632-
RTCErrorOr<CodecList> checked_codec_list =
633-
CodecList::Create(current_content->media_description()->codecs());
634-
if (!checked_codec_list.ok()) {
635-
return checked_codec_list.MoveError();
636-
}
637-
// Use MergeCodecs in order to handle PT clashes.
638-
MergeCodecs(checked_codec_list.value(), mid, codecs, pt_suggester);
639-
}
640-
// Add our codecs that are not in the current description.
641-
if (media_description_options.type == webrtc::MediaType::AUDIO) {
642-
MergeCodecs(all_audio_codecs(), mid, codecs, pt_suggester);
643-
} else {
644-
MergeCodecs(all_video_codecs(), mid, codecs, pt_suggester);
645-
}
576+
PayloadTypeSuggester& pt_suggester,
577+
const CodecList& codecs) {
646578
CodecList filtered_codecs;
647579
CodecList supported_codecs =
648580
media_description_options.type == webrtc::MediaType::AUDIO
@@ -743,7 +675,7 @@ webrtc::RTCErrorOr<std::vector<Codec>> CodecVendor::GetNegotiatedCodecsForOffer(
743675
}
744676
filtered_codecs = codecs_from_arg.MoveValue();
745677
}
746-
AssignCodecIdsAndLinkRed(&pt_suggester, mid,
678+
AssignCodecIdsAndLinkRed(&pt_suggester, media_description_options.mid,
747679
filtered_codecs.writable_codecs());
748680
return filtered_codecs.codecs();
749681
}
@@ -755,23 +687,8 @@ webrtc::RTCErrorOr<Codecs> CodecVendor::GetNegotiatedCodecsForAnswer(
755687
webrtc::RtpTransceiverDirection answer_rtd,
756688
const webrtc::ContentInfo* current_content,
757689
const std::vector<Codec> codecs_from_offer,
758-
PayloadTypeSuggester& pt_suggester) {
759-
CodecList codecs;
760-
std::string mid = media_description_options.mid;
761-
if (current_content && current_content->mid() == mid) {
762-
RTCErrorOr<CodecList> checked_codec_list =
763-
CodecList::Create(current_content->media_description()->codecs());
764-
if (!checked_codec_list.ok()) {
765-
return checked_codec_list.MoveError();
766-
}
767-
MergeCodecs(checked_codec_list.value(), mid, codecs, pt_suggester);
768-
}
769-
// Add all our supported codecs
770-
if (media_description_options.type == webrtc::MediaType::AUDIO) {
771-
MergeCodecs(all_audio_codecs(), mid, codecs, pt_suggester);
772-
} else {
773-
MergeCodecs(all_video_codecs(), mid, codecs, pt_suggester);
774-
}
690+
PayloadTypeSuggester& pt_suggester,
691+
const CodecList& codecs) {
775692
CodecList filtered_codecs;
776693
CodecList negotiated_codecs;
777694
if (media_description_options.codecs_to_include.empty()) {
@@ -805,8 +722,20 @@ webrtc::RTCErrorOr<Codecs> CodecVendor::GetNegotiatedCodecsForAnswer(
805722
}
806723
}
807724
}
808-
// Merge other_codecs into filtered_codecs, resolving PT conflicts.
809-
MergeCodecs(supported_codecs, mid, filtered_codecs, pt_suggester);
725+
// Add other supported codecs.
726+
CodecList other_codecs;
727+
for (const Codec& codec : supported_codecs) {
728+
if (FindMatchingCodec(supported_codecs, codecs, codec) &&
729+
!FindMatchingCodec(supported_codecs, filtered_codecs, codec)) {
730+
// We should use the local codec with local parameters and the codec
731+
// id would be correctly mapped in `NegotiateCodecs`.
732+
other_codecs.push_back(codec);
733+
}
734+
}
735+
736+
// Use ComputeCodecsUnion to avoid having duplicate payload IDs.
737+
// This is a no-op for audio until RTX is added.
738+
filtered_codecs = ComputeCodecsUnion(filtered_codecs, other_codecs);
810739
}
811740

812741
if (media_description_options.type == webrtc::MediaType::AUDIO &&
@@ -892,6 +821,107 @@ void CodecVendor::set_video_codecs(const CodecList& send_codecs,
892821
video_send_codecs_.set_codecs(send_codecs);
893822
video_recv_codecs_.set_codecs(recv_codecs);
894823
}
824+
// Getting codecs for an offer involves these steps:
825+
//
826+
// 1. Construct payload type -> codec mappings for current description.
827+
// 2. Add any reference codecs that weren't already present
828+
// 3. For each individual media description (m= section), filter codecs based
829+
// on the directional attribute (happens in another method).
830+
RTCError CodecVendor::GetCodecsForOffer(
831+
const std::vector<const webrtc::ContentInfo*>& current_active_contents,
832+
CodecList& audio_codecs,
833+
CodecList& video_codecs) const {
834+
// First - get all codecs from the current description if the media type
835+
// is used. Add them to `used_pltypes` so the payload type is not reused if a
836+
// new media type is added.
837+
UsedPayloadTypes used_pltypes;
838+
auto error = MergeCodecsFromDescription(current_active_contents, audio_codecs,
839+
video_codecs, &used_pltypes);
840+
if (!error.ok()) {
841+
return error;
842+
}
843+
// Add our codecs that are not in the current description.
844+
MergeCodecs(all_audio_codecs(), audio_codecs, &used_pltypes);
845+
MergeCodecs(all_video_codecs(), video_codecs, &used_pltypes);
846+
return RTCError::OK();
847+
}
848+
849+
// Getting codecs for an answer involves these steps:
850+
//
851+
// 1. Construct payload type -> codec mappings for current description.
852+
// 2. Add any codecs from the offer that weren't already present.
853+
// 3. Add any remaining codecs that weren't already present.
854+
// 4. For each individual media description (m= section), filter codecs based
855+
// on the directional attribute (happens in another method).
856+
RTCError CodecVendor::GetCodecsForAnswer(
857+
const std::vector<const webrtc::ContentInfo*>& current_active_contents,
858+
const webrtc::SessionDescription& remote_offer,
859+
CodecList& audio_codecs,
860+
CodecList& video_codecs) const {
861+
// First - get all codecs from the current description if the media type
862+
// is used. Add them to `used_pltypes` so the payload type is not reused if a
863+
// new media type is added.
864+
UsedPayloadTypes used_pltypes;
865+
RTCError error = MergeCodecsFromDescription(
866+
current_active_contents, audio_codecs, video_codecs, &used_pltypes);
867+
if (!error.ok()) {
868+
return error;
869+
}
870+
// Second - filter out codecs that we don't support at all and should ignore.
871+
CodecList filtered_offered_audio_codecs;
872+
CodecList filtered_offered_video_codecs;
873+
for (const ContentInfo& content : remote_offer.contents()) {
874+
RTCErrorOr<CodecList> offered_codecs =
875+
CodecList::Create(content.media_description()->codecs());
876+
if (!offered_codecs.ok()) {
877+
return offered_codecs.MoveError();
878+
}
879+
if (IsMediaContentOfType(&content, webrtc::MediaType::AUDIO)) {
880+
for (const Codec& offered_audio_codec : offered_codecs.value()) {
881+
if (!FindMatchingCodec(offered_codecs.value(),
882+
filtered_offered_audio_codecs,
883+
offered_audio_codec) &&
884+
FindMatchingCodec(offered_codecs.value(), all_audio_codecs(),
885+
offered_audio_codec)) {
886+
filtered_offered_audio_codecs.push_back(offered_audio_codec);
887+
}
888+
}
889+
} else if (IsMediaContentOfType(&content, webrtc::MediaType::VIDEO)) {
890+
std::vector<Codec> pending_rtx_codecs;
891+
for (const Codec& offered_video_codec : offered_codecs.value()) {
892+
if (!FindMatchingCodec(offered_codecs.value(),
893+
filtered_offered_video_codecs,
894+
offered_video_codec) &&
895+
FindMatchingCodec(offered_codecs.value(), all_video_codecs(),
896+
offered_video_codec)) {
897+
// Special case: If it's an RTX codec, and the APT points to
898+
// a codec that is not yet in the codec list, put it aside.
899+
if (offered_video_codec.GetResiliencyType() ==
900+
Codec::ResiliencyType::kRtx &&
901+
!GetAssociatedCodecForRtx(filtered_offered_video_codecs,
902+
offered_video_codec)) {
903+
pending_rtx_codecs.push_back(offered_video_codec);
904+
continue;
905+
}
906+
filtered_offered_video_codecs.push_back(offered_video_codec);
907+
}
908+
}
909+
// If the associated codec showed up later in the codec list,
910+
// append the corresponding RTX codec.
911+
for (const Codec& codec : pending_rtx_codecs) {
912+
if (GetAssociatedCodecForRtx(filtered_offered_video_codecs, codec)) {
913+
filtered_offered_video_codecs.push_back(codec);
914+
}
915+
}
916+
}
917+
}
918+
919+
// Add codecs that are not in the current description but were in
920+
// `remote_offer`.
921+
MergeCodecs(filtered_offered_audio_codecs, audio_codecs, &used_pltypes);
922+
MergeCodecs(filtered_offered_video_codecs, video_codecs, &used_pltypes);
923+
return RTCError::OK();
924+
}
895925

896926
CodecList CodecVendor::GetVideoCodecsForOffer(
897927
const RtpTransceiverDirection& direction) const {
@@ -964,19 +994,9 @@ CodecList CodecVendor::GetAudioCodecsForAnswer(
964994
}
965995

966996
CodecList CodecVendor::all_video_codecs() const {
967-
CodecList all_codecs;
968-
UsedPayloadTypes used_payload_types;
969-
for (const Codec& codec : video_recv_codecs_.codecs()) {
970-
Codec codec_mutable = codec;
971-
used_payload_types.FindAndSetIdUsed(&codec_mutable);
972-
all_codecs.push_back(codec_mutable);
973-
}
974-
975-
// Use MergeCodecs to merge the second half of our list as it already checks
976-
// and fixes problems with duplicate payload types.
977-
MergeCodecs(video_send_codecs_.codecs(), all_codecs, &used_payload_types);
978-
979-
return all_codecs;
997+
// Use ComputeCodecsUnion to avoid having duplicate payload IDs
998+
return ComputeCodecsUnion(video_recv_codecs_.codecs(),
999+
video_send_codecs_.codecs());
9801000
}
9811001

9821002
CodecList CodecVendor::all_audio_codecs() const {

pc/codec_vendor.h

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,22 @@ class CodecVendor {
4747
const webrtc::FieldTrialsView& trials);
4848

4949
public:
50+
webrtc::RTCError GetCodecsForOffer(
51+
const std::vector<const webrtc::ContentInfo*>& current_active_contents,
52+
CodecList& audio_codecs,
53+
CodecList& video_codecs) const;
54+
webrtc::RTCError GetCodecsForAnswer(
55+
const std::vector<const webrtc::ContentInfo*>& current_active_contents,
56+
const webrtc::SessionDescription& remote_offer,
57+
CodecList& audio_codecs,
58+
CodecList& video_codecs) const;
59+
5060
webrtc::RTCErrorOr<std::vector<Codec>> GetNegotiatedCodecsForOffer(
5161
const MediaDescriptionOptions& media_description_options,
5262
const MediaSessionOptions& session_options,
5363
const webrtc::ContentInfo* current_content,
54-
webrtc::PayloadTypeSuggester& pt_suggester);
64+
webrtc::PayloadTypeSuggester& pt_suggester,
65+
const CodecList& codecs);
5566

5667
webrtc::RTCErrorOr<Codecs> GetNegotiatedCodecsForAnswer(
5768
const MediaDescriptionOptions& media_description_options,
@@ -60,7 +71,8 @@ class CodecVendor {
6071
webrtc::RtpTransceiverDirection answer_rtd,
6172
const webrtc::ContentInfo* current_content,
6273
std::vector<Codec> codecs_from_offer,
63-
webrtc::PayloadTypeSuggester& pt_suggester);
74+
webrtc::PayloadTypeSuggester& pt_suggester,
75+
const CodecList& codecs);
6476

6577
// Functions exposed for testing
6678
void set_audio_codecs(const CodecList& send_codecs,

pc/jsep_transport_controller_unittest.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include <utility>
1919
#include <vector>
2020

21-
#include "api/candidate.h"
2221
#include "api/crypto/crypto_options.h"
2322
#include "api/dtls_transport_interface.h"
2423
#include "api/environment/environment.h"

0 commit comments

Comments
 (0)