2016-11-15 06:30:54 -08:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
|
|
|
|
|
*
|
|
|
|
|
* Use of this source code is governed by a BSD-style license
|
|
|
|
|
* that can be found in the LICENSE file in the root of the source
|
|
|
|
|
* tree. An additional intellectual property rights grant can be found
|
|
|
|
|
* in the file PATENTS. All contributing project authors may
|
|
|
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "webrtc/media/engine/videoencodersoftwarefallbackwrapper.h"
|
|
|
|
|
|
2017-08-23 14:19:50 -07:00
|
|
|
#include "webrtc/media/base/h264_profile_level_id.h"
|
Reland of Stop using hardcoded payload types for video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2513633002/ )
Reason for revert:
The WebRtcBrowserTest.NegotiateUnsupportedVideoCodec test has been fixed in Chromium with the following change:
function removeVideoCodec(offerSdp) {
- offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n',
- 'a=rtpmap:100 XVP8/90000\r\n');
+ offerSdp = offerSdp.replace(/a=rtpmap:(\d+)\ VP8\/90000\r\n/,
+ 'a=rtpmap:$1 XVP8/90000\r\n');
return offerSdp;
}
Original issue's description:
> Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ )
>
> Reason for revert:
> Breaks chromium.fyi test:
> WebRtcBrowserTest.NegotiateUnsupportedVideoCodec
>
> Original issue's description:
> > Stop using hardcoded payload types for video codecs
> >
> > This CL stops using hardcoded payload types for different video codecs
> > and will dynamically assign them payload types incrementally from 96 to
> > 127 instead.
> >
> > This CL:
> > * Replaces 'std::vector<VideoCodec> DefaultVideoCodecList()' in
> > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for
> > internally supported software codecs instead. The purpose is to
> > streamline the payload type assignment in webrtcvideoengine2.cc which
> > will now have two encoder factories of the same
> > WebRtcVideoEncoderFactory type; one internal and one external.
> > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec
> > instead.
> > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and
> > moves the create function to the internal encoder factory instead.
> > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an
> > interface without any static functions.
> > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies
> > the internal and external codecs and assigns them payload types
> > incrementally from 96 to 127.
> > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about
> > what payload types will be used.
> >
> > BUG=webrtc:6677,webrtc:6705
> > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org
> >
> > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b
> > Cr-Commit-Position: refs/heads/master@{#15135}
>
> TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:6677,webrtc:6705
>
> Committed: https://crrev.com/eacbaea920797ff751ca83050d140821f5055591
> Cr-Commit-Position: refs/heads/master@{#15140}
TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6677,webrtc:6705
Review-Url: https://codereview.webrtc.org/2511933002
Cr-Commit-Position: refs/heads/master@{#15148}
2016-11-18 01:34:11 -08:00
|
|
|
#include "webrtc/media/engine/internalencoderfactory.h"
|
2016-11-15 06:30:54 -08:00
|
|
|
#include "webrtc/modules/video_coding/include/video_error_codes.h"
|
2017-08-16 00:53:59 -07:00
|
|
|
#include "webrtc/rtc_base/checks.h"
|
2017-07-06 19:44:34 +02:00
|
|
|
#include "webrtc/rtc_base/logging.h"
|
2017-08-16 00:53:59 -07:00
|
|
|
#include "webrtc/rtc_base/timeutils.h"
|
|
|
|
|
#include "webrtc/system_wrappers/include/field_trial.h"
|
2016-11-15 06:30:54 -08:00
|
|
|
|
|
|
|
|
namespace webrtc {
|
2017-08-16 00:53:59 -07:00
|
|
|
namespace {
|
|
|
|
|
const char kVp8ForceFallbackEncoderFieldTrial[] =
|
|
|
|
|
"WebRTC-VP8-Forced-Fallback-Encoder";
|
|
|
|
|
|
|
|
|
|
bool EnableForcedFallback(const cricket::VideoCodec& codec) {
|
|
|
|
|
if (!webrtc::field_trial::IsEnabled(kVp8ForceFallbackEncoderFieldTrial))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
return (PayloadNameToCodecType(codec.name).value_or(kVideoCodecUnknown) ==
|
|
|
|
|
kVideoCodecVP8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool IsForcedFallbackPossible(const VideoCodec& codec_settings) {
|
|
|
|
|
return codec_settings.codecType == kVideoCodecVP8 &&
|
|
|
|
|
codec_settings.numberOfSimulcastStreams <= 1 &&
|
|
|
|
|
codec_settings.VP8().numberOfTemporalLayers == 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void GetForcedFallbackParamsFromFieldTrialGroup(uint32_t* param_low_kbps,
|
|
|
|
|
uint32_t* param_high_kbps,
|
|
|
|
|
int64_t* param_min_low_ms) {
|
|
|
|
|
RTC_DCHECK(param_low_kbps);
|
|
|
|
|
RTC_DCHECK(param_high_kbps);
|
|
|
|
|
RTC_DCHECK(param_min_low_ms);
|
|
|
|
|
std::string group =
|
|
|
|
|
webrtc::field_trial::FindFullName(kVp8ForceFallbackEncoderFieldTrial);
|
|
|
|
|
if (group.empty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
int low_kbps;
|
|
|
|
|
int high_kbps;
|
|
|
|
|
int min_low_ms;
|
2017-08-17 08:58:54 -07:00
|
|
|
int min_pixels;
|
|
|
|
|
if (sscanf(group.c_str(), "Enabled-%d,%d,%d,%d", &low_kbps, &high_kbps,
|
|
|
|
|
&min_low_ms, &min_pixels) != 4) {
|
2017-08-16 00:53:59 -07:00
|
|
|
LOG(LS_WARNING) << "Invalid number of forced fallback parameters provided.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
2017-08-17 08:58:54 -07:00
|
|
|
if (min_low_ms <= 0 || min_pixels <= 0 || low_kbps <= 0 ||
|
|
|
|
|
high_kbps <= low_kbps) {
|
2017-08-16 00:53:59 -07:00
|
|
|
LOG(LS_WARNING) << "Invalid forced fallback parameter value provided.";
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
*param_low_kbps = low_kbps;
|
|
|
|
|
*param_high_kbps = high_kbps;
|
|
|
|
|
*param_min_low_ms = min_low_ms;
|
|
|
|
|
}
|
|
|
|
|
} // namespace
|
2016-11-15 06:30:54 -08:00
|
|
|
|
|
|
|
|
VideoEncoderSoftwareFallbackWrapper::VideoEncoderSoftwareFallbackWrapper(
|
Reland of Stop using hardcoded payload types for video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2513633002/ )
Reason for revert:
The WebRtcBrowserTest.NegotiateUnsupportedVideoCodec test has been fixed in Chromium with the following change:
function removeVideoCodec(offerSdp) {
- offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n',
- 'a=rtpmap:100 XVP8/90000\r\n');
+ offerSdp = offerSdp.replace(/a=rtpmap:(\d+)\ VP8\/90000\r\n/,
+ 'a=rtpmap:$1 XVP8/90000\r\n');
return offerSdp;
}
Original issue's description:
> Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ )
>
> Reason for revert:
> Breaks chromium.fyi test:
> WebRtcBrowserTest.NegotiateUnsupportedVideoCodec
>
> Original issue's description:
> > Stop using hardcoded payload types for video codecs
> >
> > This CL stops using hardcoded payload types for different video codecs
> > and will dynamically assign them payload types incrementally from 96 to
> > 127 instead.
> >
> > This CL:
> > * Replaces 'std::vector<VideoCodec> DefaultVideoCodecList()' in
> > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for
> > internally supported software codecs instead. The purpose is to
> > streamline the payload type assignment in webrtcvideoengine2.cc which
> > will now have two encoder factories of the same
> > WebRtcVideoEncoderFactory type; one internal and one external.
> > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec
> > instead.
> > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and
> > moves the create function to the internal encoder factory instead.
> > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an
> > interface without any static functions.
> > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies
> > the internal and external codecs and assigns them payload types
> > incrementally from 96 to 127.
> > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about
> > what payload types will be used.
> >
> > BUG=webrtc:6677,webrtc:6705
> > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org
> >
> > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b
> > Cr-Commit-Position: refs/heads/master@{#15135}
>
> TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:6677,webrtc:6705
>
> Committed: https://crrev.com/eacbaea920797ff751ca83050d140821f5055591
> Cr-Commit-Position: refs/heads/master@{#15140}
TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6677,webrtc:6705
Review-Url: https://codereview.webrtc.org/2511933002
Cr-Commit-Position: refs/heads/master@{#15148}
2016-11-18 01:34:11 -08:00
|
|
|
const cricket::VideoCodec& codec,
|
2016-11-15 06:30:54 -08:00
|
|
|
webrtc::VideoEncoder* encoder)
|
2016-11-16 16:41:30 +01:00
|
|
|
: number_of_cores_(0),
|
|
|
|
|
max_payload_size_(0),
|
|
|
|
|
rates_set_(false),
|
|
|
|
|
framerate_(0),
|
2016-11-15 06:30:54 -08:00
|
|
|
channel_parameters_set_(false),
|
2016-11-16 16:41:30 +01:00
|
|
|
packet_loss_(0),
|
|
|
|
|
rtt_(0),
|
Reland of Stop using hardcoded payload types for video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2513633002/ )
Reason for revert:
The WebRtcBrowserTest.NegotiateUnsupportedVideoCodec test has been fixed in Chromium with the following change:
function removeVideoCodec(offerSdp) {
- offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n',
- 'a=rtpmap:100 XVP8/90000\r\n');
+ offerSdp = offerSdp.replace(/a=rtpmap:(\d+)\ VP8\/90000\r\n/,
+ 'a=rtpmap:$1 XVP8/90000\r\n');
return offerSdp;
}
Original issue's description:
> Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ )
>
> Reason for revert:
> Breaks chromium.fyi test:
> WebRtcBrowserTest.NegotiateUnsupportedVideoCodec
>
> Original issue's description:
> > Stop using hardcoded payload types for video codecs
> >
> > This CL stops using hardcoded payload types for different video codecs
> > and will dynamically assign them payload types incrementally from 96 to
> > 127 instead.
> >
> > This CL:
> > * Replaces 'std::vector<VideoCodec> DefaultVideoCodecList()' in
> > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for
> > internally supported software codecs instead. The purpose is to
> > streamline the payload type assignment in webrtcvideoengine2.cc which
> > will now have two encoder factories of the same
> > WebRtcVideoEncoderFactory type; one internal and one external.
> > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec
> > instead.
> > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and
> > moves the create function to the internal encoder factory instead.
> > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an
> > interface without any static functions.
> > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies
> > the internal and external codecs and assigns them payload types
> > incrementally from 96 to 127.
> > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about
> > what payload types will be used.
> >
> > BUG=webrtc:6677,webrtc:6705
> > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org
> >
> > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b
> > Cr-Commit-Position: refs/heads/master@{#15135}
>
> TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:6677,webrtc:6705
>
> Committed: https://crrev.com/eacbaea920797ff751ca83050d140821f5055591
> Cr-Commit-Position: refs/heads/master@{#15140}
TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6677,webrtc:6705
Review-Url: https://codereview.webrtc.org/2511933002
Cr-Commit-Position: refs/heads/master@{#15148}
2016-11-18 01:34:11 -08:00
|
|
|
codec_(codec),
|
2016-11-15 06:30:54 -08:00
|
|
|
encoder_(encoder),
|
2017-08-16 00:53:59 -07:00
|
|
|
callback_(nullptr),
|
|
|
|
|
forced_fallback_possible_(EnableForcedFallback(codec)) {
|
|
|
|
|
if (forced_fallback_possible_) {
|
|
|
|
|
GetForcedFallbackParamsFromFieldTrialGroup(&forced_fallback_.low_kbps,
|
|
|
|
|
&forced_fallback_.high_kbps,
|
|
|
|
|
&forced_fallback_.min_low_ms);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-15 06:30:54 -08:00
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::InitFallbackEncoder() {
|
2017-08-23 14:19:50 -07:00
|
|
|
MaybeModifyCodecForFallback();
|
Reland of Stop using hardcoded payload types for video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2513633002/ )
Reason for revert:
The WebRtcBrowserTest.NegotiateUnsupportedVideoCodec test has been fixed in Chromium with the following change:
function removeVideoCodec(offerSdp) {
- offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n',
- 'a=rtpmap:100 XVP8/90000\r\n');
+ offerSdp = offerSdp.replace(/a=rtpmap:(\d+)\ VP8\/90000\r\n/,
+ 'a=rtpmap:$1 XVP8/90000\r\n');
return offerSdp;
}
Original issue's description:
> Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ )
>
> Reason for revert:
> Breaks chromium.fyi test:
> WebRtcBrowserTest.NegotiateUnsupportedVideoCodec
>
> Original issue's description:
> > Stop using hardcoded payload types for video codecs
> >
> > This CL stops using hardcoded payload types for different video codecs
> > and will dynamically assign them payload types incrementally from 96 to
> > 127 instead.
> >
> > This CL:
> > * Replaces 'std::vector<VideoCodec> DefaultVideoCodecList()' in
> > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for
> > internally supported software codecs instead. The purpose is to
> > streamline the payload type assignment in webrtcvideoengine2.cc which
> > will now have two encoder factories of the same
> > WebRtcVideoEncoderFactory type; one internal and one external.
> > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec
> > instead.
> > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and
> > moves the create function to the internal encoder factory instead.
> > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an
> > interface without any static functions.
> > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies
> > the internal and external codecs and assigns them payload types
> > incrementally from 96 to 127.
> > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about
> > what payload types will be used.
> >
> > BUG=webrtc:6677,webrtc:6705
> > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org
> >
> > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b
> > Cr-Commit-Position: refs/heads/master@{#15135}
>
> TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:6677,webrtc:6705
>
> Committed: https://crrev.com/eacbaea920797ff751ca83050d140821f5055591
> Cr-Commit-Position: refs/heads/master@{#15140}
TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6677,webrtc:6705
Review-Url: https://codereview.webrtc.org/2511933002
Cr-Commit-Position: refs/heads/master@{#15148}
2016-11-18 01:34:11 -08:00
|
|
|
cricket::InternalEncoderFactory internal_factory;
|
|
|
|
|
if (!FindMatchingCodec(internal_factory.supported_codecs(), codec_)) {
|
2016-11-15 06:30:54 -08:00
|
|
|
LOG(LS_WARNING)
|
|
|
|
|
<< "Encoder requesting fallback to codec not supported in software.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
Reland of Stop using hardcoded payload types for video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2513633002/ )
Reason for revert:
The WebRtcBrowserTest.NegotiateUnsupportedVideoCodec test has been fixed in Chromium with the following change:
function removeVideoCodec(offerSdp) {
- offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n',
- 'a=rtpmap:100 XVP8/90000\r\n');
+ offerSdp = offerSdp.replace(/a=rtpmap:(\d+)\ VP8\/90000\r\n/,
+ 'a=rtpmap:$1 XVP8/90000\r\n');
return offerSdp;
}
Original issue's description:
> Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ )
>
> Reason for revert:
> Breaks chromium.fyi test:
> WebRtcBrowserTest.NegotiateUnsupportedVideoCodec
>
> Original issue's description:
> > Stop using hardcoded payload types for video codecs
> >
> > This CL stops using hardcoded payload types for different video codecs
> > and will dynamically assign them payload types incrementally from 96 to
> > 127 instead.
> >
> > This CL:
> > * Replaces 'std::vector<VideoCodec> DefaultVideoCodecList()' in
> > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for
> > internally supported software codecs instead. The purpose is to
> > streamline the payload type assignment in webrtcvideoengine2.cc which
> > will now have two encoder factories of the same
> > WebRtcVideoEncoderFactory type; one internal and one external.
> > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec
> > instead.
> > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and
> > moves the create function to the internal encoder factory instead.
> > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an
> > interface without any static functions.
> > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies
> > the internal and external codecs and assigns them payload types
> > incrementally from 96 to 127.
> > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about
> > what payload types will be used.
> >
> > BUG=webrtc:6677,webrtc:6705
> > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org
> >
> > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b
> > Cr-Commit-Position: refs/heads/master@{#15135}
>
> TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:6677,webrtc:6705
>
> Committed: https://crrev.com/eacbaea920797ff751ca83050d140821f5055591
> Cr-Commit-Position: refs/heads/master@{#15140}
TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6677,webrtc:6705
Review-Url: https://codereview.webrtc.org/2511933002
Cr-Commit-Position: refs/heads/master@{#15148}
2016-11-18 01:34:11 -08:00
|
|
|
fallback_encoder_.reset(internal_factory.CreateVideoEncoder(codec_));
|
2016-11-15 06:30:54 -08:00
|
|
|
if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_,
|
|
|
|
|
max_payload_size_) !=
|
|
|
|
|
WEBRTC_VIDEO_CODEC_OK) {
|
|
|
|
|
LOG(LS_ERROR) << "Failed to initialize software-encoder fallback.";
|
|
|
|
|
fallback_encoder_->Release();
|
|
|
|
|
fallback_encoder_.reset();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// Replay callback, rates, and channel parameters.
|
|
|
|
|
if (callback_)
|
|
|
|
|
fallback_encoder_->RegisterEncodeCompleteCallback(callback_);
|
|
|
|
|
if (rates_set_)
|
2016-11-16 16:41:30 +01:00
|
|
|
fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate_);
|
2016-11-15 06:30:54 -08:00
|
|
|
if (channel_parameters_set_)
|
|
|
|
|
fallback_encoder_->SetChannelParameters(packet_loss_, rtt_);
|
|
|
|
|
|
|
|
|
|
fallback_implementation_name_ =
|
|
|
|
|
std::string(fallback_encoder_->ImplementationName()) +
|
|
|
|
|
" (fallback from: " + encoder_->ImplementationName() + ")";
|
|
|
|
|
// Since we're switching to the fallback encoder, Release the real encoder. It
|
|
|
|
|
// may be re-initialized via InitEncode later, and it will continue to get
|
|
|
|
|
// Set calls for rates and channel parameters in the meantime.
|
|
|
|
|
encoder_->Release();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t VideoEncoderSoftwareFallbackWrapper::InitEncode(
|
|
|
|
|
const VideoCodec* codec_settings,
|
|
|
|
|
int32_t number_of_cores,
|
|
|
|
|
size_t max_payload_size) {
|
|
|
|
|
// Store settings, in case we need to dynamically switch to the fallback
|
|
|
|
|
// encoder after a failed Encode call.
|
|
|
|
|
codec_settings_ = *codec_settings;
|
|
|
|
|
number_of_cores_ = number_of_cores;
|
|
|
|
|
max_payload_size_ = max_payload_size;
|
|
|
|
|
// Clear stored rate/channel parameters.
|
|
|
|
|
rates_set_ = false;
|
|
|
|
|
channel_parameters_set_ = false;
|
2017-08-16 00:53:59 -07:00
|
|
|
ValidateSettingsForForcedFallback();
|
|
|
|
|
|
|
|
|
|
// Try to reinit forced software codec if it is in use.
|
|
|
|
|
if (TryReInitForcedFallbackEncoder()) {
|
|
|
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
|
|
|
}
|
|
|
|
|
forced_fallback_.Reset();
|
2016-11-15 06:30:54 -08:00
|
|
|
|
|
|
|
|
int32_t ret =
|
|
|
|
|
encoder_->InitEncode(codec_settings, number_of_cores, max_payload_size);
|
Reland of Stop using hardcoded payload types for video codecs (patchset #1 id:1 of https://codereview.webrtc.org/2513633002/ )
Reason for revert:
The WebRtcBrowserTest.NegotiateUnsupportedVideoCodec test has been fixed in Chromium with the following change:
function removeVideoCodec(offerSdp) {
- offerSdp = offerSdp.replace('a=rtpmap:100 VP8/90000\r\n',
- 'a=rtpmap:100 XVP8/90000\r\n');
+ offerSdp = offerSdp.replace(/a=rtpmap:(\d+)\ VP8\/90000\r\n/,
+ 'a=rtpmap:$1 XVP8/90000\r\n');
return offerSdp;
}
Original issue's description:
> Revert of Stop using hardcoded payload types for video codecs (patchset #6 id:210001 of https://codereview.webrtc.org/2493133002/ )
>
> Reason for revert:
> Breaks chromium.fyi test:
> WebRtcBrowserTest.NegotiateUnsupportedVideoCodec
>
> Original issue's description:
> > Stop using hardcoded payload types for video codecs
> >
> > This CL stops using hardcoded payload types for different video codecs
> > and will dynamically assign them payload types incrementally from 96 to
> > 127 instead.
> >
> > This CL:
> > * Replaces 'std::vector<VideoCodec> DefaultVideoCodecList()' in
> > webrtcvideoengine2.cc with an explicit WebRtcVideoEncoderFactory for
> > internally supported software codecs instead. The purpose is to
> > streamline the payload type assignment in webrtcvideoengine2.cc which
> > will now have two encoder factories of the same
> > WebRtcVideoEncoderFactory type; one internal and one external.
> > * Removes webrtc::VideoEncoder::EncoderType and use cricket::VideoCodec
> > instead.
> > * Removes 'static VideoEncoder* Create(EncoderType codec_type)' and
> > moves the create function to the internal encoder factory instead.
> > * Removes video_encoder.cc. webrtc::VideoEncoder is now just an
> > interface without any static functions.
> > * The function GetSupportedCodecs in webrtcvideoengine2.cc unifies
> > the internal and external codecs and assigns them payload types
> > incrementally from 96 to 127.
> > * Updates webrtcvideoengine2_unittest.cc and removes assumptions about
> > what payload types will be used.
> >
> > BUG=webrtc:6677,webrtc:6705
> > R=hta@webrtc.org, ossu@webrtc.org, stefan@webrtc.org
> >
> > Committed: https://crrev.com/42043b95872b51321f508bf255d804ce3dff366b
> > Cr-Commit-Position: refs/heads/master@{#15135}
>
> TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
> # Skipping CQ checks because original CL landed less than 1 days ago.
> NOPRESUBMIT=true
> NOTREECHECKS=true
> NOTRY=true
> BUG=webrtc:6677,webrtc:6705
>
> Committed: https://crrev.com/eacbaea920797ff751ca83050d140821f5055591
> Cr-Commit-Position: refs/heads/master@{#15140}
TBR=hta@webrtc.org,stefan@webrtc.org,ossu@webrtc.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=webrtc:6677,webrtc:6705
Review-Url: https://codereview.webrtc.org/2511933002
Cr-Commit-Position: refs/heads/master@{#15148}
2016-11-18 01:34:11 -08:00
|
|
|
if (ret == WEBRTC_VIDEO_CODEC_OK || codec_.name.empty()) {
|
2016-11-15 06:30:54 -08:00
|
|
|
if (fallback_encoder_)
|
|
|
|
|
fallback_encoder_->Release();
|
|
|
|
|
fallback_encoder_.reset();
|
|
|
|
|
if (callback_)
|
|
|
|
|
encoder_->RegisterEncodeCompleteCallback(callback_);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
// Try to instantiate software codec.
|
|
|
|
|
if (InitFallbackEncoder()) {
|
|
|
|
|
return WEBRTC_VIDEO_CODEC_OK;
|
|
|
|
|
}
|
|
|
|
|
// Software encoder failed, use original return code.
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t VideoEncoderSoftwareFallbackWrapper::RegisterEncodeCompleteCallback(
|
|
|
|
|
EncodedImageCallback* callback) {
|
|
|
|
|
callback_ = callback;
|
|
|
|
|
int32_t ret = encoder_->RegisterEncodeCompleteCallback(callback);
|
|
|
|
|
if (fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->RegisterEncodeCompleteCallback(callback);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t VideoEncoderSoftwareFallbackWrapper::Release() {
|
|
|
|
|
// If the fallback_encoder_ is non-null, it means it was created via
|
|
|
|
|
// InitFallbackEncoder which has Release()d encoder_, so we should only ever
|
|
|
|
|
// need to Release() whichever one is active.
|
|
|
|
|
if (fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->Release();
|
|
|
|
|
return encoder_->Release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t VideoEncoderSoftwareFallbackWrapper::Encode(
|
|
|
|
|
const VideoFrame& frame,
|
|
|
|
|
const CodecSpecificInfo* codec_specific_info,
|
|
|
|
|
const std::vector<FrameType>* frame_types) {
|
2017-08-16 00:53:59 -07:00
|
|
|
if (TryReleaseForcedFallbackEncoder()) {
|
|
|
|
|
// Frame may have been converted from kNative to kI420 during fallback.
|
|
|
|
|
if (encoder_->SupportsNativeHandle() &&
|
|
|
|
|
frame.video_frame_buffer()->type() != VideoFrameBuffer::Type::kNative) {
|
|
|
|
|
LOG(LS_WARNING) << "Encoder supports native frames, dropping one frame "
|
|
|
|
|
<< "to avoid possible reconfig due to format change.";
|
|
|
|
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-15 06:30:54 -08:00
|
|
|
if (fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->Encode(frame, codec_specific_info, frame_types);
|
|
|
|
|
int32_t ret = encoder_->Encode(frame, codec_specific_info, frame_types);
|
|
|
|
|
// If requested, try a software fallback.
|
2017-08-16 00:53:59 -07:00
|
|
|
bool fallback_requested =
|
|
|
|
|
(ret == WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE) ||
|
|
|
|
|
(ret == WEBRTC_VIDEO_CODEC_OK && RequestForcedFallback());
|
|
|
|
|
if (fallback_requested && InitFallbackEncoder()) {
|
|
|
|
|
// Fallback was successful.
|
|
|
|
|
if (ret == WEBRTC_VIDEO_CODEC_FALLBACK_SOFTWARE)
|
|
|
|
|
forced_fallback_.Reset(); // Not a forced fallback.
|
2017-06-14 11:28:08 +02:00
|
|
|
if (frame.video_frame_buffer()->type() == VideoFrameBuffer::Type::kNative &&
|
2016-11-15 06:30:54 -08:00
|
|
|
!fallback_encoder_->SupportsNativeHandle()) {
|
|
|
|
|
LOG(LS_WARNING) << "Fallback encoder doesn't support native frames, "
|
|
|
|
|
<< "dropping one frame.";
|
|
|
|
|
return WEBRTC_VIDEO_CODEC_ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 00:53:59 -07:00
|
|
|
// Start using the fallback with this frame.
|
2016-11-15 06:30:54 -08:00
|
|
|
return fallback_encoder_->Encode(frame, codec_specific_info, frame_types);
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t VideoEncoderSoftwareFallbackWrapper::SetChannelParameters(
|
|
|
|
|
uint32_t packet_loss,
|
|
|
|
|
int64_t rtt) {
|
|
|
|
|
channel_parameters_set_ = true;
|
|
|
|
|
packet_loss_ = packet_loss;
|
|
|
|
|
rtt_ = rtt;
|
|
|
|
|
int32_t ret = encoder_->SetChannelParameters(packet_loss, rtt);
|
|
|
|
|
if (fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->SetChannelParameters(packet_loss, rtt);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-16 16:41:30 +01:00
|
|
|
int32_t VideoEncoderSoftwareFallbackWrapper::SetRateAllocation(
|
|
|
|
|
const BitrateAllocation& bitrate_allocation,
|
|
|
|
|
uint32_t framerate) {
|
2016-11-15 06:30:54 -08:00
|
|
|
rates_set_ = true;
|
2016-11-16 16:41:30 +01:00
|
|
|
bitrate_allocation_ = bitrate_allocation;
|
2016-11-15 06:30:54 -08:00
|
|
|
framerate_ = framerate;
|
2016-11-16 16:41:30 +01:00
|
|
|
int32_t ret = encoder_->SetRateAllocation(bitrate_allocation_, framerate);
|
2016-11-15 06:30:54 -08:00
|
|
|
if (fallback_encoder_)
|
2016-11-16 16:41:30 +01:00
|
|
|
return fallback_encoder_->SetRateAllocation(bitrate_allocation_, framerate);
|
2016-11-15 06:30:54 -08:00
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::SupportsNativeHandle() const {
|
|
|
|
|
if (fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->SupportsNativeHandle();
|
|
|
|
|
return encoder_->SupportsNativeHandle();
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-29 01:44:11 -08:00
|
|
|
VideoEncoder::ScalingSettings
|
|
|
|
|
VideoEncoderSoftwareFallbackWrapper::GetScalingSettings() const {
|
2017-08-17 08:58:54 -07:00
|
|
|
if (forced_fallback_possible_ && fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->GetScalingSettings();
|
2016-11-29 01:44:11 -08:00
|
|
|
return encoder_->GetScalingSettings();
|
|
|
|
|
}
|
|
|
|
|
|
2017-01-26 00:36:31 -08:00
|
|
|
const char *VideoEncoderSoftwareFallbackWrapper::ImplementationName() const {
|
|
|
|
|
if (fallback_encoder_)
|
|
|
|
|
return fallback_encoder_->ImplementationName();
|
|
|
|
|
return encoder_->ImplementationName();
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-16 00:53:59 -07:00
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::IsForcedFallbackActive() const {
|
|
|
|
|
return (forced_fallback_possible_ && fallback_encoder_ &&
|
|
|
|
|
forced_fallback_.start_ms);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::RequestForcedFallback() {
|
|
|
|
|
if (!forced_fallback_possible_ || fallback_encoder_ || !rates_set_)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// No fallback encoder.
|
|
|
|
|
return forced_fallback_.ShouldStart(bitrate_allocation_.get_sum_kbps(),
|
|
|
|
|
codec_settings_);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::TryReleaseForcedFallbackEncoder() {
|
|
|
|
|
if (!IsForcedFallbackActive())
|
|
|
|
|
return false;
|
|
|
|
|
|
2017-08-17 08:58:54 -07:00
|
|
|
if (!forced_fallback_.ShouldStop(bitrate_allocation_.get_sum_kbps(),
|
|
|
|
|
codec_settings_)) {
|
2017-08-16 00:53:59 -07:00
|
|
|
return false;
|
2017-08-17 08:58:54 -07:00
|
|
|
}
|
2017-08-16 00:53:59 -07:00
|
|
|
|
|
|
|
|
// Release the forced fallback encoder.
|
|
|
|
|
if (encoder_->InitEncode(&codec_settings_, number_of_cores_,
|
|
|
|
|
max_payload_size_) == WEBRTC_VIDEO_CODEC_OK) {
|
|
|
|
|
LOG(LS_INFO) << "Stop forced SW encoder fallback, max bitrate exceeded.";
|
|
|
|
|
fallback_encoder_->Release();
|
|
|
|
|
fallback_encoder_.reset();
|
|
|
|
|
forced_fallback_.Reset();
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::TryReInitForcedFallbackEncoder() {
|
|
|
|
|
if (!IsForcedFallbackActive())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Encoder reconfigured.
|
|
|
|
|
if (!forced_fallback_.IsValid(codec_settings_)) {
|
|
|
|
|
LOG(LS_INFO) << "Stop forced SW encoder fallback, max pixels exceeded.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// Settings valid, reinitialize the forced fallback encoder.
|
|
|
|
|
if (fallback_encoder_->InitEncode(&codec_settings_, number_of_cores_,
|
|
|
|
|
max_payload_size_) !=
|
|
|
|
|
WEBRTC_VIDEO_CODEC_OK) {
|
|
|
|
|
LOG(LS_ERROR) << "Failed to init forced SW encoder fallback.";
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void VideoEncoderSoftwareFallbackWrapper::ValidateSettingsForForcedFallback() {
|
|
|
|
|
if (!forced_fallback_possible_)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (!IsForcedFallbackPossible(codec_settings_)) {
|
|
|
|
|
if (IsForcedFallbackActive()) {
|
|
|
|
|
fallback_encoder_->Release();
|
|
|
|
|
fallback_encoder_.reset();
|
|
|
|
|
}
|
|
|
|
|
LOG(LS_INFO) << "Disable forced_fallback_possible_ due to settings.";
|
|
|
|
|
forced_fallback_possible_ = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::ForcedFallbackParams::ShouldStart(
|
|
|
|
|
uint32_t bitrate_kbps,
|
|
|
|
|
const VideoCodec& codec) {
|
|
|
|
|
if (bitrate_kbps > low_kbps || !IsValid(codec)) {
|
|
|
|
|
start_ms.reset();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Has bitrate been below |low_kbps| for long enough duration.
|
|
|
|
|
int64_t now_ms = rtc::TimeMillis();
|
|
|
|
|
if (!start_ms)
|
|
|
|
|
start_ms.emplace(now_ms);
|
|
|
|
|
|
|
|
|
|
if ((now_ms - *start_ms) >= min_low_ms) {
|
|
|
|
|
LOG(LS_INFO) << "Request forced SW encoder fallback.";
|
|
|
|
|
// In case the request fails, update time to avoid too frequent requests.
|
|
|
|
|
start_ms.emplace(now_ms);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool VideoEncoderSoftwareFallbackWrapper::ForcedFallbackParams::ShouldStop(
|
2017-08-17 08:58:54 -07:00
|
|
|
uint32_t bitrate_kbps,
|
|
|
|
|
const VideoCodec& codec) const {
|
|
|
|
|
return bitrate_kbps >= high_kbps &&
|
|
|
|
|
(codec.width * codec.height >= kMinPixelsStop);
|
2017-08-16 00:53:59 -07:00
|
|
|
}
|
|
|
|
|
|
2017-08-23 14:19:50 -07:00
|
|
|
void VideoEncoderSoftwareFallbackWrapper::MaybeModifyCodecForFallback() {
|
|
|
|
|
// We have a specific case for H264 ConstrainedBaseline because that is the
|
|
|
|
|
// only supported profile in Sw fallback.
|
|
|
|
|
if (!cricket::CodecNamesEq(codec_.name.c_str(), cricket::kH264CodecName))
|
|
|
|
|
return;
|
|
|
|
|
codec_.SetParam(cricket::kH264FmtpProfileLevelId,
|
|
|
|
|
cricket::kH264ProfileLevelConstrainedBaseline);
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-15 06:30:54 -08:00
|
|
|
} // namespace webrtc
|