• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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