Commit 260cd179 authored by Chih-Yu Huang's avatar Chih-Yu Huang Committed by Commit Bot

vaapi vea, v4l2 vea: Use fixed output buffer size.

In CL:1195175 we change the formula for Vaapi VEA. However, the
formula still failed at small resolution. According to the
investigation at crbug.com/889739 comment 1 and 2, using the fixed
buffer size might be the choice before we can update the buffer size
when the bitrate and framerate are changed.

Also, Because this function is general for Vaapi VEA and V4L2 VEA, we
move it to gpu_video_accelerator_util.

BUG=b:113309237
BUG=chromium:889739
TEST=pass VideoEncoderTest CTS on eve and scarlet device
TEST=pass RTC lookback on eve at H264 HD
TEST=pass VEA unittest on eve

Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: I0aa6fd8b67c19ad93bae6e62430105dc9ccf6a80
Reviewed-on: https://chromium-review.googlesource.com/1253315
Commit-Queue: Chih-Yu Huang <akahuang@chromium.org>
Reviewed-by: default avatarPawel Osciak <posciak@chromium.org>
Reviewed-by: default avatarHirokazu Honda <hiroh@chromium.org>
Cr-Commit-Position: refs/heads/master@{#595738}
parent 3e89d0d3
......@@ -326,6 +326,8 @@ source_set("common") {
"format_utils.cc",
"format_utils.h",
"gpu_video_decode_accelerator_helpers.h",
"gpu_video_encode_accelerator_helpers.cc",
"gpu_video_encode_accelerator_helpers.h",
"h264_decoder.cc",
"h264_decoder.h",
"h264_dpb.cc",
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/gpu/gpu_video_encode_accelerator_helpers.h"
#include <algorithm>
#include "base/logging.h"
namespace media {
namespace {
// The maximum size for output buffer, which is chosen empirically for
// 1080p video.
constexpr size_t kMaxBitstreamBufferSizeInBytes = 2 * 1024 * 1024; // 2MB
// The mapping from resolution, bitrate, framerate to the bitstream buffer size.
struct BitstreamBufferSizeInfo {
int coded_size_area;
uint32_t bitrate_in_bps;
uint32_t framerate;
uint32_t buffer_size_in_bytes;
};
// The bitstream buffer size for each resolution. The table must be sorted in
// increasing order by the resolution. The value is decided by measuring the
// biggest buffer size, and then double the size as margin. (crbug.com/889739)
// TODO(akahuang): Measure the buffer size when we support 4K encoding.
constexpr BitstreamBufferSizeInfo kBitstreamBufferSizeTable[] = {
{320 * 180, 100000, 30, 15000},
{640 * 360, 500000, 30, 52000},
{1280 * 720, 1200000, 30, 110000},
{1920 * 1080, 4000000, 30, 380000},
};
} // namespace
size_t GetEncodeBitstreamBufferSize(const gfx::Size& size,
uint32_t bitrate,
uint32_t framerate) {
DCHECK_NE(framerate, 0u);
for (auto& data : kBitstreamBufferSizeTable) {
if (size.GetArea() <= data.coded_size_area) {
// The buffer size is proportional to (bitrate / framerate), but linear
// interpolation for smaller ratio is not enough. Therefore we only use
// linear extrapolation for larger ratio.
double ratio = std::max(
1.0f * (bitrate / framerate) / (data.bitrate_in_bps / data.framerate),
1.0f);
return std::min(static_cast<size_t>(data.buffer_size_in_bytes * ratio),
kMaxBitstreamBufferSizeInBytes);
}
}
return kMaxBitstreamBufferSizeInBytes;
}
// Get the maximum output bitstream buffer size. Because we don't change
// the buffer size when we update bitrate and framerate, we have to calculate
// the buffer size by the maximum bitrate.
// However, the maximum bitrate for intel chipset is 40Mbps. The buffer size
// calculated with this bitrate is always larger than 2MB. Therefore we just
// return the value.
// TODO(crbug.com/889739): Deprecate this function after we can update the
// buffer size while requesting new bitrate and framerate.
size_t GetEncodeBitstreamBufferSize() {
// GetEncodeBitstreamBufferSize(size, 40000000, 30)
return kMaxBitstreamBufferSizeInBytes;
}
} // namespace media
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_GPU_GPU_VIDEO_ENCODE_ACCELERATOR_HELPERS_H_
#define MEDIA_GPU_GPU_VIDEO_ENCODE_ACCELERATOR_HELPERS_H_
#include "media/gpu/media_gpu_export.h"
#include "ui/gfx/geometry/size.h"
namespace media {
// Helper functions for VideoEncodeAccelerator implementations in GPU process.
// Calculate the bitstream buffer size for VideoEncodeAccelerator.
// |size|: the resolution of video stream
// |bitrate|: the bit rate in bps
// |framerate|: the frame rate in fps
MEDIA_GPU_EXPORT size_t GetEncodeBitstreamBufferSize(const gfx::Size& size,
uint32_t bitrate,
uint32_t framerate);
// Get the maximum bitstream buffer size for VideoEncodeAccelerator.
MEDIA_GPU_EXPORT size_t GetEncodeBitstreamBufferSize();
} // namespace media
#endif // MEDIA_GPU_GPU_VIDEO_ENCODE_ACCELERATOR_HELPERS_H_
......@@ -26,6 +26,7 @@
#include "media/base/scopedfd_helper.h"
#include "media/base/unaligned_shared_memory.h"
#include "media/base/video_types.h"
#include "media/gpu/gpu_video_encode_accelerator_helpers.h"
#include "media/gpu/v4l2/v4l2_image_processor.h"
#include "media/video/h264_parser.h"
......@@ -1051,7 +1052,7 @@ bool V4L2VideoEncodeAccelerator::SetOutputFormat(
DCHECK(!input_streamon_);
DCHECK(!output_streamon_);
output_buffer_byte_size_ = kOutputBufferSize;
output_buffer_byte_size_ = GetEncodeBitstreamBufferSize();
struct v4l2_format format;
memset(&format, 0, sizeof(format));
......
......@@ -96,7 +96,6 @@ class MEDIA_GPU_EXPORT V4L2VideoEncodeAccelerator
kInputBufferCount = 2,
kOutputBufferCount = 2,
kImageProcBufferCount = 2,
kOutputBufferSize = (2 * 1024 * 1024),
};
// Internal state of the encoder.
......
......@@ -4,20 +4,12 @@
#include "media/gpu/vaapi/accelerated_video_encoder.h"
#include <algorithm>
#include "media/base/video_frame.h"
#include "media/gpu/gpu_video_encode_accelerator_helpers.h"
#include "media/video/video_encode_accelerator.h"
namespace media {
namespace {
// The maximum size for bitstream buffer, which is chosen empirically for the
// video smaller than 1080p.
// TODO(akahuang): Refactor it when we support 4K encoding.
constexpr size_t kMaxBitstreamBufferSizeInBytes = 2 * 1024 * 1024; // 2MB
} // namespace
AcceleratedVideoEncoder::EncodeJob::EncodeJob(
scoped_refptr<VideoFrame> input_frame,
bool keyframe,
......@@ -64,11 +56,7 @@ void AcceleratedVideoEncoder::EncodeJob::Execute() {
}
size_t AcceleratedVideoEncoder::GetBitstreamBufferSize() const {
// The buffer size of uncompressed stream is a feasible estimation of the
// output buffer size. However, the estimation is loose in high resolution.
// Therefore we set an empirical upper bound.
size_t uncompressed_buffer_size = GetCodedSize().GetArea() * 3 / 2;
return std::min(uncompressed_buffer_size, kMaxBitstreamBufferSizeInBytes);
return GetEncodeBitstreamBufferSize();
}
} // namespace media
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment