diff options
Diffstat (limited to 'third_party/libwebrtc/rtc_tools/converter/converter.cc')
-rw-r--r-- | third_party/libwebrtc/rtc_tools/converter/converter.cc | 175 |
1 files changed, 175 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_tools/converter/converter.cc b/third_party/libwebrtc/rtc_tools/converter/converter.cc new file mode 100644 index 0000000000..ca5eb26703 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/converter/converter.cc @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2012 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 "rtc_tools/converter/converter.h" + +#include <stdio.h> +#include <sys/stat.h> + +#include <iomanip> +#include <sstream> + +#include "third_party/libyuv/include/libyuv/compare.h" +#include "third_party/libyuv/include/libyuv/convert.h" + +#ifdef WIN32 +#define SEPARATOR '\\' +#define STAT _stat +#else +#define SEPARATOR '/' +#define STAT stat +#endif + +namespace webrtc { +namespace test { + +Converter::Converter(int width, int height) : width_(width), height_(height) {} + +bool Converter::ConvertRGBAToI420Video(std::string frames_dir, + std::string output_file_name, + bool delete_frames) { + FILE* output_file = fopen(output_file_name.c_str(), "wb"); + + // Open output file in append mode. + if (output_file == NULL) { + fprintf(stderr, "Couldn't open input file for reading: %s\n", + output_file_name.c_str()); + return false; + } + + int input_frame_size = InputFrameSize(); + uint8_t* rgba_buffer = new uint8_t[input_frame_size]; + int y_plane_size = YPlaneSize(); + uint8_t* dst_y = new uint8_t[y_plane_size]; + int u_plane_size = UPlaneSize(); + uint8_t* dst_u = new uint8_t[u_plane_size]; + int v_plane_size = VPlaneSize(); + uint8_t* dst_v = new uint8_t[v_plane_size]; + + int counter = 0; // Counter to form frame names. + bool success = false; // Is conversion successful. + + while (true) { + std::string file_name = FormFrameName(4, counter); + // Get full path file name. + std::string input_file_name = FindFullFileName(frames_dir, file_name); + + if (FileExists(input_file_name)) { + ++counter; // Update counter for the next round. + } else { + fprintf(stdout, "Reached end of frames list\n"); + break; + } + + // Read the RGBA frame into rgba_buffer. + ReadRGBAFrame(input_file_name.c_str(), input_frame_size, rgba_buffer); + + // Delete the input frame. + if (delete_frames) { + if (remove(input_file_name.c_str()) != 0) { + fprintf(stderr, "Cannot delete file %s\n", input_file_name.c_str()); + } + } + + // Convert to I420 frame. + libyuv::ABGRToI420(rgba_buffer, SrcStrideFrame(), dst_y, DstStrideY(), + dst_u, DstStrideU(), dst_v, DstStrideV(), width_, + height_); + + // Add the I420 frame to the YUV video file. + success = AddYUVToFile(dst_y, y_plane_size, dst_u, u_plane_size, dst_v, + v_plane_size, output_file); + + if (!success) { + fprintf(stderr, "LibYUV error during RGBA to I420 frame conversion\n"); + break; + } + } + + delete[] rgba_buffer; + delete[] dst_y; + delete[] dst_u; + delete[] dst_v; + + fclose(output_file); + + return success; +} + +bool Converter::AddYUVToFile(uint8_t* y_plane, + int y_plane_size, + uint8_t* u_plane, + int u_plane_size, + uint8_t* v_plane, + int v_plane_size, + FILE* output_file) { + bool success = AddYUVPlaneToFile(y_plane, y_plane_size, output_file) && + AddYUVPlaneToFile(u_plane, u_plane_size, output_file) && + AddYUVPlaneToFile(v_plane, v_plane_size, output_file); + return success; +} + +bool Converter::AddYUVPlaneToFile(uint8_t* yuv_plane, + int yuv_plane_size, + FILE* file) { + size_t bytes_written = fwrite(yuv_plane, 1, yuv_plane_size, file); + + if (bytes_written != static_cast<size_t>(yuv_plane_size)) { + fprintf(stderr, + "Number of bytes written (%d) doesn't match size of y plane" + " (%d)\n", + static_cast<int>(bytes_written), yuv_plane_size); + return false; + } + return true; +} + +bool Converter::ReadRGBAFrame(const char* input_file_name, + int input_frame_size, + unsigned char* buffer) { + FILE* input_file = fopen(input_file_name, "rb"); + if (input_file == NULL) { + fprintf(stderr, "Couldn't open input file for reading: %s\n", + input_file_name); + return false; + } + + size_t nbr_read = fread(buffer, 1, input_frame_size, input_file); + fclose(input_file); + + if (nbr_read != static_cast<size_t>(input_frame_size)) { + fprintf(stderr, "Error reading from input file: %s\n", input_file_name); + return false; + } + + return true; +} + +std::string Converter::FindFullFileName(std::string dir_name, + std::string file_name) { + return dir_name + SEPARATOR + file_name; +} + +bool Converter::FileExists(std::string file_name_to_check) { + struct STAT file_info; + int result = STAT(file_name_to_check.c_str(), &file_info); + return (result == 0); +} + +std::string Converter::FormFrameName(int width, int number) { + std::stringstream tmp; + + // Zero-pad number to a string. + tmp << std::setfill('0') << std::setw(width) << number; + + return "frame_" + tmp.str(); +} + +} // namespace test +} // namespace webrtc |