webrtc/test/mappable_native_buffer.h
Henrik Boström bd9e4a95eb Support native scaling of VideoFrameBuffers in LibvpxVp9Encoder.
This CL is part of Optimized Scaling efforts. In Chromium, the native
frame buffer is getting an optimized CropAndScale() implementation. To
support HW accelerated scaling, returning pre-scaled images and skipping
unnecessary intermediate downscales, WebRTC needs to 1) use CropAndScale
instead of libyuv::XXXXScale and 2) only map buffers it actually intends
to encode.
- To achieve this, WebRTC encoders are updated to map kNative video
  buffers so that in a follow-up CL VideoStreamEncoder can stop mapping
  intermediate buffer sizes.

In this CL LibvpxVp9Encoder is updated to map kNative buffers of pixel
formats it supports and convert ToI420() if the kNative buffer is
something else. A fake native buffer that keeps track of which
resolutions were mapped, MappableNativeBuffer, is added.

Because VP9 is currently an SVC encoder and not a simulcast encoder, it
does not need to invoke CropAndScale.

This CL also fixes MultiplexEncoderAdapter, but because it simply
forwards frames it only cares about the pixel format when
|supports_augmented_data_| is true so this is the only time we map it.
Because this encoder is not used with kNative in practise, we don't care
to make this path optimal.

Bug: webrtc:12469, chromium:1157072
Change-Id: I74edf85b18eccd0d250776bbade7a6444478efce
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/212580
Commit-Queue: Henrik Boström <hbos@webrtc.org>
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Reviewed-by: Evan Shrubsole <eshr@google.com>
Cr-Commit-Position: refs/heads/master@{#33526}
2021-03-22 13:35:35 +00:00

122 lines
4.4 KiB
C++

/*
* Copyright (c) 2020 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 TEST_MAPPABLE_NATIVE_BUFFER_H_
#define TEST_MAPPABLE_NATIVE_BUFFER_H_
#include <utility>
#include <vector>
#include "api/array_view.h"
#include "api/video/video_frame.h"
#include "common_video/include/video_frame_buffer.h"
#include "rtc_base/ref_counted_object.h"
#include "rtc_base/synchronization/mutex.h"
namespace webrtc {
namespace test {
class MappableNativeBuffer;
VideoFrame CreateMappableNativeFrame(int64_t ntp_time_ms,
VideoFrameBuffer::Type mappable_type,
int width,
int height);
rtc::scoped_refptr<MappableNativeBuffer> GetMappableNativeBufferFromVideoFrame(
const VideoFrame& frame);
// A for-testing native buffer that is scalable and mappable. The contents of
// the buffer is black and the pixels are created upon mapping. Mapped buffers
// are stored inside MappableNativeBuffer, allowing tests to verify which
// resolutions were mapped, e.g. when passing them in to an encoder or other
// modules.
class MappableNativeBuffer : public VideoFrameBuffer {
public:
// If |allow_i420_conversion| is false, calling ToI420() on a non-I420 buffer
// will DCHECK-crash. Used to ensure zero-copy in tests.
MappableNativeBuffer(VideoFrameBuffer::Type mappable_type,
int width,
int height);
~MappableNativeBuffer() override;
VideoFrameBuffer::Type mappable_type() const { return mappable_type_; }
VideoFrameBuffer::Type type() const override { return Type::kNative; }
int width() const override { return width_; }
int height() const override { return height_; }
rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(int offset_x,
int offset_y,
int crop_width,
int crop_height,
int scaled_width,
int scaled_height) override;
rtc::scoped_refptr<I420BufferInterface> ToI420() override;
rtc::scoped_refptr<VideoFrameBuffer> GetMappedFrameBuffer(
rtc::ArrayView<VideoFrameBuffer::Type> types) override;
// Gets all the buffers that have been mapped so far, including mappings of
// cropped and scaled buffers.
std::vector<rtc::scoped_refptr<VideoFrameBuffer>> GetMappedFramedBuffers()
const;
bool DidConvertToI420() const;
private:
friend class rtc::RefCountedObject<MappableNativeBuffer>;
class ScaledBuffer : public VideoFrameBuffer {
public:
ScaledBuffer(rtc::scoped_refptr<MappableNativeBuffer> parent,
int width,
int height);
~ScaledBuffer() override;
VideoFrameBuffer::Type type() const override { return Type::kNative; }
int width() const override { return width_; }
int height() const override { return height_; }
rtc::scoped_refptr<VideoFrameBuffer> CropAndScale(
int offset_x,
int offset_y,
int crop_width,
int crop_height,
int scaled_width,
int scaled_height) override;
rtc::scoped_refptr<I420BufferInterface> ToI420() override;
rtc::scoped_refptr<VideoFrameBuffer> GetMappedFrameBuffer(
rtc::ArrayView<VideoFrameBuffer::Type> types) override;
private:
friend class rtc::RefCountedObject<ScaledBuffer>;
const rtc::scoped_refptr<MappableNativeBuffer> parent_;
const int width_;
const int height_;
};
rtc::scoped_refptr<ScaledBuffer> FullSizeBuffer();
rtc::scoped_refptr<VideoFrameBuffer> GetOrCreateMappedBuffer(int width,
int height);
const VideoFrameBuffer::Type mappable_type_;
const int width_;
const int height_;
mutable Mutex lock_;
std::vector<rtc::scoped_refptr<VideoFrameBuffer>> mapped_buffers_
RTC_GUARDED_BY(&lock_);
};
} // namespace test
} // namespace webrtc
#endif // TEST_MAPPABLE_NATIVE_BUFFER_H_