2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h"
15 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
16 #include "webrtc/system_wrappers/interface/event_wrapper.h"
17 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
22 Frame(unsigned char* buffer,
26 : buffer(new unsigned char[buffer_size]),
27 buffer_size(buffer_size),
29 render_time(render_time) {
30 memcpy(this->buffer.get(), buffer, buffer_size);
33 webrtc::scoped_ptr<unsigned char[]> buffer;
39 DISALLOW_COPY_AND_ASSIGN(Frame);
43 ViEToFileRenderer::ViEToFileRenderer()
47 thread_(webrtc::ThreadWrapper::CreateThread(
48 ViEToFileRenderer::RunRenderThread,
49 this, webrtc::kNormalPriority, "ViEToFileRendererThread")),
50 frame_queue_cs_(webrtc::CriticalSectionWrapper::CreateCriticalSection()),
51 frame_render_event_(webrtc::EventWrapper::Create()),
56 ViEToFileRenderer::~ViEToFileRenderer() {
57 while (!free_frame_queue_.empty()) {
58 delete free_frame_queue_.front();
59 free_frame_queue_.pop_front();
63 bool ViEToFileRenderer::PrepareForRendering(
64 const std::string& output_path,
65 const std::string& output_filename) {
67 assert(output_file_ == NULL);
69 output_file_ = fopen((output_path + output_filename).c_str(), "wb");
70 if (output_file_ == NULL) {
74 output_filename_ = output_filename;
75 output_path_ = output_path;
77 return thread_->Start(tid);
80 void ViEToFileRenderer::StopRendering() {
81 assert(output_file_ != NULL);
82 if (thread_.get() != NULL) {
83 thread_->SetNotAlive();
84 // Signal that a frame is ready to be written to file.
85 frame_render_event_->Set();
86 // Call Stop() repeatedly, waiting for ProcessRenderQueue() to finish.
87 while (!thread_->Stop()) continue;
93 bool ViEToFileRenderer::SaveOutputFile(const std::string& prefix) {
94 assert(output_file_ == NULL && output_filename_ != "");
95 if (rename((output_path_ + output_filename_).c_str(),
96 (output_path_ + prefix + output_filename_).c_str()) != 0) {
97 perror("Failed to rename output file");
104 bool ViEToFileRenderer::DeleteOutputFile() {
105 assert(output_file_ == NULL && output_filename_ != "");
106 if (remove((output_path_ + output_filename_).c_str()) != 0) {
107 perror("Failed to delete output file");
114 const std::string ViEToFileRenderer::GetFullOutputPath() const {
115 return output_path_ + output_filename_;
118 void ViEToFileRenderer::ForgetOutputFile() {
119 output_filename_ = "";
123 int ViEToFileRenderer::DeliverFrame(unsigned char *buffer,
129 webrtc::CriticalSectionScoped lock(frame_queue_cs_.get());
131 if (free_frame_queue_.empty()) {
132 frame = new test::Frame(buffer, buffer_size, time_stamp, render_time);
134 // Reuse an already allocated frame.
135 frame = free_frame_queue_.front();
136 free_frame_queue_.pop_front();
137 if (frame->buffer_size < buffer_size) {
138 frame->buffer.reset(new unsigned char[buffer_size]);
140 memcpy(frame->buffer.get(), buffer, buffer_size);
141 frame->buffer_size = buffer_size;
142 frame->timestamp = time_stamp;
143 frame->render_time = render_time;
145 render_queue_.push_back(frame);
146 // Signal that a frame is ready to be written to file.
147 frame_render_event_->Set();
151 bool ViEToFileRenderer::IsTextureSupported() { return false; }
153 int ViEToFileRenderer::FrameSizeChange(unsigned int width,
155 unsigned int number_of_streams) {
159 bool ViEToFileRenderer::RunRenderThread(void* obj) {
161 ViEToFileRenderer* renderer = static_cast<ViEToFileRenderer*>(obj);
162 return renderer->ProcessRenderQueue();
165 bool ViEToFileRenderer::ProcessRenderQueue() {
166 // Wait for a frame to be rendered.
167 frame_render_event_->Wait(WEBRTC_EVENT_INFINITE);
168 frame_queue_cs_->Enter();
169 // Render all frames in the queue.
170 while (!render_queue_.empty()) {
171 test::Frame* frame = render_queue_.front();
172 render_queue_.pop_front();
173 // Leave the critical section before writing to file to not block calls to
175 frame_queue_cs_->Leave();
176 assert(output_file_);
177 int written = fwrite(frame->buffer.get(), sizeof(unsigned char),
178 frame->buffer_size, output_file_);
179 frame_queue_cs_->Enter();
181 free_frame_queue_.push_front(frame);
182 if (written != frame->buffer_size) {
183 frame_queue_cs_->Leave();
187 frame_queue_cs_->Leave();