OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright (c) 2012 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 #include <stdio.h> | |
11 #include <stdlib.h> | |
12 #include <sys/stat.h> | |
13 | |
14 #include <iomanip> | |
15 #include <sstream> | |
16 | |
17 #include "webrtc/tools/converter/converter.h" | |
18 | |
19 #ifdef WIN32 | |
20 #define SEPARATOR '\\' | |
21 #define STAT _stat | |
22 #else | |
23 #define SEPARATOR '/' | |
24 #define STAT stat | |
25 #endif | |
26 | |
27 namespace webrtc { | |
28 namespace test { | |
29 | |
30 Converter::Converter(int width, int height) | |
31 : width_(width), | |
32 height_(height) { | |
33 } | |
34 | |
35 bool Converter::ConvertRGBAToI420Video(std::string frames_dir, | |
36 std::string output_file_name, | |
37 bool delete_frames) { | |
38 FILE* output_file = fopen(output_file_name.c_str(), "wb"); | |
39 | |
40 // Open output file in append mode. | |
41 if (output_file == NULL) { | |
42 fprintf(stderr, "Couldn't open input file for reading: %s\n", | |
43 output_file_name.c_str()); | |
44 return false; | |
45 } | |
46 | |
47 int input_frame_size = InputFrameSize(); | |
48 uint8_t* rgba_buffer = new uint8_t[input_frame_size]; | |
49 int y_plane_size = YPlaneSize(); | |
50 uint8_t* dst_y = new uint8_t[y_plane_size]; | |
51 int u_plane_size = UPlaneSize(); | |
52 uint8_t* dst_u = new uint8_t[u_plane_size]; | |
53 int v_plane_size = VPlaneSize(); | |
54 uint8_t* dst_v = new uint8_t[v_plane_size]; | |
55 | |
56 int counter = 0; // Counter to form frame names. | |
57 bool success = false; // Is conversion successful. | |
58 | |
59 while (true) { | |
60 std::string file_name = FormFrameName(4, counter); | |
61 // Get full path file name. | |
62 std::string input_file_name = FindFullFileName(frames_dir, file_name); | |
63 | |
64 if (FileExists(input_file_name)) { | |
65 ++counter; // Update counter for the next round. | |
66 } else { | |
67 fprintf(stdout, "Reached end of frames list\n"); | |
68 break; | |
69 } | |
70 | |
71 // Read the RGBA frame into rgba_buffer. | |
72 ReadRGBAFrame(input_file_name.c_str(), input_frame_size, rgba_buffer); | |
73 | |
74 // Delete the input frame. | |
75 if (delete_frames) { | |
76 if (remove(input_file_name.c_str()) != 0) { | |
77 fprintf(stderr, "Cannot delete file %s\n", input_file_name.c_str()); | |
78 } | |
79 } | |
80 | |
81 // Convert to I420 frame. | |
82 libyuv::ABGRToI420(rgba_buffer, SrcStrideFrame(), | |
83 dst_y, DstStrideY(), | |
84 dst_u, DstStrideU(), | |
85 dst_v, DstStrideV(), | |
86 width_, height_); | |
87 | |
88 // Add the I420 frame to the YUV video file. | |
89 success = AddYUVToFile(dst_y, y_plane_size, dst_u, u_plane_size, | |
90 dst_v, v_plane_size, output_file); | |
91 | |
92 | |
93 if (!success) { | |
94 fprintf(stderr, "LibYUV error during RGBA to I420 frame conversion\n"); | |
95 break; | |
96 } | |
97 } | |
98 | |
99 delete[] rgba_buffer; | |
100 delete[] dst_y; | |
101 delete[] dst_u; | |
102 delete[] dst_v; | |
103 | |
104 fclose(output_file); | |
105 | |
106 return success; | |
107 } | |
108 | |
109 bool Converter::AddYUVToFile(uint8_t* y_plane, | |
110 int y_plane_size, | |
111 uint8_t* u_plane, | |
112 int u_plane_size, | |
113 uint8_t* v_plane, | |
114 int v_plane_size, | |
115 FILE* output_file) { | |
116 bool success = AddYUVPlaneToFile(y_plane, y_plane_size, output_file) && | |
117 AddYUVPlaneToFile(u_plane, u_plane_size, output_file) && | |
118 AddYUVPlaneToFile(v_plane, v_plane_size, output_file); | |
119 return success; | |
120 } | |
121 | |
122 bool Converter::AddYUVPlaneToFile(uint8_t* yuv_plane, | |
123 int yuv_plane_size, | |
124 FILE* file) { | |
125 size_t bytes_written = fwrite(yuv_plane, 1, yuv_plane_size, file); | |
126 | |
127 if (bytes_written != static_cast<size_t>(yuv_plane_size)) { | |
128 fprintf(stderr, "Number of bytes written (%d) doesn't match size of y plane" | |
129 " (%d)\n", static_cast<int>(bytes_written), yuv_plane_size); | |
130 return false; | |
131 } | |
132 return true; | |
133 } | |
134 | |
135 bool Converter::ReadRGBAFrame(const char* input_file_name, int input_frame_size, | |
136 unsigned char* buffer) { | |
137 FILE* input_file = fopen(input_file_name, "rb"); | |
138 if (input_file == NULL) { | |
139 fprintf(stderr, "Couldn't open input file for reading: %s\n", | |
140 input_file_name); | |
141 return false; | |
142 } | |
143 | |
144 size_t nbr_read = fread(buffer, 1, input_frame_size, input_file); | |
145 fclose(input_file); | |
146 | |
147 if (nbr_read != static_cast<size_t>(input_frame_size)) { | |
148 fprintf(stderr, "Error reading from input file: %s\n", input_file_name); | |
149 return false; | |
150 } | |
151 | |
152 return true; | |
153 } | |
154 | |
155 std::string Converter::FindFullFileName(std::string dir_name, | |
156 std::string file_name) { | |
157 return dir_name + SEPARATOR + file_name; | |
158 } | |
159 | |
160 bool Converter:: FileExists(std::string file_name_to_check) { | |
161 struct STAT file_info; | |
162 int result = STAT(file_name_to_check.c_str(), &file_info); | |
163 return (result == 0); | |
164 } | |
165 | |
166 std::string Converter::FormFrameName(int width, int number) { | |
167 std::stringstream tmp; | |
168 | |
169 // Zero-pad number to a string. | |
170 tmp << std::setfill('0') << std::setw(width) << number; | |
171 | |
172 return "frame_" + tmp.str(); | |
173 } | |
174 | |
175 } // namespace test | |
176 } // namespace webrtc | |
OLD | NEW |