Delete post_encode_callback
Bug: webrtc:9864 Change-Id: I5e45a73e50e2cf6b25b415a83fe637f8f5b4e70e Reviewed-on: https://webrtc-review.googlesource.com/c/14840 Commit-Queue: Niels Moller <nisse@webrtc.org> Reviewed-by: Sebastian Jansson <srte@webrtc.org> Reviewed-by: Erik Språng <sprang@webrtc.org> Reviewed-by: Stefan Holmer <stefan@webrtc.org> Cr-Commit-Position: refs/heads/master@{#25106}
This commit is contained in:
@ -26,7 +26,6 @@
|
|||||||
#include "api/video_codecs/sdp_video_format.h"
|
#include "api/video_codecs/sdp_video_format.h"
|
||||||
#include "call/rtp_config.h"
|
#include "call/rtp_config.h"
|
||||||
#include "common_types.h" // NOLINT(build/include)
|
#include "common_types.h" // NOLINT(build/include)
|
||||||
#include "common_video/include/frame_callback.h"
|
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
@ -78,8 +78,6 @@ std::string VideoSendStream::Config::ToString() const {
|
|||||||
ss << ", rtcp: " << rtcp.ToString();
|
ss << ", rtcp: " << rtcp.ToString();
|
||||||
ss << ", pre_encode_callback: "
|
ss << ", pre_encode_callback: "
|
||||||
<< (pre_encode_callback ? "(VideoSinkInterface)" : "nullptr");
|
<< (pre_encode_callback ? "(VideoSinkInterface)" : "nullptr");
|
||||||
ss << ", post_encode_callback: "
|
|
||||||
<< (post_encode_callback ? "(EncodedFrameObserver)" : "nullptr");
|
|
||||||
ss << ", render_delay_ms: " << render_delay_ms;
|
ss << ", render_delay_ms: " << render_delay_ms;
|
||||||
ss << ", target_delay_ms: " << target_delay_ms;
|
ss << ", target_delay_ms: " << target_delay_ms;
|
||||||
ss << ", suspend_below_min_bitrate: "
|
ss << ", suspend_below_min_bitrate: "
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "api/call/transport.h"
|
#include "api/call/transport.h"
|
||||||
|
#include "api/video/video_frame.h"
|
||||||
#include "api/video/video_sink_interface.h"
|
#include "api/video/video_sink_interface.h"
|
||||||
#include "api/video/video_source_interface.h"
|
#include "api/video/video_source_interface.h"
|
||||||
#include "api/video/video_stream_encoder_settings.h"
|
#include "api/video/video_stream_encoder_settings.h"
|
||||||
@ -24,7 +25,6 @@
|
|||||||
#include "api/video_codecs/video_encoder_factory.h"
|
#include "api/video_codecs/video_encoder_factory.h"
|
||||||
#include "call/rtp_config.h"
|
#include "call/rtp_config.h"
|
||||||
#include "common_types.h" // NOLINT(build/include)
|
#include "common_types.h" // NOLINT(build/include)
|
||||||
#include "common_video/include/frame_callback.h"
|
|
||||||
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -117,12 +117,6 @@ class VideoSendStream {
|
|||||||
// effects, snapshots etc. 'nullptr' disables the callback.
|
// effects, snapshots etc. 'nullptr' disables the callback.
|
||||||
rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback = nullptr;
|
rtc::VideoSinkInterface<VideoFrame>* pre_encode_callback = nullptr;
|
||||||
|
|
||||||
// Called for each encoded frame, e.g. used for file storage. 'nullptr'
|
|
||||||
// disables the callback. Also measures timing and passes the time
|
|
||||||
// spent on encoding. This timing will not fire if encoding takes longer
|
|
||||||
// than the measuring window, since the sample data will have been dropped.
|
|
||||||
EncodedFrameObserver* post_encode_callback = nullptr;
|
|
||||||
|
|
||||||
// Expected delay needed by the renderer, i.e. the frame will be delivered
|
// Expected delay needed by the renderer, i.e. the frame will be delivered
|
||||||
// this many milliseconds, if possible, earlier than expected render time.
|
// this many milliseconds, if possible, earlier than expected render time.
|
||||||
// Only valid if |local_renderer| is set.
|
// Only valid if |local_renderer| is set.
|
||||||
|
@ -26,7 +26,6 @@ rtc_static_library("common_video") {
|
|||||||
"h264/sps_vui_rewriter.h",
|
"h264/sps_vui_rewriter.h",
|
||||||
"i420_buffer_pool.cc",
|
"i420_buffer_pool.cc",
|
||||||
"include/bitrate_adjuster.h",
|
"include/bitrate_adjuster.h",
|
||||||
"include/frame_callback.h",
|
|
||||||
"include/i420_buffer_pool.h",
|
"include/i420_buffer_pool.h",
|
||||||
"include/incoming_video_stream.h",
|
"include/incoming_video_stream.h",
|
||||||
"include/video_frame.h",
|
"include/video_frame.h",
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2013 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 COMMON_VIDEO_INCLUDE_FRAME_CALLBACK_H_
|
|
||||||
#define COMMON_VIDEO_INCLUDE_FRAME_CALLBACK_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#include "common_types.h" // NOLINT(build/include)
|
|
||||||
|
|
||||||
namespace webrtc {
|
|
||||||
|
|
||||||
class VideoFrame;
|
|
||||||
|
|
||||||
struct EncodedFrame {
|
|
||||||
public:
|
|
||||||
EncodedFrame()
|
|
||||||
: data_(nullptr),
|
|
||||||
length_(0),
|
|
||||||
frame_type_(kEmptyFrame),
|
|
||||||
stream_id_(0),
|
|
||||||
timestamp_(0) {}
|
|
||||||
EncodedFrame(const uint8_t* data,
|
|
||||||
size_t length,
|
|
||||||
FrameType frame_type,
|
|
||||||
size_t stream_id,
|
|
||||||
uint32_t timestamp)
|
|
||||||
: data_(data),
|
|
||||||
length_(length),
|
|
||||||
frame_type_(frame_type),
|
|
||||||
stream_id_(stream_id),
|
|
||||||
timestamp_(timestamp) {}
|
|
||||||
|
|
||||||
const uint8_t* data_;
|
|
||||||
const size_t length_;
|
|
||||||
const FrameType frame_type_;
|
|
||||||
const size_t stream_id_;
|
|
||||||
const uint32_t timestamp_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class EncodedFrameObserver {
|
|
||||||
public:
|
|
||||||
virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) = 0;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual ~EncodedFrameObserver() {}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace webrtc
|
|
||||||
|
|
||||||
#endif // COMMON_VIDEO_INCLUDE_FRAME_CALLBACK_H_
|
|
@ -17,7 +17,6 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "common_video/include/frame_callback.h"
|
|
||||||
#include "modules/video_coding/decoder_database.h"
|
#include "modules/video_coding/decoder_database.h"
|
||||||
#include "modules/video_coding/encoder_database.h"
|
#include "modules/video_coding/encoder_database.h"
|
||||||
#include "modules/video_coding/frame_buffer.h"
|
#include "modules/video_coding/frame_buffer.h"
|
||||||
|
@ -221,79 +221,4 @@ TEST_P(CallOperationEndToEndTest, TransmitsFirstFrame) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_P(CallOperationEndToEndTest, ObserversEncodedFrames) {
|
|
||||||
class EncodedFrameTestObserver : public EncodedFrameObserver {
|
|
||||||
public:
|
|
||||||
EncodedFrameTestObserver()
|
|
||||||
: length_(0), frame_type_(kEmptyFrame), called_(false, false) {}
|
|
||||||
virtual ~EncodedFrameTestObserver() {}
|
|
||||||
|
|
||||||
virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
|
|
||||||
frame_type_ = encoded_frame.frame_type_;
|
|
||||||
length_ = encoded_frame.length_;
|
|
||||||
buffer_.reset(new uint8_t[length_]);
|
|
||||||
memcpy(buffer_.get(), encoded_frame.data_, length_);
|
|
||||||
called_.Set();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Wait() { return called_.Wait(kDefaultTimeoutMs); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::unique_ptr<uint8_t[]> buffer_;
|
|
||||||
size_t length_;
|
|
||||||
FrameType frame_type_;
|
|
||||||
rtc::Event called_;
|
|
||||||
};
|
|
||||||
|
|
||||||
EncodedFrameTestObserver post_encode_observer;
|
|
||||||
test::FrameForwarder forwarder;
|
|
||||||
std::unique_ptr<test::FrameGenerator> frame_generator;
|
|
||||||
|
|
||||||
std::unique_ptr<test::DirectTransport> sender_transport;
|
|
||||||
std::unique_ptr<test::DirectTransport> receiver_transport;
|
|
||||||
|
|
||||||
task_queue_.SendTask([&]() {
|
|
||||||
CreateCalls();
|
|
||||||
|
|
||||||
sender_transport = absl::make_unique<test::DirectTransport>(
|
|
||||||
&task_queue_,
|
|
||||||
absl::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
|
|
||||||
absl::make_unique<SimulatedNetwork>(
|
|
||||||
BuiltInNetworkBehaviorConfig())),
|
|
||||||
sender_call_.get(), payload_type_map_);
|
|
||||||
receiver_transport = absl::make_unique<test::DirectTransport>(
|
|
||||||
&task_queue_,
|
|
||||||
absl::make_unique<FakeNetworkPipe>(Clock::GetRealTimeClock(),
|
|
||||||
absl::make_unique<SimulatedNetwork>(
|
|
||||||
BuiltInNetworkBehaviorConfig())),
|
|
||||||
receiver_call_.get(), payload_type_map_);
|
|
||||||
sender_transport->SetReceiver(receiver_call_->Receiver());
|
|
||||||
receiver_transport->SetReceiver(sender_call_->Receiver());
|
|
||||||
|
|
||||||
CreateSendConfig(1, 0, 0, sender_transport.get());
|
|
||||||
CreateMatchingReceiveConfigs(receiver_transport.get());
|
|
||||||
GetVideoSendConfig()->post_encode_callback = &post_encode_observer;
|
|
||||||
|
|
||||||
CreateVideoStreams();
|
|
||||||
Start();
|
|
||||||
|
|
||||||
frame_generator = test::FrameGenerator::CreateSquareGenerator(
|
|
||||||
kDefaultWidth, kDefaultHeight, absl::nullopt, absl::nullopt);
|
|
||||||
GetVideoSendStream()->SetSource(&forwarder,
|
|
||||||
DegradationPreference::MAINTAIN_FRAMERATE);
|
|
||||||
forwarder.IncomingCapturedFrame(*frame_generator->NextFrame());
|
|
||||||
});
|
|
||||||
|
|
||||||
EXPECT_TRUE(post_encode_observer.Wait())
|
|
||||||
<< "Timed out while waiting for send-side encoded-frame callback.";
|
|
||||||
|
|
||||||
task_queue_.SendTask([this, &sender_transport, &receiver_transport]() {
|
|
||||||
Stop();
|
|
||||||
DestroyStreams();
|
|
||||||
sender_transport.reset();
|
|
||||||
receiver_transport.reset();
|
|
||||||
DestroyCalls();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -70,7 +70,6 @@ VideoAnalyzer::VideoAnalyzer(test::LayerFilteringTransport* transport,
|
|||||||
selected_stream_(selected_stream),
|
selected_stream_(selected_stream),
|
||||||
selected_sl_(selected_sl),
|
selected_sl_(selected_sl),
|
||||||
selected_tl_(selected_tl),
|
selected_tl_(selected_tl),
|
||||||
pre_encode_proxy_(this),
|
|
||||||
last_fec_bytes_(0),
|
last_fec_bytes_(0),
|
||||||
frames_to_process_(duration_frames),
|
frames_to_process_(duration_frames),
|
||||||
frames_recorded_(0),
|
frames_recorded_(0),
|
||||||
@ -231,10 +230,10 @@ void VideoAnalyzer::PreEncodeOnFrame(const VideoFrame& video_frame) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoAnalyzer::EncodedFrameCallback(const EncodedFrame& encoded_frame) {
|
void VideoAnalyzer::PostEncodeOnFrame(size_t stream_id, uint32_t timestamp) {
|
||||||
rtc::CritScope lock(&crit_);
|
rtc::CritScope lock(&crit_);
|
||||||
if (!first_sent_timestamp_ && encoded_frame.stream_id_ == selected_stream_) {
|
if (!first_sent_timestamp_ && stream_id == selected_stream_) {
|
||||||
first_sent_timestamp_ = encoded_frame.timestamp_;
|
first_sent_timestamp_ = timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -366,10 +365,6 @@ void VideoAnalyzer::Wait() {
|
|||||||
stats_polling_thread_.Stop();
|
stats_polling_thread_.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::VideoSinkInterface<VideoFrame>* VideoAnalyzer::pre_encode_proxy() {
|
|
||||||
return &pre_encode_proxy_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoAnalyzer::StartMeasuringCpuProcessTime() {
|
void VideoAnalyzer::StartMeasuringCpuProcessTime() {
|
||||||
rtc::CritScope lock(&cpu_measurement_lock_);
|
rtc::CritScope lock(&cpu_measurement_lock_);
|
||||||
cpu_time_ -= rtc::GetProcessCpuTimeNanos();
|
cpu_time_ -= rtc::GetProcessCpuTimeNanos();
|
||||||
@ -841,13 +836,6 @@ VideoAnalyzer::Sample::Sample(int dropped,
|
|||||||
psnr(psnr),
|
psnr(psnr),
|
||||||
ssim(ssim) {}
|
ssim(ssim) {}
|
||||||
|
|
||||||
VideoAnalyzer::PreEncodeProxy::PreEncodeProxy(VideoAnalyzer* parent)
|
|
||||||
: parent_(parent) {}
|
|
||||||
|
|
||||||
void VideoAnalyzer::PreEncodeProxy::OnFrame(const VideoFrame& video_frame) {
|
|
||||||
parent_->PreEncodeOnFrame(video_frame);
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoAnalyzer::CapturedFrameForwarder::CapturedFrameForwarder(
|
VideoAnalyzer::CapturedFrameForwarder::CapturedFrameForwarder(
|
||||||
VideoAnalyzer* analyzer,
|
VideoAnalyzer* analyzer,
|
||||||
Clock* clock)
|
Clock* clock)
|
||||||
|
@ -25,8 +25,7 @@ namespace webrtc {
|
|||||||
|
|
||||||
class VideoAnalyzer : public PacketReceiver,
|
class VideoAnalyzer : public PacketReceiver,
|
||||||
public Transport,
|
public Transport,
|
||||||
public rtc::VideoSinkInterface<VideoFrame>,
|
public rtc::VideoSinkInterface<VideoFrame> {
|
||||||
public EncodedFrameObserver {
|
|
||||||
public:
|
public:
|
||||||
VideoAnalyzer(test::LayerFilteringTransport* transport,
|
VideoAnalyzer(test::LayerFilteringTransport* transport,
|
||||||
const std::string& test_label,
|
const std::string& test_label,
|
||||||
@ -61,9 +60,7 @@ class VideoAnalyzer : public PacketReceiver,
|
|||||||
int64_t packet_time_us) override;
|
int64_t packet_time_us) override;
|
||||||
|
|
||||||
void PreEncodeOnFrame(const VideoFrame& video_frame);
|
void PreEncodeOnFrame(const VideoFrame& video_frame);
|
||||||
|
void PostEncodeOnFrame(size_t stream_id, uint32_t timestamp);
|
||||||
// EncodedFrameObserver implementation, wired to post_encode_callback.
|
|
||||||
void EncodedFrameCallback(const EncodedFrame& encoded_frame) override;
|
|
||||||
|
|
||||||
bool SendRtp(const uint8_t* packet,
|
bool SendRtp(const uint8_t* packet,
|
||||||
size_t length,
|
size_t length,
|
||||||
@ -73,8 +70,6 @@ class VideoAnalyzer : public PacketReceiver,
|
|||||||
void OnFrame(const VideoFrame& video_frame) override;
|
void OnFrame(const VideoFrame& video_frame) override;
|
||||||
void Wait();
|
void Wait();
|
||||||
|
|
||||||
rtc::VideoSinkInterface<VideoFrame>* pre_encode_proxy();
|
|
||||||
|
|
||||||
void StartMeasuringCpuProcessTime();
|
void StartMeasuringCpuProcessTime();
|
||||||
void StopMeasuringCpuProcessTime();
|
void StopMeasuringCpuProcessTime();
|
||||||
void StartExcludingCpuThreadTime();
|
void StartExcludingCpuThreadTime();
|
||||||
@ -132,17 +127,6 @@ class VideoAnalyzer : public PacketReceiver,
|
|||||||
double ssim;
|
double ssim;
|
||||||
};
|
};
|
||||||
|
|
||||||
// This class receives the send-side OnFrame callback and is provided to not
|
|
||||||
// conflict with the receiver-side renderer callback.
|
|
||||||
class PreEncodeProxy : public rtc::VideoSinkInterface<VideoFrame> {
|
|
||||||
public:
|
|
||||||
explicit PreEncodeProxy(VideoAnalyzer* parent);
|
|
||||||
void OnFrame(const VideoFrame& video_frame) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
VideoAnalyzer* const parent_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Implements VideoSinkInterface to receive captured frames from a
|
// Implements VideoSinkInterface to receive captured frames from a
|
||||||
// FrameGeneratorCapturer. Implements VideoSourceInterface to be able to act
|
// FrameGeneratorCapturer. Implements VideoSourceInterface to be able to act
|
||||||
// as a source to VideoSendStream.
|
// as a source to VideoSendStream.
|
||||||
@ -221,7 +205,6 @@ class VideoAnalyzer : public PacketReceiver,
|
|||||||
const size_t selected_stream_;
|
const size_t selected_stream_;
|
||||||
const int selected_sl_;
|
const int selected_sl_;
|
||||||
const int selected_tl_;
|
const int selected_tl_;
|
||||||
PreEncodeProxy pre_encode_proxy_;
|
|
||||||
|
|
||||||
rtc::CriticalSection comparison_lock_;
|
rtc::CriticalSection comparison_lock_;
|
||||||
std::vector<Sample> samples_ RTC_GUARDED_BY(comparison_lock_);
|
std::vector<Sample> samples_ RTC_GUARDED_BY(comparison_lock_);
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
#include "test/run_loop.h"
|
#include "test/run_loop.h"
|
||||||
#include "test/testsupport/fileutils.h"
|
#include "test/testsupport/fileutils.h"
|
||||||
#include "test/video_renderer.h"
|
#include "test/video_renderer.h"
|
||||||
#include "video/video_analyzer.h"
|
|
||||||
#ifdef WEBRTC_WIN
|
#ifdef WEBRTC_WIN
|
||||||
#include "modules/audio_device/include/audio_device_factory.h"
|
#include "modules/audio_device/include/audio_device_factory.h"
|
||||||
#endif
|
#endif
|
||||||
@ -123,13 +122,16 @@ class FrameDumpingDecoder : public VideoDecoder {
|
|||||||
std::unique_ptr<IvfFileWriter> writer_;
|
std::unique_ptr<IvfFileWriter> writer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An encoder wrapper that writes the encoded frames to file, one per simulcast
|
// This wrapper provides two features needed by the video quality tests:
|
||||||
// layer.
|
// 1. Invoke VideoAnalyzer callbacks before and after encoding each frame.
|
||||||
class FrameDumpingEncoder : public VideoEncoder, private EncodedImageCallback {
|
// 2. Write the encoded frames to file, one file per simulcast layer.
|
||||||
|
class QualityTestVideoEncoder : public VideoEncoder,
|
||||||
|
private EncodedImageCallback {
|
||||||
public:
|
public:
|
||||||
FrameDumpingEncoder(std::unique_ptr<VideoEncoder> encoder,
|
QualityTestVideoEncoder(std::unique_ptr<VideoEncoder> encoder,
|
||||||
std::vector<rtc::PlatformFile> files)
|
VideoAnalyzer* analyzer,
|
||||||
: encoder_(std::move(encoder)) {
|
std::vector<rtc::PlatformFile> files)
|
||||||
|
: encoder_(std::move(encoder)), analyzer_(analyzer) {
|
||||||
for (rtc::PlatformFile file : files) {
|
for (rtc::PlatformFile file : files) {
|
||||||
writers_.push_back(
|
writers_.push_back(
|
||||||
IvfFileWriter::Wrap(rtc::File(file), /* byte_limit= */ 100000000));
|
IvfFileWriter::Wrap(rtc::File(file), /* byte_limit= */ 100000000));
|
||||||
@ -151,6 +153,9 @@ class FrameDumpingEncoder : public VideoEncoder, private EncodedImageCallback {
|
|||||||
int32_t Encode(const VideoFrame& frame,
|
int32_t Encode(const VideoFrame& frame,
|
||||||
const CodecSpecificInfo* codec_specific_info,
|
const CodecSpecificInfo* codec_specific_info,
|
||||||
const std::vector<FrameType>* frame_types) {
|
const std::vector<FrameType>* frame_types) {
|
||||||
|
if (analyzer_) {
|
||||||
|
analyzer_->PreEncodeOnFrame(frame);
|
||||||
|
}
|
||||||
return encoder_->Encode(frame, codec_specific_info, frame_types);
|
return encoder_->Encode(frame, codec_specific_info, frame_types);
|
||||||
}
|
}
|
||||||
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override {
|
int32_t SetChannelParameters(uint32_t packet_loss, int64_t rtt) override {
|
||||||
@ -186,6 +191,10 @@ class FrameDumpingEncoder : public VideoEncoder, private EncodedImageCallback {
|
|||||||
simulcast_index = encoded_image.SpatialIndex().value_or(0);
|
simulcast_index = encoded_image.SpatialIndex().value_or(0);
|
||||||
}
|
}
|
||||||
RTC_DCHECK_GE(simulcast_index, 0);
|
RTC_DCHECK_GE(simulcast_index, 0);
|
||||||
|
if (analyzer_) {
|
||||||
|
analyzer_->PostEncodeOnFrame(simulcast_index,
|
||||||
|
encoded_image.Timestamp());
|
||||||
|
}
|
||||||
if (static_cast<size_t>(simulcast_index) < writers_.size()) {
|
if (static_cast<size_t>(simulcast_index) < writers_.size()) {
|
||||||
writers_[simulcast_index]->WriteFrame(encoded_image,
|
writers_[simulcast_index]->WriteFrame(encoded_image,
|
||||||
codec_specific_info->codecType);
|
codec_specific_info->codecType);
|
||||||
@ -202,6 +211,7 @@ class FrameDumpingEncoder : public VideoEncoder, private EncodedImageCallback {
|
|||||||
|
|
||||||
std::unique_ptr<VideoEncoder> encoder_;
|
std::unique_ptr<VideoEncoder> encoder_;
|
||||||
EncodedImageCallback* callback_ = nullptr;
|
EncodedImageCallback* callback_ = nullptr;
|
||||||
|
VideoAnalyzer* const analyzer_;
|
||||||
std::vector<std::unique_ptr<IvfFileWriter>> writers_;
|
std::vector<std::unique_ptr<IvfFileWriter>> writers_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -228,7 +238,8 @@ std::unique_ptr<VideoDecoder> VideoQualityTest::CreateVideoDecoder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<VideoEncoder> VideoQualityTest::CreateVideoEncoder(
|
std::unique_ptr<VideoEncoder> VideoQualityTest::CreateVideoEncoder(
|
||||||
const SdpVideoFormat& format) {
|
const SdpVideoFormat& format,
|
||||||
|
VideoAnalyzer* analyzer) {
|
||||||
std::unique_ptr<VideoEncoder> encoder;
|
std::unique_ptr<VideoEncoder> encoder;
|
||||||
if (format.name == "VP8") {
|
if (format.name == "VP8") {
|
||||||
encoder = absl::make_unique<VP8EncoderSimulcastProxy>(
|
encoder = absl::make_unique<VP8EncoderSimulcastProxy>(
|
||||||
@ -245,12 +256,17 @@ std::unique_ptr<VideoEncoder> VideoQualityTest::CreateVideoEncoder(
|
|||||||
sb << send_logs_++;
|
sb << send_logs_++;
|
||||||
std::string prefix =
|
std::string prefix =
|
||||||
params_.logging.encoded_frame_base_path + "." + sb.str() + ".send.";
|
params_.logging.encoded_frame_base_path + "." + sb.str() + ".send.";
|
||||||
encoder = absl::make_unique<FrameDumpingEncoder>(
|
encoder = absl::make_unique<QualityTestVideoEncoder>(
|
||||||
std::move(encoder), std::vector<rtc::PlatformFile>(
|
std::move(encoder), analyzer,
|
||||||
{rtc::CreatePlatformFile(prefix + "1.ivf"),
|
std::vector<rtc::PlatformFile>(
|
||||||
rtc::CreatePlatformFile(prefix + "2.ivf"),
|
{rtc::CreatePlatformFile(prefix + "1.ivf"),
|
||||||
rtc::CreatePlatformFile(prefix + "3.ivf")}));
|
rtc::CreatePlatformFile(prefix + "2.ivf"),
|
||||||
|
rtc::CreatePlatformFile(prefix + "3.ivf")}));
|
||||||
|
} else if (analyzer) {
|
||||||
|
encoder = absl::make_unique<QualityTestVideoEncoder>(
|
||||||
|
std::move(encoder), analyzer, std::vector<rtc::PlatformFile>());
|
||||||
}
|
}
|
||||||
|
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,8 +277,12 @@ VideoQualityTest::VideoQualityTest(
|
|||||||
return this->CreateVideoDecoder(format);
|
return this->CreateVideoDecoder(format);
|
||||||
}),
|
}),
|
||||||
video_encoder_factory_([this](const SdpVideoFormat& format) {
|
video_encoder_factory_([this](const SdpVideoFormat& format) {
|
||||||
return this->CreateVideoEncoder(format);
|
return this->CreateVideoEncoder(format, nullptr);
|
||||||
}),
|
}),
|
||||||
|
video_encoder_factory_with_analyzer_(
|
||||||
|
[this](const SdpVideoFormat& format) {
|
||||||
|
return this->CreateVideoEncoder(format, analyzer_.get());
|
||||||
|
}),
|
||||||
receive_logs_(0),
|
receive_logs_(0),
|
||||||
send_logs_(0),
|
send_logs_(0),
|
||||||
injection_components_(std::move(injection_components)) {
|
injection_components_(std::move(injection_components)) {
|
||||||
@ -594,7 +614,8 @@ void VideoQualityTest::SetupVideo(Transport* send_transport,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
video_send_configs_[video_idx].encoder_settings.encoder_factory =
|
video_send_configs_[video_idx].encoder_settings.encoder_factory =
|
||||||
&video_encoder_factory_;
|
(video_idx == 0) ? &video_encoder_factory_with_analyzer_
|
||||||
|
: &video_encoder_factory_;
|
||||||
|
|
||||||
video_send_configs_[video_idx].rtp.payload_name =
|
video_send_configs_[video_idx].rtp.payload_name =
|
||||||
params_.video[video_idx].codec;
|
params_.video[video_idx].codec;
|
||||||
@ -1043,7 +1064,6 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
|
|||||||
std::unique_ptr<test::LayerFilteringTransport> send_transport;
|
std::unique_ptr<test::LayerFilteringTransport> send_transport;
|
||||||
std::unique_ptr<test::DirectTransport> recv_transport;
|
std::unique_ptr<test::DirectTransport> recv_transport;
|
||||||
FILE* graph_data_output_file = nullptr;
|
FILE* graph_data_output_file = nullptr;
|
||||||
std::unique_ptr<VideoAnalyzer> analyzer;
|
|
||||||
|
|
||||||
params_ = params;
|
params_ = params;
|
||||||
// TODO(ivica): Merge with RunWithRenderer and use a flag / argument to
|
// TODO(ivica): Merge with RunWithRenderer and use a flag / argument to
|
||||||
@ -1100,7 +1120,7 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
|
|||||||
if (graph_title.empty())
|
if (graph_title.empty())
|
||||||
graph_title = VideoQualityTest::GenerateGraphTitle();
|
graph_title = VideoQualityTest::GenerateGraphTitle();
|
||||||
bool is_quick_test_enabled = field_trial::IsEnabled("WebRTC-QuickPerfTest");
|
bool is_quick_test_enabled = field_trial::IsEnabled("WebRTC-QuickPerfTest");
|
||||||
analyzer = absl::make_unique<VideoAnalyzer>(
|
analyzer_ = absl::make_unique<VideoAnalyzer>(
|
||||||
send_transport.get(), params_.analyzer.test_label,
|
send_transport.get(), params_.analyzer.test_label,
|
||||||
params_.analyzer.avg_psnr_threshold, params_.analyzer.avg_ssim_threshold,
|
params_.analyzer.avg_psnr_threshold, params_.analyzer.avg_ssim_threshold,
|
||||||
is_quick_test_enabled
|
is_quick_test_enabled
|
||||||
@ -1114,26 +1134,23 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
|
|||||||
is_quick_test_enabled, clock_, params_.logging.rtp_dump_name);
|
is_quick_test_enabled, clock_, params_.logging.rtp_dump_name);
|
||||||
|
|
||||||
task_queue_.SendTask([&]() {
|
task_queue_.SendTask([&]() {
|
||||||
analyzer->SetCall(sender_call_.get());
|
analyzer_->SetCall(sender_call_.get());
|
||||||
analyzer->SetReceiver(receiver_call_->Receiver());
|
analyzer_->SetReceiver(receiver_call_->Receiver());
|
||||||
send_transport->SetReceiver(analyzer.get());
|
send_transport->SetReceiver(analyzer_.get());
|
||||||
recv_transport->SetReceiver(sender_call_->Receiver());
|
recv_transport->SetReceiver(sender_call_->Receiver());
|
||||||
|
|
||||||
SetupVideo(analyzer.get(), recv_transport.get());
|
SetupVideo(analyzer_.get(), recv_transport.get());
|
||||||
SetupThumbnails(analyzer.get(), recv_transport.get());
|
SetupThumbnails(analyzer_.get(), recv_transport.get());
|
||||||
video_receive_configs_[params_.ss[0].selected_stream].renderer =
|
video_receive_configs_[params_.ss[0].selected_stream].renderer =
|
||||||
analyzer.get();
|
analyzer_.get();
|
||||||
GetVideoSendConfig()->pre_encode_callback = analyzer->pre_encode_proxy();
|
|
||||||
RTC_DCHECK(!GetVideoSendConfig()->post_encode_callback);
|
|
||||||
GetVideoSendConfig()->post_encode_callback = analyzer.get();
|
|
||||||
|
|
||||||
CreateFlexfecStreams();
|
CreateFlexfecStreams();
|
||||||
CreateVideoStreams();
|
CreateVideoStreams();
|
||||||
analyzer->SetSendStream(video_send_streams_[0]);
|
analyzer_->SetSendStream(video_send_streams_[0]);
|
||||||
if (video_receive_streams_.size() == 1)
|
if (video_receive_streams_.size() == 1)
|
||||||
analyzer->SetReceiveStream(video_receive_streams_[0]);
|
analyzer_->SetReceiveStream(video_receive_streams_[0]);
|
||||||
|
|
||||||
GetVideoSendStream()->SetSource(analyzer->OutputInterface(),
|
GetVideoSendStream()->SetSource(analyzer_->OutputInterface(),
|
||||||
degradation_preference_);
|
degradation_preference_);
|
||||||
SetupThumbnailCapturers(params_.call.num_thumbnails);
|
SetupThumbnailCapturers(params_.call.num_thumbnails);
|
||||||
for (size_t i = 0; i < thumbnail_send_streams_.size(); ++i) {
|
for (size_t i = 0; i < thumbnail_send_streams_.size(); ++i) {
|
||||||
@ -1143,7 +1160,8 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
|
|||||||
|
|
||||||
CreateCapturers();
|
CreateCapturers();
|
||||||
|
|
||||||
analyzer->SetSource(video_capturers_[0].get(), params_.ss[0].infer_streams);
|
analyzer_->SetSource(video_capturers_[0].get(),
|
||||||
|
params_.ss[0].infer_streams);
|
||||||
|
|
||||||
for (size_t video_idx = 1; video_idx < num_video_streams_; ++video_idx) {
|
for (size_t video_idx = 1; video_idx < num_video_streams_; ++video_idx) {
|
||||||
video_send_streams_[video_idx]->SetSource(
|
video_send_streams_[video_idx]->SetSource(
|
||||||
@ -1153,16 +1171,16 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
|
|||||||
if (params_.audio.enabled) {
|
if (params_.audio.enabled) {
|
||||||
SetupAudio(send_transport.get());
|
SetupAudio(send_transport.get());
|
||||||
StartAudioStreams();
|
StartAudioStreams();
|
||||||
analyzer->SetAudioReceiveStream(audio_receive_streams_[0]);
|
analyzer_->SetAudioReceiveStream(audio_receive_streams_[0]);
|
||||||
}
|
}
|
||||||
StartVideoStreams();
|
StartVideoStreams();
|
||||||
StartThumbnails();
|
StartThumbnails();
|
||||||
analyzer->StartMeasuringCpuProcessTime();
|
analyzer_->StartMeasuringCpuProcessTime();
|
||||||
StartVideoCapture();
|
StartVideoCapture();
|
||||||
StartThumbnailCapture();
|
StartThumbnailCapture();
|
||||||
});
|
});
|
||||||
|
|
||||||
analyzer->Wait();
|
analyzer_->Wait();
|
||||||
|
|
||||||
task_queue_.SendTask([&]() {
|
task_queue_.SendTask([&]() {
|
||||||
StopThumbnailCapture();
|
StopThumbnailCapture();
|
||||||
@ -1181,6 +1199,7 @@ void VideoQualityTest::RunWithAnalyzer(const Params& params) {
|
|||||||
|
|
||||||
DestroyCalls();
|
DestroyCalls();
|
||||||
});
|
});
|
||||||
|
analyzer_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rtc::scoped_refptr<AudioDeviceModule> VideoQualityTest::CreateAudioDevice() {
|
rtc::scoped_refptr<AudioDeviceModule> VideoQualityTest::CreateAudioDevice() {
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "test/call_test.h"
|
#include "test/call_test.h"
|
||||||
#include "test/frame_generator.h"
|
#include "test/frame_generator.h"
|
||||||
#include "test/layer_filtering_transport.h"
|
#include "test/layer_filtering_transport.h"
|
||||||
|
#include "video/video_analyzer.h"
|
||||||
#ifdef WEBRTC_WIN
|
#ifdef WEBRTC_WIN
|
||||||
#include "modules/audio_device/win/core_audio_utility_win.h"
|
#include "modules/audio_device/win/core_audio_utility_win.h"
|
||||||
#endif
|
#endif
|
||||||
@ -75,8 +76,8 @@ class VideoQualityTest :
|
|||||||
void SetupThumbnailCapturers(size_t num_thumbnail_streams);
|
void SetupThumbnailCapturers(size_t num_thumbnail_streams);
|
||||||
std::unique_ptr<VideoDecoder> CreateVideoDecoder(
|
std::unique_ptr<VideoDecoder> CreateVideoDecoder(
|
||||||
const SdpVideoFormat& format);
|
const SdpVideoFormat& format);
|
||||||
std::unique_ptr<VideoEncoder> CreateVideoEncoder(
|
std::unique_ptr<VideoEncoder> CreateVideoEncoder(const SdpVideoFormat& format,
|
||||||
const SdpVideoFormat& format);
|
VideoAnalyzer* analyzer);
|
||||||
void SetupVideo(Transport* send_transport, Transport* recv_transport);
|
void SetupVideo(Transport* send_transport, Transport* recv_transport);
|
||||||
void SetupThumbnails(Transport* send_transport, Transport* recv_transport);
|
void SetupThumbnails(Transport* send_transport, Transport* recv_transport);
|
||||||
void StartAudioStreams();
|
void StartAudioStreams();
|
||||||
@ -103,6 +104,7 @@ class VideoQualityTest :
|
|||||||
test::FunctionVideoDecoderFactory video_decoder_factory_;
|
test::FunctionVideoDecoderFactory video_decoder_factory_;
|
||||||
InternalDecoderFactory internal_decoder_factory_;
|
InternalDecoderFactory internal_decoder_factory_;
|
||||||
test::FunctionVideoEncoderFactory video_encoder_factory_;
|
test::FunctionVideoEncoderFactory video_encoder_factory_;
|
||||||
|
test::FunctionVideoEncoderFactory video_encoder_factory_with_analyzer_;
|
||||||
InternalEncoderFactory internal_encoder_factory_;
|
InternalEncoderFactory internal_encoder_factory_;
|
||||||
std::vector<VideoSendStream::Config> thumbnail_send_configs_;
|
std::vector<VideoSendStream::Config> thumbnail_send_configs_;
|
||||||
std::vector<VideoEncoderConfig> thumbnail_encoder_configs_;
|
std::vector<VideoEncoderConfig> thumbnail_encoder_configs_;
|
||||||
@ -116,6 +118,9 @@ class VideoQualityTest :
|
|||||||
Params params_;
|
Params params_;
|
||||||
std::unique_ptr<InjectionComponents> injection_components_;
|
std::unique_ptr<InjectionComponents> injection_components_;
|
||||||
|
|
||||||
|
// Set non-null when running with analyzer.
|
||||||
|
std::unique_ptr<VideoAnalyzer> analyzer_;
|
||||||
|
|
||||||
// Note: not same as similarly named member in CallTest. This is the number of
|
// Note: not same as similarly named member in CallTest. This is the number of
|
||||||
// separate send streams, the one in CallTest is the number of substreams for
|
// separate send streams, the one in CallTest is the number of substreams for
|
||||||
// a single send stream.
|
// a single send stream.
|
||||||
|
@ -563,17 +563,6 @@ EncodedImageCallback::Result VideoSendStreamImpl::OnEncodedImage(
|
|||||||
// Encoded is called on whatever thread the real encoder implementation run
|
// Encoded is called on whatever thread the real encoder implementation run
|
||||||
// on. In the case of hardware encoders, there might be several encoders
|
// on. In the case of hardware encoders, there might be several encoders
|
||||||
// running in parallel on different threads.
|
// running in parallel on different threads.
|
||||||
const size_t simulcast_idx =
|
|
||||||
(codec_specific_info->codecType != kVideoCodecVP9)
|
|
||||||
? encoded_image.SpatialIndex().value_or(0)
|
|
||||||
: 0;
|
|
||||||
if (config_->post_encode_callback) {
|
|
||||||
// TODO(nisse): Delete webrtc::EncodedFrame class, pass EncodedImage
|
|
||||||
// instead.
|
|
||||||
config_->post_encode_callback->EncodedFrameCallback(EncodedFrame(
|
|
||||||
encoded_image._buffer, encoded_image._length, encoded_image._frameType,
|
|
||||||
simulcast_idx, encoded_image.Timestamp()));
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
rtc::CritScope lock(&encoder_activity_crit_sect_);
|
rtc::CritScope lock(&encoder_activity_crit_sect_);
|
||||||
if (check_encoder_activity_task_)
|
if (check_encoder_activity_task_)
|
||||||
|
Reference in New Issue
Block a user