diff --git a/webrtc/test/BUILD.gn b/webrtc/test/BUILD.gn index b4e5f4bfb1..2db6120189 100644 --- a/webrtc/test/BUILD.gn +++ b/webrtc/test/BUILD.gn @@ -207,7 +207,6 @@ if (!build_with_chromium) { ":test_support", ":video_test_common", "..:webrtc_common", - "../api:video_frame_api", "../common_video", "../rtc_base:rtc_base_approved", "../system_wrappers", @@ -216,11 +215,6 @@ if (!build_with_chromium) { "//third_party/gflags", ] - if (!is_ios) { - deps += [ "//third_party:jpeg" ] - sources += [ "testsupport/jpeg_frame_writer.cc" ] - } - public_deps = [ ":fileutils", ] diff --git a/webrtc/test/DEPS b/webrtc/test/DEPS index 9d4e6afdf0..1d44a0742e 100644 --- a/webrtc/test/DEPS +++ b/webrtc/test/DEPS @@ -1,6 +1,4 @@ include_rules = [ - "+third_party/libjpeg", - "+third_party/libjpeg_turbo", "+webrtc/base", "+webrtc/call", "+webrtc/common_audio", diff --git a/webrtc/test/testsupport/frame_writer.h b/webrtc/test/testsupport/frame_writer.h index 148f23338c..76298498ac 100644 --- a/webrtc/test/testsupport/frame_writer.h +++ b/webrtc/test/testsupport/frame_writer.h @@ -15,7 +15,6 @@ #include -#include "webrtc/api/video/video_frame.h" #include "webrtc/typedefs.h" namespace webrtc { @@ -83,20 +82,6 @@ class Y4mFrameWriterImpl : public YuvFrameWriterImpl { const int frame_rate_; }; -// LibJpeg is not available on iOS -#if !defined(is_ios) -class JpegFrameWriter { - public: - JpegFrameWriter(const std::string &output_filename); - bool WriteFrame(const VideoFrame& input_frame, int quality); - - private: - bool frame_written_; - const std::string output_filename_; - FILE* output_file_; -}; -#endif - } // namespace test } // namespace webrtc diff --git a/webrtc/test/testsupport/jpeg_frame_writer.cc b/webrtc/test/testsupport/jpeg_frame_writer.cc deleted file mode 100644 index 6e1caa1bcd..0000000000 --- a/webrtc/test/testsupport/jpeg_frame_writer.cc +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2017 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 - - -#include "webrtc/common_types.h" -#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h" -#include "webrtc/rtc_base/checks.h" -#include "webrtc/rtc_base/logging.h" -#include "webrtc/test/testsupport/frame_writer.h" - -extern "C" { -#if defined(USE_SYSTEM_LIBJPEG) -#include -#elif defined(USE_LIBJPEG_TURBO) -#include "third_party/libjpeg_turbo/jpeglib.h" -#else -#include "third_party/libjpeg/jpeglib.h" -#endif -} - -namespace webrtc { -namespace test { - -JpegFrameWriter::JpegFrameWriter(const std::string &output_filename) - : frame_written_(false), - output_filename_(output_filename), - output_file_(nullptr) {} - -bool JpegFrameWriter::WriteFrame(const VideoFrame& input_frame, int quality) { - RTC_CHECK(!frame_written_) << "Only a single frame can be saved to Jpeg."; - const int kColorPlanes = 3; // R, G and B. - size_t rgb_len = input_frame.height() * input_frame.width() * kColorPlanes; - std::unique_ptr rgb_buf(new uint8_t[rgb_len]); - - // kRGB24 actually corresponds to FourCC 24BG which is 24-bit BGR. - if (ConvertFromI420(input_frame, VideoType::kRGB24, 0, rgb_buf.get()) < 0) { - LOG(LS_ERROR) << "Could not convert input frame to RGB."; - return false; - } - output_file_ = fopen(output_filename_.c_str(), "wb"); - if (!output_file_) { - LOG(LS_ERROR) << "Couldn't open file to write jpeg frame to:" << - output_filename_; - return false; - } - - // Invoking LIBJPEG - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - JSAMPROW row_pointer[1]; - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - - jpeg_stdio_dest(&cinfo, output_file_); - - cinfo.image_width = input_frame.width(); - cinfo.image_height = input_frame.height(); - cinfo.input_components = kColorPlanes; - cinfo.in_color_space = JCS_EXT_BGR; - jpeg_set_defaults(&cinfo); - jpeg_set_quality(&cinfo, quality, TRUE); - - jpeg_start_compress(&cinfo, TRUE); - int row_stride = input_frame.width() * kColorPlanes; - while (cinfo.next_scanline < cinfo.image_height) { - row_pointer[0] = &rgb_buf.get()[cinfo.next_scanline * row_stride]; - jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - - jpeg_finish_compress(&cinfo); - jpeg_destroy_compress(&cinfo); - fclose(output_file_); - - frame_written_ = true; - return true; -} - -} // namespace test -} // namespace webrtc diff --git a/webrtc/test/testsupport/test_output.cc b/webrtc/test/testsupport/test_output.cc index 9bb1847199..aea5110d97 100644 --- a/webrtc/test/testsupport/test_output.cc +++ b/webrtc/test/testsupport/test_output.cc @@ -12,36 +12,32 @@ #include -#include "webrtc/rtc_base/flags.h" +#include "gflags/gflags.h" #include "webrtc/rtc_base/file.h" #include "webrtc/rtc_base/logging.h" #include "webrtc/rtc_base/pathutils.h" #include "webrtc/test/testsupport/fileutils.h" -namespace { -const std::string kDefaultOutputPath = webrtc::test::OutputPath(); -} - DEFINE_string(test_output_dir, - kDefaultOutputPath.c_str(), + webrtc::test::OutputPath(), "The output folder where test output should be saved."); namespace webrtc { namespace test { bool GetTestOutputDir(std::string* out_dir) { - if (strlen(FLAG_test_output_dir) == 0) { + if (FLAGS_test_output_dir.empty()) { LOG(LS_WARNING) << "No test_out_dir defined."; return false; } - *out_dir = FLAG_test_output_dir; + *out_dir = FLAGS_test_output_dir; return true; } bool WriteToTestOutput(const char* filename, const uint8_t* buffer, size_t length) { - if (strlen(FLAG_test_output_dir) == 0) { + if (FLAGS_test_output_dir.empty()) { LOG(LS_WARNING) << "No test_out_dir defined."; return false; } @@ -52,7 +48,7 @@ bool WriteToTestOutput(const char* filename, } rtc::File output = - rtc::File::Create(rtc::Pathname(FLAG_test_output_dir, filename)); + rtc::File::Create(rtc::Pathname(FLAGS_test_output_dir, filename)); return output.IsOpen() && output.Write(buffer, length) == length; } diff --git a/webrtc/test/testsupport/test_output_unittest.cc b/webrtc/test/testsupport/test_output_unittest.cc index 3d489fe53b..511ce6f750 100644 --- a/webrtc/test/testsupport/test_output_unittest.cc +++ b/webrtc/test/testsupport/test_output_unittest.cc @@ -14,7 +14,7 @@ #include -#include "webrtc/rtc_base/flags.h" +#include "gflags/gflags.h" #include "webrtc/rtc_base/file.h" #include "webrtc/rtc_base/pathutils.h" #include "webrtc/rtc_base/platform_file.h" @@ -26,10 +26,10 @@ namespace webrtc { namespace test { TEST(IsolatedOutputTest, ShouldRejectInvalidIsolatedOutDir) { - const char* backup = FLAG_test_output_dir; - FLAG_test_output_dir = ""; + std::string backup = FLAGS_test_output_dir; + FLAGS_test_output_dir = ""; ASSERT_FALSE(WriteToTestOutput("a-file", "some-contents")); - FLAG_test_output_dir = backup; + FLAGS_test_output_dir = backup; } TEST(IsolatedOutputTest, ShouldRejectInvalidFileName) { @@ -42,7 +42,7 @@ TEST(IsolatedOutputTest, ShouldBeAbleToWriteContent) { const char* filename = "a-file"; const char* content = "some-contents"; if (WriteToTestOutput(filename, content)) { - rtc::Pathname out_file(FLAG_test_output_dir, filename); + rtc::Pathname out_file(FLAGS_test_output_dir, filename); rtc::File input = rtc::File::Open(out_file); EXPECT_TRUE(input.IsOpen()); EXPECT_TRUE(input.Seek(0)); diff --git a/webrtc/video/BUILD.gn b/webrtc/video/BUILD.gn index b3a376ccdd..08abe685dc 100644 --- a/webrtc/video/BUILD.gn +++ b/webrtc/video/BUILD.gn @@ -111,7 +111,6 @@ if (rtc_include_tests) { "../test:test_renderer", "../test:test_renderer", "../test:test_support", - "../test:test_support_test_output", "../test:video_test_common", "../test:video_test_common", "../test:video_test_support", diff --git a/webrtc/video/video_quality_test.cc b/webrtc/video/video_quality_test.cc index b0d82b83ed..6ad64bc33f 100644 --- a/webrtc/video/video_quality_test.cc +++ b/webrtc/video/video_quality_test.cc @@ -33,12 +33,9 @@ #include "webrtc/rtc_base/checks.h" #include "webrtc/rtc_base/cpu_time.h" #include "webrtc/rtc_base/event.h" -#include "webrtc/rtc_base/flags.h" #include "webrtc/rtc_base/format_macros.h" -#include "webrtc/rtc_base/logging.h" #include "webrtc/rtc_base/memory_usage.h" #include "webrtc/rtc_base/optional.h" -#include "webrtc/rtc_base/pathutils.h" #include "webrtc/rtc_base/platform_file.h" #include "webrtc/rtc_base/timeutils.h" #include "webrtc/system_wrappers/include/cpu_info.h" @@ -49,18 +46,12 @@ #include "webrtc/test/statistics.h" #include "webrtc/test/testsupport/fileutils.h" #include "webrtc/test/testsupport/frame_writer.h" -#include "webrtc/test/testsupport/test_output.h" #include "webrtc/test/vcm_capturer.h" #include "webrtc/test/video_renderer.h" #include "webrtc/voice_engine/include/voe_base.h" #include "webrtc/test/rtp_file_writer.h" -DEFINE_bool(save_worst_frame, - false, - "Enable saving a frame with the lowest PSNR to a jpeg file in the " - "test_output_dir"); - namespace { constexpr int kSendStatsPollingIntervalMs = 1000; @@ -833,21 +824,27 @@ class VideoAnalyzer : public PacketReceiver, // will be flaky. PrintResult("memory_usage", memory_usage_, " bytes"); #endif + // TODO(ilnik): enable frame writing for android, once jpeg frame writer + // is implemented. - // LibJpeg is not available on iOS. -#if !defined(WEBRTC_IOS) - // Saving only the worst frame for manual analysis. Intention here is to - // only detect video corruptions and not to track picture quality. Thus, - // jpeg is used here. - if (FLAG_save_worst_frame && worst_frame_) { - std::string output_dir; - test::GetTestOutputDir(&output_dir); - std::string output_path = - rtc::Pathname(output_dir, test_label_ + ".jpg").pathname(); - LOG(LS_INFO) << "Saving worst frame to " << output_path; - test::JpegFrameWriter frame_writer(output_path); - RTC_CHECK(frame_writer.WriteFrame(worst_frame_->frame, - 100 /*best quality*/)); +#if !defined(WEBRTC_ANDROID) + if (worst_frame_) { + test::Y4mFrameWriterImpl frame_writer(test_label_ + ".y4m", + worst_frame_->frame.width(), + worst_frame_->frame.height(), 1); + bool res = frame_writer.Init(); + RTC_DCHECK(res); + size_t length = + CalcBufferSize(VideoType::kI420, worst_frame_->frame.width(), + worst_frame_->frame.height()); + rtc::Buffer extracted_buffer(length); + size_t extracted_length = + ExtractBuffer(worst_frame_->frame.video_frame_buffer()->ToI420(), + length, extracted_buffer.data()); + RTC_DCHECK_EQ(extracted_length, frame_writer.FrameLength()); + res = frame_writer.WriteFrame(extracted_buffer.data()); + RTC_DCHECK(res); + frame_writer.Close(); } #endif