Parse max-fr and max-fs from SDP FMTP line

max-fr and max-fs are mandatory fields for VP8 and VP9.

Add parsing as a first step to enable use of these fields.

Bug: chromium:1032518
Change-Id: I4fd8f7f84f6303d646fb3f5313a02d6cf4160346
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/162801
Commit-Queue: Johannes Kron <kron@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30114}
This commit is contained in:
Johannes Kron 2019-12-19 15:05:20 +01:00 committed by Commit Bot
parent 5cad55b240
commit c8f3134b29
4 changed files with 171 additions and 0 deletions

View File

@ -63,6 +63,20 @@ rtc_library("rtc_vp9_profile") {
]
}
rtc_library("rtc_sdp_fmtp_utils") {
visibility = [ "*" ]
sources = [
"base/sdp_fmtp_utils.cc",
"base/sdp_fmtp_utils.h",
]
deps = [
"../api/video_codecs:video_codecs_api",
"../rtc_base:stringutils",
"//third_party/abseil-cpp/absl/types:optional",
]
}
rtc_library("rtc_media_base") {
visibility = [ "*" ]
defines = []
@ -523,6 +537,7 @@ if (rtc_include_tests) {
":rtc_media_base",
":rtc_media_engine_defaults",
":rtc_media_tests_utils",
":rtc_sdp_fmtp_utils",
":rtc_simulcast_encoder_adapter",
":rtc_vp9_profile",
"../:webrtc_common",
@ -589,6 +604,7 @@ if (rtc_include_tests) {
"base/codec_unittest.cc",
"base/rtp_data_engine_unittest.cc",
"base/rtp_utils_unittest.cc",
"base/sdp_fmtp_utils_unittest.cc",
"base/stream_params_unittest.cc",
"base/turn_utils_unittest.cc",
"base/video_adapter_unittest.cc",

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2019 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 "media/base/sdp_fmtp_utils.h"
#include <map>
#include <utility>
#include "rtc_base/string_to_number.h"
namespace webrtc {
namespace {
// Max frame rate for VP8 and VP9 video.
const char kVPxFmtpMaxFrameRate[] = "max-fr";
// Max frame size for VP8 and VP9 video.
const char kVPxFmtpMaxFrameSize[] = "max-fs";
const int kVPxFmtpFrameSizeSubBlockPixels = 256;
absl::optional<int> ParsePositiveNumberFromParams(
const SdpVideoFormat::Parameters& params,
const char* parameter_name) {
const auto max_frame_rate_it = params.find(parameter_name);
if (max_frame_rate_it == params.end())
return absl::nullopt;
const absl::optional<int> i =
rtc::StringToNumber<int>(max_frame_rate_it->second);
if (!i.has_value() || i.value() <= 0)
return absl::nullopt;
return i;
}
} // namespace
absl::optional<int> ParseSdpForVPxMaxFrameRate(
const SdpVideoFormat::Parameters& params) {
return ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameRate);
}
absl::optional<int> ParseSdpForVPxMaxFrameSize(
const SdpVideoFormat::Parameters& params) {
const absl::optional<int> i =
ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameSize);
return i ? absl::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels)
: absl::nullopt;
}
} // namespace webrtc

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2019 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.
*/
#ifndef MEDIA_BASE_SDP_FMTP_UTILS_H_
#define MEDIA_BASE_SDP_FMTP_UTILS_H_
#include "absl/types/optional.h"
#include "api/video_codecs/sdp_video_format.h"
namespace webrtc {
// Parse max frame rate from SDP FMTP line. absl::nullopt is returned if the
// field is missing or not a number.
absl::optional<int> ParseSdpForVPxMaxFrameRate(
const SdpVideoFormat::Parameters& params);
// Parse max frame size from SDP FMTP line. absl::nullopt is returned if the
// field is missing or not a number. Please note that the value is stored in sub
// blocks but the returned value is in total number of pixels.
absl::optional<int> ParseSdpForVPxMaxFrameSize(
const SdpVideoFormat::Parameters& params);
} // namespace webrtc
#endif // MEDIA_BASE_SDP_FMTP_UTILS_H__

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2019 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 "media/base/sdp_fmtp_utils.h"
#include <string.h>
#include <map>
#include <utility>
#include "rtc_base/string_to_number.h"
#include "test/gtest.h"
namespace webrtc {
namespace {
// Max frame rate for VP8 and VP9 video.
const char kVPxFmtpMaxFrameRate[] = "max-fr";
// Max frame size for VP8 and VP9 video.
const char kVPxFmtpMaxFrameSize[] = "max-fs";
} // namespace
TEST(SdpFmtpUtilsTest, MaxFrameRateIsMissingOrInvalid) {
SdpVideoFormat::Parameters params;
absl::optional<int> empty = ParseSdpForVPxMaxFrameRate(params);
EXPECT_FALSE(empty);
params[kVPxFmtpMaxFrameRate] = "-1";
EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
params[kVPxFmtpMaxFrameRate] = "0";
EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
params[kVPxFmtpMaxFrameRate] = "abcde";
EXPECT_FALSE(ParseSdpForVPxMaxFrameRate(params));
}
TEST(SdpFmtpUtilsTest, MaxFrameRateIsSpecified) {
SdpVideoFormat::Parameters params;
params[kVPxFmtpMaxFrameRate] = "30";
EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 30);
params[kVPxFmtpMaxFrameRate] = "60";
EXPECT_EQ(ParseSdpForVPxMaxFrameRate(params), 60);
}
TEST(SdpFmtpUtilsTest, MaxFrameSizeIsMissingOrInvalid) {
SdpVideoFormat::Parameters params;
absl::optional<int> empty = ParseSdpForVPxMaxFrameSize(params);
EXPECT_FALSE(empty);
params[kVPxFmtpMaxFrameSize] = "-1";
EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
params[kVPxFmtpMaxFrameSize] = "0";
EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
params[kVPxFmtpMaxFrameSize] = "abcde";
EXPECT_FALSE(ParseSdpForVPxMaxFrameSize(params));
}
TEST(SdpFmtpUtilsTest, MaxFrameSizeIsSpecified) {
SdpVideoFormat::Parameters params;
params[kVPxFmtpMaxFrameSize] = "8100"; // 1920 x 1080 / (16^2)
EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 1920 * 1080);
params[kVPxFmtpMaxFrameSize] = "32400"; // 3840 x 2160 / (16^2)
EXPECT_EQ(ParseSdpForVPxMaxFrameSize(params), 3840 * 2160);
}
} // namespace webrtc