Reland of H.264 packetization mode 0 (try 3) (patchset #1 id:1 of https://codereview.webrtc.org/2558453002/ )
Reason for revert: Fixed timeouts in slow tests Original issue's description: > Revert of H.264 packetization mode 0 (try 3) (patchset #13 id:490001 of https://codereview.webrtc.org/2528343002/ ) > > Reason for revert: > Failures on the Linux Memcheck bot > > Original issue's description: > > This approach passes packetization mode to the encoder as part of > > a cricket::VideoCodec structure, rather than as part of struct VideoCodecH264 inside webrtc::VideoCodec. > > > > BUG=600254 > > > > Committed: https://crrev.com/e59647b991f61cf1cf61b020356705e6c0f81257 > > Cr-Commit-Position: refs/heads/master@{#15437} > > TBR=hbos@webrtc.org,sprang@webrtc.org,mflodman@webrtc.org,magjed@webrtc.org > # Skipping CQ checks because original CL landed less than 1 days ago. > NOPRESUBMIT=true > NOTREECHECKS=true > NOTRY=true > BUG=600254 > > Committed: https://crrev.com/243a0a7a7fd6b5da1e32df31f1bfbb6a68dc09f3 > Cr-Commit-Position: refs/heads/master@{#15441} TBR=hbos@webrtc.org,sprang@webrtc.org,mflodman@webrtc.org,magjed@webrtc.org # Skipping CQ checks because original CL landed less than 1 days ago. NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=600254 Review-Url: https://codereview.webrtc.org/2558463002 Cr-Commit-Position: refs/heads/master@{#15445}
This commit is contained in:
@ -49,7 +49,7 @@ H264Encoder* H264Encoder::Create(const cricket::VideoCodec& codec) {
|
||||
#if defined(WEBRTC_USE_H264)
|
||||
RTC_CHECK(g_rtc_use_h264);
|
||||
LOG(LS_INFO) << "Creating H264EncoderImpl.";
|
||||
return new H264EncoderImpl();
|
||||
return new H264EncoderImpl(codec);
|
||||
#else
|
||||
RTC_NOTREACHED();
|
||||
return nullptr;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "webrtc/modules/video_coding/codecs/h264/h264_encoder_impl.h"
|
||||
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_api.h"
|
||||
#include "third_party/openh264/src/codec/api/svc/codec_app_def.h"
|
||||
@ -21,6 +22,7 @@
|
||||
#include "webrtc/base/checks.h"
|
||||
#include "webrtc/base/logging.h"
|
||||
#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
|
||||
#include "webrtc/media/base/mediaconstants.h"
|
||||
#include "webrtc/system_wrappers/include/metrics.h"
|
||||
|
||||
namespace webrtc {
|
||||
@ -150,7 +152,7 @@ static void RtpFragmentize(EncodedImage* encoded_image,
|
||||
}
|
||||
}
|
||||
|
||||
H264EncoderImpl::H264EncoderImpl()
|
||||
H264EncoderImpl::H264EncoderImpl(const cricket::VideoCodec& codec)
|
||||
: openh264_encoder_(nullptr),
|
||||
width_(0),
|
||||
height_(0),
|
||||
@ -160,10 +162,20 @@ H264EncoderImpl::H264EncoderImpl()
|
||||
mode_(kRealtimeVideo),
|
||||
frame_dropping_on_(false),
|
||||
key_frame_interval_(0),
|
||||
packetization_mode_(H264PacketizationMode::SingleNalUnit),
|
||||
max_payload_size_(0),
|
||||
number_of_cores_(0),
|
||||
encoded_image_callback_(nullptr),
|
||||
has_reported_init_(false),
|
||||
has_reported_error_(false) {}
|
||||
has_reported_error_(false) {
|
||||
RTC_CHECK(cricket::CodecNamesEq(codec.name, cricket::kH264CodecName));
|
||||
std::string packetization_mode_string;
|
||||
if (codec.GetParam(cricket::kH264FmtpPacketizationMode,
|
||||
&packetization_mode_string) &&
|
||||
packetization_mode_string == "1") {
|
||||
packetization_mode_ = H264PacketizationMode::NonInterleaved;
|
||||
}
|
||||
}
|
||||
|
||||
H264EncoderImpl::~H264EncoderImpl() {
|
||||
Release();
|
||||
@ -171,7 +183,7 @@ H264EncoderImpl::~H264EncoderImpl() {
|
||||
|
||||
int32_t H264EncoderImpl::InitEncode(const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores,
|
||||
size_t /*max_payload_size*/) {
|
||||
size_t max_payload_size) {
|
||||
ReportInit();
|
||||
if (!codec_settings ||
|
||||
codec_settings->codecType != kVideoCodecH264) {
|
||||
@ -218,6 +230,7 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* codec_settings,
|
||||
mode_ = codec_settings->mode;
|
||||
frame_dropping_on_ = codec_settings->H264().frameDroppingOn;
|
||||
key_frame_interval_ = codec_settings->H264().keyFrameInterval;
|
||||
max_payload_size_ = max_payload_size;
|
||||
|
||||
// Codec_settings uses kbits/second; encoder uses bits/second.
|
||||
max_bps_ = codec_settings->maxBitrate * 1000;
|
||||
@ -227,6 +240,7 @@ int32_t H264EncoderImpl::InitEncode(const VideoCodec* codec_settings,
|
||||
target_bps_ = codec_settings->targetBitrate * 1000;
|
||||
|
||||
SEncParamExt encoder_params = CreateEncoderParams();
|
||||
|
||||
// Initialize.
|
||||
if (openh264_encoder_->InitializeExt(&encoder_params) != 0) {
|
||||
LOG(LS_ERROR) << "Failed to initialize OpenH264 encoder";
|
||||
@ -370,6 +384,7 @@ int32_t H264EncoderImpl::Encode(const VideoFrame& input_frame,
|
||||
// Deliver encoded image.
|
||||
CodecSpecificInfo codec_specific;
|
||||
codec_specific.codecType = kVideoCodecH264;
|
||||
codec_specific.codecSpecific.H264.packetization_mode = packetization_mode_;
|
||||
encoded_image_callback_->OnEncodedImage(encoded_image_, &codec_specific,
|
||||
&frag_header);
|
||||
|
||||
@ -434,19 +449,46 @@ SEncParamExt H264EncoderImpl::CreateEncoderParams() const {
|
||||
encoder_params.iTargetBitrate;
|
||||
encoder_params.sSpatialLayers[0].iMaxSpatialBitrate =
|
||||
encoder_params.iMaxBitrate;
|
||||
LOG(INFO) << "OpenH264 version is " << OPENH264_MAJOR << "."
|
||||
<< OPENH264_MINOR;
|
||||
switch (packetization_mode_) {
|
||||
case H264PacketizationMode::SingleNalUnit:
|
||||
// Limit the size of the packets produced.
|
||||
#if (OPENH264_MAJOR == 1) && (OPENH264_MINOR <= 5)
|
||||
// Slice num according to number of threads.
|
||||
encoder_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_AUTO_SLICE;
|
||||
encoder_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_DYN_SLICE;
|
||||
// The slice size is max payload size - room for a NAL header.
|
||||
// The constant 50 is NAL_HEADER_ADD_0X30BYTES in openh264 source,
|
||||
// but is not exported.
|
||||
const kNalHeaderSizeAllocation = 50;
|
||||
encoder_params.sSpatialLayers[0]
|
||||
.sSliceCfg.sSliceArgument.uiSliceSizeConstraint =
|
||||
static_cast<unsigned int>(max_payload_size_ -
|
||||
kNalHeaderSizeAllocation);
|
||||
encoder_params.uiMaxNalSize =
|
||||
static_cast<unsigned int>(max_payload_size_);
|
||||
#else
|
||||
// When uiSliceMode = SM_FIXEDSLCNUM_SLICE, uiSliceNum = 0 means auto design
|
||||
// it with cpu core number.
|
||||
// TODO(sprang): Set to 0 when we understand why the rate controller borks
|
||||
// when uiSliceNum > 1.
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceNum = 1;
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceMode =
|
||||
SM_FIXEDSLCNUM_SLICE;
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceNum = 1;
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceMode =
|
||||
SM_SIZELIMITED_SLICE;
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceSizeConstraint =
|
||||
static_cast<unsigned int>(max_payload_size_);
|
||||
#endif
|
||||
|
||||
break;
|
||||
case H264PacketizationMode::NonInterleaved:
|
||||
#if (OPENH264_MAJOR == 1) && (OPENH264_MINOR <= 5)
|
||||
// Slice num according to number of threads.
|
||||
encoder_params.sSpatialLayers[0].sSliceCfg.uiSliceMode = SM_AUTO_SLICE;
|
||||
#else
|
||||
// When uiSliceMode = SM_FIXEDSLCNUM_SLICE, uiSliceNum = 0 means auto
|
||||
// design it with cpu core number.
|
||||
// TODO(sprang): Set to 0 when we understand why the rate controller borks
|
||||
// when uiSliceNum > 1.
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceNum = 1;
|
||||
encoder_params.sSpatialLayers[0].sSliceArgument.uiSliceMode =
|
||||
SM_FIXEDSLCNUM_SLICE;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return encoder_params;
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,7 @@ namespace webrtc {
|
||||
|
||||
class H264EncoderImpl : public H264Encoder {
|
||||
public:
|
||||
H264EncoderImpl();
|
||||
explicit H264EncoderImpl(const cricket::VideoCodec& codec);
|
||||
~H264EncoderImpl() override;
|
||||
|
||||
// |max_payload_size| is ignored.
|
||||
@ -39,7 +39,7 @@ class H264EncoderImpl : public H264Encoder {
|
||||
// - height
|
||||
int32_t InitEncode(const VideoCodec* codec_settings,
|
||||
int32_t number_of_cores,
|
||||
size_t /*max_payload_size*/) override;
|
||||
size_t max_payload_size) override;
|
||||
int32_t Release() override;
|
||||
|
||||
int32_t RegisterEncodeCompleteCallback(
|
||||
@ -61,6 +61,11 @@ class H264EncoderImpl : public H264Encoder {
|
||||
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override;
|
||||
int32_t SetPeriodicKeyFrames(bool enable) override;
|
||||
|
||||
// Exposed for testing.
|
||||
H264PacketizationMode PacketizationModeForTesting() const {
|
||||
return packetization_mode_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool IsInitialized() const;
|
||||
SEncParamExt CreateEncoderParams() const;
|
||||
@ -81,7 +86,9 @@ class H264EncoderImpl : public H264Encoder {
|
||||
// H.264 specifc parameters
|
||||
bool frame_dropping_on_;
|
||||
int key_frame_interval_;
|
||||
H264PacketizationMode packetization_mode_;
|
||||
|
||||
size_t max_payload_size_;
|
||||
int32_t number_of_cores_;
|
||||
|
||||
EncodedImage encoded_image_;
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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/modules/video_coding/codecs/h264/h264_encoder_impl.h"
|
||||
|
||||
#include "webrtc/test/gtest.h"
|
||||
|
||||
namespace webrtc {
|
||||
|
||||
namespace {
|
||||
|
||||
const int kMaxPayloadSize = 1024;
|
||||
const int kNumCores = 1;
|
||||
|
||||
void SetDefaultSettings(VideoCodec* codec_settings) {
|
||||
codec_settings->codecType = kVideoCodecH264;
|
||||
codec_settings->maxFramerate = 60;
|
||||
codec_settings->width = 640;
|
||||
codec_settings->height = 480;
|
||||
// If frame dropping is false, we get a warning that bitrate can't
|
||||
// be controlled for RC_QUALITY_MODE; RC_BITRATE_MODE and RC_TIMESTAMP_MODE
|
||||
codec_settings->H264()->frameDroppingOn = true;
|
||||
codec_settings->targetBitrate = 2000;
|
||||
codec_settings->maxBitrate = 4000;
|
||||
}
|
||||
|
||||
TEST(H264EncoderImplTest, CanInitializeWithDefaultParameters) {
|
||||
H264EncoderImpl encoder(cricket::VideoCodec("H264"));
|
||||
VideoCodec codec_settings;
|
||||
SetDefaultSettings(&codec_settings);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
||||
EXPECT_EQ(H264PacketizationMode::NonInterleaved,
|
||||
encoder.PacketizationModeForTesting());
|
||||
}
|
||||
|
||||
TEST(H264EncoderImplTest, CanInitializeWithNonInterleavedModeExplicitly) {
|
||||
cricket::VideoCodec codec("H264");
|
||||
codec.SetParam(cricket::kH264FmtpPacketizationMode, "1");
|
||||
H264EncoderImpl encoder(codec);
|
||||
VideoCodec codec_settings;
|
||||
SetDefaultSettings(&codec_settings);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
||||
EXPECT_EQ(H264PacketizationMode::NonInterleaved,
|
||||
encoder.PacketizationModeForTesting());
|
||||
}
|
||||
|
||||
TEST(H264EncoderImplTest, CanInitializeWithSingleNalUnitModeExplicitly) {
|
||||
cricket::VideoCodec codec("H264");
|
||||
codec.SetParam(cricket::kH264FmtpPacketizationMode, "0");
|
||||
H264EncoderImpl encoder(codec);
|
||||
VideoCodec codec_settings;
|
||||
SetDefaultSettings(&codec_settings);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
||||
EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
|
||||
encoder.PacketizationModeForTesting());
|
||||
}
|
||||
|
||||
TEST(H264EncoderImplTest, CanInitializeWithRemovedParameter) {
|
||||
cricket::VideoCodec codec("H264");
|
||||
codec.RemoveParam(cricket::kH264FmtpPacketizationMode);
|
||||
H264EncoderImpl encoder(codec);
|
||||
VideoCodec codec_settings;
|
||||
SetDefaultSettings(&codec_settings);
|
||||
EXPECT_EQ(WEBRTC_VIDEO_CODEC_OK,
|
||||
encoder.InitEncode(&codec_settings, kNumCores, kMaxPayloadSize));
|
||||
EXPECT_EQ(H264PacketizationMode::SingleNalUnit,
|
||||
encoder.PacketizationModeForTesting());
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
} // namespace webrtc
|
||||
Reference in New Issue
Block a user