summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/testsupport/y4m_frame_reader.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/test/testsupport/y4m_frame_reader.cc')
-rw-r--r--third_party/libwebrtc/test/testsupport/y4m_frame_reader.cc92
1 files changed, 92 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/testsupport/y4m_frame_reader.cc b/third_party/libwebrtc/test/testsupport/y4m_frame_reader.cc
new file mode 100644
index 0000000000..72fb9b5188
--- /dev/null
+++ b/third_party/libwebrtc/test/testsupport/y4m_frame_reader.cc
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2018 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 <stdio.h>
+
+#include <string>
+
+#include "api/scoped_refptr.h"
+#include "api/video/i420_buffer.h"
+#include "common_video/libyuv/include/webrtc_libyuv.h"
+#include "rtc_base/logging.h"
+#include "rtc_base/strings/string_builder.h"
+#include "test/testsupport/file_utils.h"
+#include "test/testsupport/frame_reader.h"
+
+namespace webrtc {
+namespace test {
+namespace {
+constexpr int kFrameHeaderSize = 6; // "FRAME\n"
+} // namespace
+
+void ParseY4mHeader(std::string filepath,
+ Resolution* resolution,
+ int* header_size) {
+ FILE* file = fopen(filepath.c_str(), "r");
+ RTC_CHECK(file != NULL) << "Cannot open " << filepath;
+
+ // Length of Y4M header is technically unlimited due to the comment tag 'X'.
+ char h[1024];
+ RTC_CHECK(fgets(h, sizeof(h), file) != NULL)
+ << "File " << filepath << " is too small";
+ fclose(file);
+
+ RTC_CHECK(sscanf(h, "YUV4MPEG2 W%d H%d", &resolution->width,
+ &resolution->height) == 2)
+ << filepath << " is not a valid Y4M file";
+
+ RTC_CHECK_GT(resolution->width, 0) << "Width must be positive";
+ RTC_CHECK_GT(resolution->height, 0) << "Height must be positive";
+
+ *header_size = strcspn(h, "\n") + 1;
+ RTC_CHECK(static_cast<unsigned>(*header_size) < sizeof(h))
+ << filepath << " has unexpectedly large header";
+}
+
+Y4mFrameReaderImpl::Y4mFrameReaderImpl(std::string filepath,
+ RepeatMode repeat_mode)
+ : YuvFrameReaderImpl(filepath, Resolution(), repeat_mode) {}
+
+void Y4mFrameReaderImpl::Init() {
+ file_ = fopen(filepath_.c_str(), "rb");
+ RTC_CHECK(file_ != nullptr) << "Cannot open " << filepath_;
+
+ ParseY4mHeader(filepath_, &resolution_, &header_size_bytes_);
+ frame_size_bytes_ =
+ CalcBufferSize(VideoType::kI420, resolution_.width, resolution_.height);
+ frame_size_bytes_ += kFrameHeaderSize;
+
+ size_t file_size_bytes = GetFileSize(filepath_);
+ RTC_CHECK_GT(file_size_bytes, 0u) << "File " << filepath_ << " is empty";
+ RTC_CHECK_GT(file_size_bytes, header_size_bytes_)
+ << "File " << filepath_ << " is too small";
+
+ num_frames_ = static_cast<int>((file_size_bytes - header_size_bytes_) /
+ frame_size_bytes_);
+ RTC_CHECK_GT(num_frames_, 0u) << "File " << filepath_ << " is too small";
+ header_size_bytes_ += kFrameHeaderSize;
+}
+
+std::unique_ptr<FrameReader> CreateY4mFrameReader(std::string filepath) {
+ return CreateY4mFrameReader(filepath,
+ YuvFrameReaderImpl::RepeatMode::kSingle);
+}
+
+std::unique_ptr<FrameReader> CreateY4mFrameReader(
+ std::string filepath,
+ YuvFrameReaderImpl::RepeatMode repeat_mode) {
+ Y4mFrameReaderImpl* frame_reader =
+ new Y4mFrameReaderImpl(filepath, repeat_mode);
+ frame_reader->Init();
+ return std::unique_ptr<FrameReader>(frame_reader);
+}
+
+} // namespace test
+} // namespace webrtc