Upstreaming browser/ui/uikit_ui_util from iOS.
[chromium-blink-merge.git] / remoting / test / video_frame_writer.cc
blob2cee01c443833c5ab8829a20ad9fd195e27e45d6
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/test/video_frame_writer.h"
7 #include <vector>
9 #include "base/files/file_path.h"
10 #include "base/files/file_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
13 #include "ui/gfx/codec/png_codec.h"
14 #include "ui/gfx/geometry/size.h"
16 namespace {
18 const base::FilePath::CharType kFrameFileName[] =
19 FILE_PATH_LITERAL("frame.png");
20 const base::FilePath::CharType kRemotingFolder[] =
21 FILE_PATH_LITERAL("remoting");
22 const base::FilePath::CharType kDumpFrameFolder[] =
23 FILE_PATH_LITERAL("dumped_images");
25 // Used to create a unique folder path.
26 const char kDateAndTimeFormatString[] = "%d-%d-%d_%d-%d-%d";
28 } // namespace
30 namespace remoting {
31 namespace test {
33 VideoFrameWriter::VideoFrameWriter()
34 : instance_creation_time_(base::Time::Now()),
35 frame_name_unique_number_(0) {}
37 VideoFrameWriter::~VideoFrameWriter() {}
39 void VideoFrameWriter::WriteFrameToPath(const webrtc::DesktopFrame& frame,
40 const base::FilePath& image_path) {
41 unsigned char* frame_data = reinterpret_cast<unsigned char*>(frame.data());
42 std::vector<unsigned char> png_encoded_data;
44 if (!gfx::PNGCodec::Encode(
45 frame_data, gfx::PNGCodec::FORMAT_BGRA,
46 gfx::Size(frame.size().width(), frame.size().height()),
47 frame.stride(), true, std::vector<gfx::PNGCodec::Comment>(),
48 &png_encoded_data)) {
49 LOG(WARNING) << "Failed to encode frame to PNG file";
50 return;
53 // Dump contents (unsigned chars) to a file as a sequence of chars.
54 int write_bytes = base::WriteFile(
55 image_path, reinterpret_cast<char*>(&*png_encoded_data.begin()),
56 static_cast<int>(png_encoded_data.size()));
57 if (write_bytes != static_cast<int>(png_encoded_data.size())) {
58 LOG(WARNING) << "Failed to write frame to disk";
62 // Save video frame to path named with the |instance_creation_time|.
63 void VideoFrameWriter::WriteFrameToDefaultPath(
64 const webrtc::DesktopFrame& frame) {
65 base::FilePath dump_frame_file_path;
66 if (!GetTempDir(&dump_frame_file_path)) {
67 LOG(WARNING) << "Failed to retrieve temporary directory path";
68 return;
71 dump_frame_file_path = dump_frame_file_path.Append(kRemotingFolder);
72 dump_frame_file_path = dump_frame_file_path.Append(kDumpFrameFolder);
73 if (!CreateDirectoryIfNotExists(dump_frame_file_path)) {
74 return;
77 // Create a sub-folder using date and time to identify a particular test run.
78 dump_frame_file_path = AppendCreationDateAndTime(dump_frame_file_path);
79 if (!CreateDirectoryIfNotExists(dump_frame_file_path)) {
80 return;
83 dump_frame_file_path = dump_frame_file_path.Append(kFrameFileName);
85 dump_frame_file_path = dump_frame_file_path.InsertBeforeExtensionASCII(
86 base::StringPrintf("(%d)", ++frame_name_unique_number_));
88 LOG(INFO) << "Video frame dumped to: " << dump_frame_file_path.value();
90 WriteFrameToPath(frame, dump_frame_file_path);
93 void VideoFrameWriter::HighlightRectInFrame(webrtc::DesktopFrame* frame,
94 const webrtc::DesktopRect& rect) {
95 if (rect.left() < 0 || rect.top() < 0 ||
96 rect.right() >= frame->size().width() ||
97 rect.bottom() >= frame->size().height()) {
98 LOG(ERROR) << "Highlight rect lies outside of the frame.";
99 return;
102 // Draw vertical borders.
103 for (int y = rect.top(); y <= rect.bottom(); ++y) {
104 ShiftPixelColor(frame, rect.left(), y, 128);
105 ShiftPixelColor(frame, rect.right(), y, 128);
108 // Draw horizontal borders.
109 for (int x = rect.left(); x <= rect.right(); ++x) {
110 ShiftPixelColor(frame, x, rect.top(), 128);
111 ShiftPixelColor(frame, x, rect.bottom(), 128);
115 base::FilePath VideoFrameWriter::AppendCreationDateAndTime(
116 const base::FilePath& file_path) {
117 base::Time::Exploded exploded_time;
118 instance_creation_time_.LocalExplode(&exploded_time);
120 int year = exploded_time.year;
121 int month = exploded_time.month;
122 int day = exploded_time.day_of_month;
123 int hour = exploded_time.hour;
124 int minute = exploded_time.minute;
125 int second = exploded_time.second;
127 return file_path.AppendASCII(base::StringPrintf(
128 kDateAndTimeFormatString, year, month, day, hour, minute, second));
131 bool VideoFrameWriter::CreateDirectoryIfNotExists(
132 const base::FilePath& file_path) {
133 if (!base::DirectoryExists(file_path) && !base::CreateDirectory(file_path)) {
134 LOG(WARNING) << "Failed to create directory: " << file_path.value();
135 return false;
137 return true;
140 void VideoFrameWriter::ShiftPixelColor(webrtc::DesktopFrame* frame,
141 int x,
142 int y,
143 int shift_amount) {
144 uint8_t* frame_pos = frame->data() + y * frame->stride() +
145 x * webrtc::DesktopFrame::kBytesPerPixel;
146 frame_pos[2] = frame_pos[2] + shift_amount;
147 frame_pos[1] = frame_pos[1] + shift_amount;
148 frame_pos[0] = frame_pos[0] + shift_amount;
151 } // namespace test
152 } // namespace remoting