1 /*
2 * Copyright (c) 2019 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "test/testsupport/video_frame_writer.h"
12
13 #include <cmath>
14 #include <cstdlib>
15 #include <limits>
16 #include <memory>
17 #include <utility>
18
19 #include "api/scoped_refptr.h"
20 #include "api/video/i420_buffer.h"
21 #include "common_video/libyuv/include/webrtc_libyuv.h"
22 #include "rtc_base/logging.h"
23
24 namespace webrtc {
25 namespace test {
26 namespace {
27
ExtractI420BufferWithSize(const VideoFrame & frame,int width,int height)28 rtc::Buffer ExtractI420BufferWithSize(const VideoFrame& frame,
29 int width,
30 int height) {
31 if (frame.width() != width || frame.height() != height) {
32 RTC_CHECK_LE(std::abs(static_cast<double>(width) / height -
33 static_cast<double>(frame.width()) / frame.height()),
34 2 * std::numeric_limits<double>::epsilon());
35 // Same aspect ratio, no cropping needed.
36 rtc::scoped_refptr<I420Buffer> scaled(I420Buffer::Create(width, height));
37 scaled->ScaleFrom(*frame.video_frame_buffer()->ToI420());
38
39 size_t length =
40 CalcBufferSize(VideoType::kI420, scaled->width(), scaled->height());
41 rtc::Buffer buffer(length);
42 RTC_CHECK_NE(ExtractBuffer(scaled, length, buffer.data()), -1);
43 return buffer;
44 }
45
46 // No resize.
47 size_t length =
48 CalcBufferSize(VideoType::kI420, frame.width(), frame.height());
49 rtc::Buffer buffer(length);
50 RTC_CHECK_NE(ExtractBuffer(frame, length, buffer.data()), -1);
51 return buffer;
52 }
53
54 } // namespace
55
Y4mVideoFrameWriterImpl(std::string output_file_name,int width,int height,int fps)56 Y4mVideoFrameWriterImpl::Y4mVideoFrameWriterImpl(std::string output_file_name,
57 int width,
58 int height,
59 int fps)
60 // We will move string here to prevent extra copy. We won't use const ref
61 // to not corrupt caller variable with move and don't assume that caller's
62 // variable won't be destructed before writer.
63 : width_(width),
64 height_(height),
65 frame_writer_(
66 std::make_unique<Y4mFrameWriterImpl>(std::move(output_file_name),
67 width_,
68 height_,
69 fps)) {
70 // Init underlying frame writer and ensure that it is operational.
71 RTC_CHECK(frame_writer_->Init());
72 }
73
WriteFrame(const webrtc::VideoFrame & frame)74 bool Y4mVideoFrameWriterImpl::WriteFrame(const webrtc::VideoFrame& frame) {
75 rtc::Buffer frame_buffer = ExtractI420BufferWithSize(frame, width_, height_);
76 RTC_CHECK_EQ(frame_buffer.size(), frame_writer_->FrameLength());
77 return frame_writer_->WriteFrame(frame_buffer.data());
78 }
79
Close()80 void Y4mVideoFrameWriterImpl::Close() {
81 frame_writer_->Close();
82 }
83
YuvVideoFrameWriterImpl(std::string output_file_name,int width,int height)84 YuvVideoFrameWriterImpl::YuvVideoFrameWriterImpl(std::string output_file_name,
85 int width,
86 int height)
87 // We will move string here to prevent extra copy. We won't use const ref
88 // to not corrupt caller variable with move and don't assume that caller's
89 // variable won't be destructed before writer.
90 : width_(width),
91 height_(height),
92 frame_writer_(
93 std::make_unique<YuvFrameWriterImpl>(std::move(output_file_name),
94 width_,
95 height_)) {
96 // Init underlying frame writer and ensure that it is operational.
97 RTC_CHECK(frame_writer_->Init());
98 }
99
WriteFrame(const webrtc::VideoFrame & frame)100 bool YuvVideoFrameWriterImpl::WriteFrame(const webrtc::VideoFrame& frame) {
101 rtc::Buffer frame_buffer = ExtractI420BufferWithSize(frame, width_, height_);
102 RTC_CHECK_EQ(frame_buffer.size(), frame_writer_->FrameLength());
103 return frame_writer_->WriteFrame(frame_buffer.data());
104 }
105
Close()106 void YuvVideoFrameWriterImpl::Close() {
107 frame_writer_->Close();
108 }
109
110 } // namespace test
111 } // namespace webrtc
112