blob: 29380921ace24770e505eaf24b5f4194d0dad472 [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
mflodman@webrtc.org194a93a2012-01-27 09:11:22 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
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
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000011#include "video_engine/vie_file_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000013#include "engine_configurations.h" // NOLINT
14
wu@webrtc.org4ee906d2011-10-13 17:56:38 +000015#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
kjellander@webrtc.org0a57aae2012-02-15 09:47:55 +000016#include "common_video/jpeg/include/jpeg.h"
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +000017#include "common_video/libyuv/include/webrtc_libyuv.h"
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000018#include "system_wrappers/interface/condition_variable_wrapper.h"
19#include "system_wrappers/interface/critical_section_wrapper.h"
20#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000021#include "video_engine/include/vie_errors.h"
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000022#include "video_engine/vie_capturer.h"
23#include "video_engine/vie_channel.h"
24#include "video_engine/vie_channel_manager.h"
25#include "video_engine/vie_defines.h"
26#include "video_engine/vie_encoder.h"
27#include "video_engine/vie_file_image.h"
28#include "video_engine/vie_file_player.h"
29#include "video_engine/vie_file_recorder.h"
30#include "video_engine/vie_impl.h"
31#include "video_engine/vie_input_manager.h"
32#include "video_engine/vie_render_manager.h"
mflodman@webrtc.org02afbea2011-12-14 18:50:47 +000033#include "video_engine/vie_renderer.h"
wu@webrtc.org4ee906d2011-10-13 17:56:38 +000034#endif
niklase@google.com470e71d2011-07-07 08:21:25 +000035
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000036namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000037
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000038ViEFile* ViEFile::GetInterface(VideoEngine* video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000039#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000040 if (!video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000041 return NULL;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000042 }
43 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
44 ViEFileImpl* vie_file_impl = vie_impl;
45 // Increase ref count.
46 (*vie_file_impl)++;
47 return vie_file_impl;
48#else
49 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000050#endif
51}
52
wu@webrtc.org4ee906d2011-10-13 17:56:38 +000053#ifdef WEBRTC_VIDEO_ENGINE_FILE_API
niklase@google.com470e71d2011-07-07 08:21:25 +000054
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000055int ViEFileImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000056 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000057 "ViEFile::Release()");
58 // Decrease ref count.
59 (*this)--;
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000060 int32_t ref_count = GetCount();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000061 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000062 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000063 "ViEFile release too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000064 shared_data_->SetLastError(kViEAPIDoesNotExist);
niklase@google.com470e71d2011-07-07 08:21:25 +000065 return -1;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000066 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000067 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000068 "ViEFile reference count: %d", ref_count);
69 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000070}
71
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000072ViEFileImpl::ViEFileImpl(ViESharedData* shared_data)
73 : shared_data_(shared_data) {
74 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000075 "ViEFileImpl::ViEFileImpl() Ctor");
niklase@google.com470e71d2011-07-07 08:21:25 +000076}
77
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000078ViEFileImpl::~ViEFileImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000079 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000080 "ViEFileImpl::~ViEFileImpl() Dtor");
81}
82
83int ViEFileImpl::StartPlayFile(const char* file_nameUTF8,
84 int& file_id,
85 const bool loop,
86 const FileFormats file_format) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000087 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
88 "%s", __FUNCTION__);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000089
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000090 if (!shared_data_->Initialized()) {
91 shared_data_->SetLastError(kViENotInitialized);
92 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000093 "%s - ViE instance %d not initialized", __FUNCTION__,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000094 shared_data_->instance_id());
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +000095 return -1;
96 }
97
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000098 VoiceEngine* voice = shared_data_->channel_manager()->GetVoiceEngine();
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000099 const int32_t result = shared_data_->input_manager()->CreateFilePlayer(
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000100 file_nameUTF8, loop, file_format, voice, file_id);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000101 if (result != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000102 shared_data_->SetLastError(result);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000103 return -1;
104 }
105 return 0;
106}
107
108int ViEFileImpl::StopPlayFile(const int file_id) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000109 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000110 "%s(file_id: %d)", __FUNCTION__, file_id);
111 {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000112 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000113 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
114 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000115 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000116 "%s: File with id %d is not playing.", __FUNCTION__,
117 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000118 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000119 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000120 }
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000121 }
122 // Destroy the capture device.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000123 return shared_data_->input_manager()->DestroyFilePlayer(file_id);
niklase@google.com470e71d2011-07-07 08:21:25 +0000124}
125
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000126int ViEFileImpl::RegisterObserver(int file_id,
127 ViEFileObserver& observer) { // NOLINT
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000128 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000129 "%s(file_id: %d)", __FUNCTION__, file_id);
130
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000131 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000132 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
133 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000134 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000135 "%s: File with id %d is not playing.", __FUNCTION__,
136 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000137 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000138 return -1;
139 }
140 if (vie_file_player->IsObserverRegistered()) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000141 WEBRTC_TRACE(kTraceError, kTraceVideo,
142 ViEId(shared_data_->instance_id(), file_id),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000143 "%s: Observer already registered", __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000144 shared_data_->SetLastError(kViEFileObserverAlreadyRegistered);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000145 return -1;
146 }
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000147 if (vie_file_player->RegisterObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000148 WEBRTC_TRACE(kTraceError, kTraceVideo,
149 ViEId(shared_data_->instance_id(), file_id),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000150 "%s: Failed to register observer", __FUNCTION__, file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000151 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000152 return -1;
153 }
154 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000155}
156
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000157int ViEFileImpl::DeregisterObserver(int file_id,
158 ViEFileObserver& observer) { // NOLINT
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000159 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000160 "%s(file_id: %d)", __FUNCTION__, file_id);
161
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000162 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000163 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
164 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000165 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000166 "%s: File with id %d is not playing.", __FUNCTION__,
167 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000168 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000169 return -1;
170 }
171 if (!vie_file_player->IsObserverRegistered()) {
172 WEBRTC_TRACE(kTraceError, kTraceVideo,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000173 ViEId(shared_data_->instance_id(), file_id),
174 "%s: No Observer registered", __FUNCTION__);
175 shared_data_->SetLastError(kViEFileObserverNotRegistered);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000176 return -1;
177 }
178 if (vie_file_player->DeRegisterObserver() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000179 WEBRTC_TRACE(kTraceError, kTraceVideo,
180 ViEId(shared_data_->instance_id(), file_id),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000181 "%s: Failed to deregister observer", __FUNCTION__, file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000182 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000183 return -1;
184 }
185 return 0;
186}
187
188int ViEFileImpl::SendFileOnChannel(const int file_id, const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000189 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000190 "%s(file_id: %d)", __FUNCTION__, file_id);
191
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000192 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000193 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
194 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000195 WEBRTC_TRACE(kTraceError, kTraceVideo,
196 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000197 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000198 shared_data_->SetLastError(kViEFileInvalidChannelId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000199 return -1;
200 }
201
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000202 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000203 if (is.FrameProvider(vie_encoder) != NULL) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000204 WEBRTC_TRACE(kTraceError, kTraceVideo,
205 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000206 "%s: Channel %d already connected to a capture device or "
207 "file.", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000208 shared_data_->SetLastError(kViEFileInputAlreadyConnected);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000209 return -1;
210 }
211
212 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
213 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000214 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000215 "%s: File with id %d is not playing.", __FUNCTION__,
216 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000217 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000218 return -1;
219 }
220
221 if (vie_file_player->RegisterFrameCallback(video_channel, vie_encoder)
222 != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000223 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000224 "%s: Failed to register frame callback.", __FUNCTION__,
225 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000226 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000227 return -1;
228 }
229 return 0;
230}
231
232int ViEFileImpl::StopSendFileOnChannel(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000233 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000234 "%s(video_channel: %d)", __FUNCTION__, video_channel);
235
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000236 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000237 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
238 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000239 WEBRTC_TRACE(kTraceError, kTraceVideo,
240 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000241 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000242 shared_data_->SetLastError(kViEFileInvalidChannelId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000243 return -1;
244 }
245
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000246 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000247 ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
248 if (!frame_provider ||
249 frame_provider->Id() < kViEFileIdBase ||
250 frame_provider->Id() > kViEFileIdMax) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000251 WEBRTC_TRACE(kTraceError, kTraceVideo,
252 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000253 "%s: No file connected to Channel %d", __FUNCTION__,
254 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000255 shared_data_->SetLastError(kViEFileNotConnected);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000256 return -1;
257 }
258 if (frame_provider->DeregisterFrameCallback(vie_encoder) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000259 WEBRTC_TRACE(kTraceError, kTraceVideo,
260 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000261 "%s: Failed to deregister file from channel %d",
262 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000263 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000264 }
265 return 0;
266}
267
268int ViEFileImpl::StartPlayFileAsMicrophone(const int file_id,
269 const int audio_channel,
270 bool mix_microphone,
271 float volume_scaling) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000272 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000273
274 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
275 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000276 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000277 "%s: File with id %d is not playing.", __FUNCTION__,
278 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000279 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000280 return -1;
281 }
282 if (vie_file_player->SendAudioOnChannel(audio_channel, mix_microphone,
283 volume_scaling) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000284 shared_data_->SetLastError(kViEFileVoEFailure);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000285 return -1;
286 }
287 return 0;
288}
289
290int ViEFileImpl::StopPlayFileAsMicrophone(const int file_id,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000291 const int audio_channel) {
292 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000293
294 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
295 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000296 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000297 "%s: File with id %d is not playing.", __FUNCTION__,
298 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000299 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000300 return -1;
301 }
302
303 if (vie_file_player->StopSendAudioOnChannel(audio_channel) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000304 shared_data_->SetLastError(kViEFileVoEFailure);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000305 return -1;
306 }
307 return 0;
308}
309
310int ViEFileImpl::StartPlayAudioLocally(const int file_id,
311 const int audio_channel,
312 float volume_scaling) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000313 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000314
315 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
316 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000317 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000318 "%s: File with id %d is not playing.", __FUNCTION__,
319 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000320 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000321 return -1;
322 }
323 if (vie_file_player->PlayAudioLocally(audio_channel, volume_scaling) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000324 shared_data_->SetLastError(kViEFileVoEFailure);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000325 return -1;
326 }
327 return 0;
328}
329
330int ViEFileImpl::StopPlayAudioLocally(const int file_id,
331 const int audio_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000332 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000333
334 ViEFilePlayer* vie_file_player = is.FilePlayer(file_id);
335 if (!vie_file_player) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000336 WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000337 "%s: File with id %d is not playing.", __FUNCTION__,
338 file_id);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000339 shared_data_->SetLastError(kViEFileNotPlaying);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000340 return -1;
341 }
342 if (vie_file_player->StopPlayAudioLocally(audio_channel) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000343 shared_data_->SetLastError(kViEFileVoEFailure);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000344 return -1;
345 }
346 return 0;
347}
348
349int ViEFileImpl::StartRecordOutgoingVideo(const int video_channel,
350 const char* file_nameUTF8,
351 AudioSource audio_source,
352 const CodecInst& audio_codec,
353 const VideoCodec& video_codec,
354 const FileFormats file_format) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000355 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
356 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000357 "%s video_channel: %d)", __FUNCTION__, video_channel);
358
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000359 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000360 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
361 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000362 WEBRTC_TRACE(kTraceError, kTraceVideo,
363 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000364 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000365 shared_data_->SetLastError(kViEFileInvalidChannelId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000366 return -1;
367 }
368 ViEFileRecorder& file_recorder = vie_encoder->GetOutgoingFileRecorder();
369 if (file_recorder.RecordingStarted()) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000370 WEBRTC_TRACE(kTraceError, kTraceVideo,
371 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000372 "%s: Already recording outgoing video on channel %d",
373 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000374 shared_data_->SetLastError(kViEFileAlreadyRecording);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000375 return -1;
376 }
377
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000378 int32_t ve_channel_id = -1;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000379 VoiceEngine* ve_ptr = NULL;
380 if (audio_source != NO_AUDIO) {
381 ViEChannel* vie_channel = cs.Channel(video_channel);
mflodman@webrtc.org194a93a2012-01-27 09:11:22 +0000382 if (!vie_channel) {
383 // Channel should exists since we have a ViEEncoder above.
384 assert(false);
385 return -1;
386 }
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000387 ve_channel_id = vie_channel->VoiceChannel();
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000388 ve_ptr = shared_data_->channel_manager()->GetVoiceEngine();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000389 if (!ve_ptr) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000390 WEBRTC_TRACE(kTraceError, kTraceVideo,
391 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000392 "%s: Can't access voice engine. Have SetVoiceEngine "
393 "been called?", __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000394 shared_data_->SetLastError(kViEFileVoENotSet);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000395 return -1;
niklase@google.com470e71d2011-07-07 08:21:25 +0000396 }
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000397 }
398 if (file_recorder.StartRecording(file_nameUTF8, video_codec, audio_source,
399 ve_channel_id, audio_codec, ve_ptr,
400 file_format) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000401 WEBRTC_TRACE(kTraceError, kTraceVideo,
402 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000403 "%s: Failed to start recording. Check arguments.",
404 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000405 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000406 return -1;
407 }
408
409 return 0;
410}
411
412int ViEFileImpl::StopRecordOutgoingVideo(const int video_channel) {
413 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000414 ViEId(shared_data_->instance_id(), video_channel),
415 "%s video_channel: %d)", __FUNCTION__, video_channel);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000416
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000417 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000418 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
419 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000420 WEBRTC_TRACE(kTraceError, kTraceVideo,
421 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000422 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000423 shared_data_->SetLastError(kViEFileInvalidChannelId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000424 return -1;
425 }
426 ViEFileRecorder& file_recorder = vie_encoder->GetOutgoingFileRecorder();
427 if (!file_recorder.RecordingStarted()) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000428 WEBRTC_TRACE(kTraceError, kTraceVideo,
429 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000430 "%s: Channel %d is not recording.", __FUNCTION__,
431 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000432 shared_data_->SetLastError(kViEFileNotRecording);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000433 return -1;
434 }
435 if (file_recorder.StopRecording() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000436 WEBRTC_TRACE(kTraceError, kTraceVideo,
437 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000438 "%s: Failed to stop recording of channel %d.", __FUNCTION__,
439 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000440 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000441 return -1;
442 }
443 return 0;
444}
445
446int ViEFileImpl::StopRecordIncomingVideo(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000447 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
448 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000449 "%s video_channel: %d)", __FUNCTION__, video_channel);
450
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000451 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000452 ViEChannel* vie_channel = cs.Channel(video_channel);
453 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000454 WEBRTC_TRACE(kTraceError, kTraceVideo,
455 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000456 "%s: Channel %d doesn't exist", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000457 shared_data_->SetLastError(kViEFileInvalidChannelId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000458 return -1;
459 }
460 ViEFileRecorder& file_recorder = vie_channel->GetIncomingFileRecorder();
461 if (!file_recorder.RecordingStarted()) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000462 WEBRTC_TRACE(kTraceError, kTraceVideo,
463 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000464 "%s: Channel %d is not recording.", __FUNCTION__,
465 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000466 shared_data_->SetLastError(kViEFileNotRecording);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000467 vie_channel->ReleaseIncomingFileRecorder();
468 return -1;
469 }
470 if (file_recorder.StopRecording() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000471 WEBRTC_TRACE(kTraceError, kTraceVideo,
472 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000473 "%s: Failed to stop recording of channel %d.",
474 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000475 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000476 vie_channel->ReleaseIncomingFileRecorder();
477 return -1;
478 }
479 // Let the channel know we are no longer recording.
480 vie_channel->ReleaseIncomingFileRecorder();
481 return 0;
482}
483
484int ViEFileImpl::StartRecordIncomingVideo(const int video_channel,
485 const char* file_nameUTF8,
486 AudioSource audio_source,
487 const CodecInst& audio_codec,
488 const VideoCodec& video_codec,
489 const FileFormats file_format) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000490 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
491 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000492 "%s video_channel: %d)", __FUNCTION__, video_channel);
493
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000494 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000495 ViEChannel* vie_channel = cs.Channel(video_channel);
496 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000497 WEBRTC_TRACE(kTraceError, kTraceVideo,
498 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000499 "%s: Channel %d doesn't exist", __FUNCTION__,
500 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000501 shared_data_->SetLastError(kViEFileInvalidChannelId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000502 return -1;
503 }
504 ViEFileRecorder& file_recorder = vie_channel->GetIncomingFileRecorder();
505 if (file_recorder.RecordingStarted()) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000506 WEBRTC_TRACE(kTraceError, kTraceVideo,
507 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000508 "%s: Already recording outgoing video on channel %d",
509 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000510 shared_data_->SetLastError(kViEFileAlreadyRecording);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000511 return -1;
512 }
513
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000514 int32_t ve_channel_id = -1;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000515 VoiceEngine* ve_ptr = NULL;
516 if (audio_source != NO_AUDIO) {
517 ve_channel_id = vie_channel->VoiceChannel();
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000518 ve_ptr = shared_data_->channel_manager()->GetVoiceEngine();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000519
520 if (!ve_ptr) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000521 WEBRTC_TRACE(kTraceError, kTraceVideo,
522 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000523 "%s: Can't access voice engine. Have SetVoiceEngine "
524 "been called?", __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000525 shared_data_->SetLastError(kViEFileVoENotSet);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000526 return -1;
527 }
528 }
529 if (file_recorder.StartRecording(file_nameUTF8, video_codec, audio_source,
530 ve_channel_id, audio_codec, ve_ptr,
531 file_format) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000532 WEBRTC_TRACE(kTraceError, kTraceVideo,
533 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000534 "%s: Failed to start recording. Check arguments.",
535 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000536 shared_data_->SetLastError(kViEFileUnknownError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000537 return -1;
538 }
539 return 0;
540}
541
542int ViEFileImpl::GetFileInformation(const char* file_name,
543 VideoCodec& video_codec,
544 CodecInst& audio_codec,
545 const FileFormats file_format) {
546 return ViEFilePlayer::GetFileInformation(
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000547 shared_data_->instance_id(),
leozwang@webrtc.org39e96592012-03-01 18:22:48 +0000548 file_name, video_codec, audio_codec, file_format);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000549}
550
551int ViEFileImpl::GetRenderSnapshot(const int video_channel,
552 const char* file_nameUTF8) {
553 // Gain access to the renderer for the specified channel and get it's
554 // current frame.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000555 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000556 ViERenderer* renderer = rs.Renderer(video_channel);
557 if (!renderer) {
558 return -1;
559 }
560
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000561 I420VideoFrame video_frame;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000562 if (renderer->GetLastRenderedFrame(video_channel, video_frame) == -1) {
563 return -1;
564 }
565
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000566 // JPEGEncoder writes the jpeg file for you (no control over it) and does
567 // not return you the buffer. Thus, we are not going to be writing to the
568 // disk here.
569 JpegEncoder jpeg_encoder;
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000570 if (jpeg_encoder.SetFileName(file_nameUTF8) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000571 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000572 "\tCould not open output file '%s' for writing!",
573 file_nameUTF8);
574 return -1;
575 }
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000576
mikhal@webrtc.org7cbb5a02012-07-25 20:38:14 +0000577 if (jpeg_encoder.Encode(video_frame) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000578 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000579 "\tCould not encode i420 -> jpeg file '%s' for writing!",
580 file_nameUTF8);
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000581 return -1;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000582 }
583 return 0;
584}
585
586int ViEFileImpl::GetRenderSnapshot(const int video_channel,
587 ViEPicture& picture) {
588 // Gain access to the renderer for the specified channel and get it's
589 // current frame.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000590 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000591 ViERenderer* renderer = rs.Renderer(video_channel);
592 if (!renderer) {
593 return -1;
594 }
595
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000596 I420VideoFrame video_frame;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000597 if (renderer->GetLastRenderedFrame(video_channel, video_frame) == -1) {
598 return -1;
599 }
600
601 // Copy from VideoFrame class to ViEPicture struct.
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000602 int buffer_length = CalcBufferSize(kI420, video_frame.width(),
603 video_frame.height());
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000604 picture.data = static_cast<uint8_t*>(malloc(buffer_length * sizeof(uint8_t)));
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000605 if (ExtractBuffer(video_frame, buffer_length, picture.data) < 0) {
606 return -1;
607 }
608
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000609 picture.size = buffer_length;
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000610 picture.width = video_frame.width();
611 picture.height = video_frame.height();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000612 picture.type = kVideoI420;
613 return 0;
614}
615
616int ViEFileImpl::GetCaptureDeviceSnapshot(const int capture_id,
617 const char* file_nameUTF8) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000618 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000619 ViECapturer* capturer = is.Capture(capture_id);
620 if (!capturer) {
621 return -1;
622 }
623
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000624 I420VideoFrame video_frame;
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000625 if (GetNextCapturedFrame(capture_id, &video_frame) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000626 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000627 "Could not gain acces to capture device %d video frame "
628 "%s:%d", capture_id, __FUNCTION__);
629 return -1;
630 }
631
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000632 // JPEGEncoder writes the jpeg file for you (no control over it) and does
633 // not return you the buffer Thusly, we are not going to be writing to the
634 // disk here.
635 JpegEncoder jpeg_encoder;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000636
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000637 if (jpeg_encoder.SetFileName(file_nameUTF8) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000638 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000639 "\tCould not open output file '%s' for writing!",
640 file_nameUTF8);
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000641 return -1;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000642 }
mikhal@webrtc.org7cbb5a02012-07-25 20:38:14 +0000643 if (jpeg_encoder.Encode(video_frame) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000644 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000645 "\tCould not encode i420 -> jpeg file '%s' for "
646 "writing!", file_nameUTF8);
mikhal@webrtc.org7cbb5a02012-07-25 20:38:14 +0000647
mflodman@webrtc.orga768ca12012-01-18 08:52:16 +0000648 return -1;
649 }
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000650 return 0;
651}
652
653int ViEFileImpl::GetCaptureDeviceSnapshot(const int capture_id,
654 ViEPicture& picture) {
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000655 I420VideoFrame video_frame;
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000656 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000657 ViECapturer* capturer = is.Capture(capture_id);
658 if (!capturer) {
659 return -1;
660 }
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000661 if (GetNextCapturedFrame(capture_id, &video_frame) == -1) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000662 WEBRTC_TRACE(kTraceError, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000663 "Could not gain acces to capture device %d video frame "
664 "%s:%d", capture_id, __FUNCTION__);
665 return -1;
666 }
667
668 // Copy from VideoFrame class to ViEPicture struct.
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000669 int buffer_length = CalcBufferSize(kI420, video_frame.width(),
670 video_frame.height());
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000671 picture.data = static_cast<uint8_t*>(malloc(buffer_length * sizeof(uint8_t)));
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000672 if (ExtractBuffer(video_frame, buffer_length, picture.data) < 0) {
673 return -1;
674 }
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000675 picture.size = buffer_length;
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000676 picture.width = video_frame.width();
677 picture.height = video_frame.height();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000678 picture.type = kVideoI420;
679 return 0;
680}
681
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000682int ViEFileImpl::FreePicture(ViEPicture& picture) { // NOLINT
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000683 if (picture.data) {
684 free(picture.data);
685 }
686
687 picture.data = NULL;
688 picture.size = 0;
689 picture.width = 0;
690 picture.height = 0;
691 picture.type = kVideoUnknown;
692 return 0;
693}
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000694
695int ViEFileImpl::SetRenderStartImage(const int video_channel,
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000696 const char* file_nameUTF8) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000697 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
698 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000699 "%s(video_channel: %d)", __FUNCTION__, video_channel);
700
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000701 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000702 ViERenderer* renderer = rs.Renderer(video_channel);
703 if (!renderer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000704 shared_data_->SetLastError(kViEFileInvalidRenderId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000705 return -1;
706 }
707
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000708 I420VideoFrame start_image;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000709 if (ViEFileImage::ConvertJPEGToVideoFrame(
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000710 ViEId(shared_data_->instance_id(), video_channel), file_nameUTF8,
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000711 &start_image) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000712 WEBRTC_TRACE(kTraceError, kTraceVideo,
713 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000714 "%s(video_channel: %d) Failed to open file.", __FUNCTION__,
715 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000716 shared_data_->SetLastError(kViEFileInvalidFile);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000717 return -1;
718 }
719 if (renderer->SetRenderStartImage(start_image) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000720 shared_data_->SetLastError(kViEFileSetStartImageError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000721 return -1;
722 }
723 return 0;
724}
725
726int ViEFileImpl::SetRenderStartImage(const int video_channel,
727 const ViEPicture& picture) {
728 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000729 ViEId(shared_data_->instance_id(), video_channel),
730 "%s(video_channel: %d)", __FUNCTION__, video_channel);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000731 if (picture.type != kVideoI420) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000732 WEBRTC_TRACE(kTraceError, kTraceVideo,
733 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000734 "%s(video_channel: %d) Not a valid picture type.",
735 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000736 shared_data_->SetLastError(kViEFileInvalidArgument);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000737 return -1;
738 }
739
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000740 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000741 ViERenderer* renderer = rs.Renderer(video_channel);
742 if (!renderer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000743 shared_data_->SetLastError(kViEFileInvalidRenderId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000744 return -1;
745 }
746
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000747 I420VideoFrame start_image;
748 if (ViEFileImage::ConvertPictureToI420VideoFrame(
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000749 ViEId(shared_data_->instance_id(), video_channel), picture,
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000750 &start_image) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000751 WEBRTC_TRACE(kTraceError, kTraceVideo,
752 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000753 "%s(video_channel: %d) Failed to use picture.",
754 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000755 shared_data_->SetLastError(kViEFileInvalidCapture);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000756 return -1;
757 }
758 if (renderer->SetRenderStartImage(start_image) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000759 shared_data_->SetLastError(kViEFileSetStartImageError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000760 return -1;
761 }
762 return 0;
763}
764int ViEFileImpl::SetRenderTimeoutImage(const int video_channel,
765 const char* file_nameUTF8,
766 const unsigned int timeout_ms) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000767 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
768 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000769 "%s(video_channel: %d)", __FUNCTION__, video_channel);
770
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000771 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000772 ViERenderer* renderer = rs.Renderer(video_channel);
773 if (!renderer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000774 shared_data_->SetLastError(kViEFileInvalidRenderId);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000775 return -1;
776 }
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000777 I420VideoFrame timeout_image;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000778 if (ViEFileImage::ConvertJPEGToVideoFrame(
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000779 ViEId(shared_data_->instance_id(), video_channel), file_nameUTF8,
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000780 &timeout_image) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000781 WEBRTC_TRACE(kTraceError, kTraceVideo,
782 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000783 "%s(video_channel: %d) Failed to open file.", __FUNCTION__,
784 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000785 shared_data_->SetLastError(kViEFileInvalidFile);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000786 return -1;
787 }
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000788 int32_t timeout_time = timeout_ms;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000789 if (timeout_ms < kViEMinRenderTimeoutTimeMs) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000790 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
791 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000792 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
793 __FUNCTION__, video_channel, kViEMinRenderTimeoutTimeMs);
794 timeout_time = kViEMinRenderTimeoutTimeMs;
795 }
796 if (timeout_ms > kViEMaxRenderTimeoutTimeMs) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000797 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
798 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000799 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
800 __FUNCTION__, video_channel, kViEMaxRenderTimeoutTimeMs);
801 timeout_time = kViEMaxRenderTimeoutTimeMs;
802 }
803 if (renderer->SetTimeoutImage(timeout_image, timeout_time) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000804 shared_data_->SetLastError(kViEFileSetRenderTimeoutError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000805 return -1;
806 }
807 return 0;
808}
809
810int ViEFileImpl::SetRenderTimeoutImage(const int video_channel,
811 const ViEPicture& picture,
812const unsigned int timeout_ms) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000813 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
814 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000815 "%s(video_channel: %d)", __FUNCTION__, video_channel);
816
817 if (picture.type != kVideoI420) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000818 WEBRTC_TRACE(kTraceError, kTraceVideo,
819 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000820 "%s(video_channel: %d) Not a valid picture type.",
821 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000822 shared_data_->SetLastError(kViEFileInvalidArgument);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000823 return -1;
824 }
825
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000826 ViERenderManagerScoped rs(*(shared_data_->render_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000827 ViERenderer* renderer = rs.Renderer(video_channel);
828 if (!renderer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000829 shared_data_->SetLastError(kViEFileSetRenderTimeoutError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000830 return -1;
831 }
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000832 I420VideoFrame timeout_image;
833 if (ViEFileImage::ConvertPictureToI420VideoFrame(
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000834 ViEId(shared_data_->instance_id(), video_channel), picture,
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000835 &timeout_image) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000836 WEBRTC_TRACE(kTraceError, kTraceVideo,
837 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000838 "%s(video_channel: %d) Failed to use picture.",
839 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000840 shared_data_->SetLastError(kViEFileInvalidCapture);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000841 return -1;
842 }
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000843 int32_t timeout_time = timeout_ms;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000844 if (timeout_ms < kViEMinRenderTimeoutTimeMs) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000845 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
846 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000847 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
848 __FUNCTION__, video_channel, kViEMinRenderTimeoutTimeMs);
849 timeout_time = kViEMinRenderTimeoutTimeMs;
850 }
851 if (timeout_ms > kViEMaxRenderTimeoutTimeMs) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000852 WEBRTC_TRACE(kTraceWarning, kTraceVideo,
853 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000854 "%s(video_channel: %d) Invalid timeout_ms, using %d.",
855 __FUNCTION__, video_channel, kViEMaxRenderTimeoutTimeMs);
856 timeout_time = kViEMaxRenderTimeoutTimeMs;
857 }
858 if (renderer->SetTimeoutImage(timeout_image, timeout_time) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000859 shared_data_->SetLastError(kViEFileSetRenderTimeoutError);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000860 return -1;
861 }
862 return 0;
863}
864
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000865int32_t ViEFileImpl::GetNextCapturedFrame(int32_t capture_id,
866 I420VideoFrame* video_frame) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000867 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000868 ViECapturer* capturer = is.Capture(capture_id);
869 if (!capturer) {
870 return -1;
871 }
872
873 ViECaptureSnapshot* snap_shot = new ViECaptureSnapshot();
874 capturer->RegisterFrameCallback(-1, snap_shot);
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000875 bool snapshot_taken = snap_shot->GetSnapshot(kViECaptureMaxSnapshotWaitTimeMs,
876 video_frame);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000877
878 // Check once again if it has been destroyed.
879 capturer->DeregisterFrameCallback(snap_shot);
880 delete snap_shot;
881 snap_shot = NULL;
882
883 if (snapshot_taken) {
884 return 0;
885 }
886 return -1;
887}
888
mikhal@webrtc.orge41bbdf2012-08-28 16:15:16 +0000889int ViEFileImpl::StartDebugRecording(int video_channel,
890 const char* file_name_utf8) {
891 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
892 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
893 if (!vie_encoder) {
894 WEBRTC_TRACE(kTraceError, kTraceVideo,
895 ViEId(shared_data_->instance_id(), video_channel),
896 "%s: No encoder %d", __FUNCTION__, video_channel);
897 return -1;
898 }
899 return vie_encoder->StartDebugRecording(file_name_utf8);
900}
901
902int ViEFileImpl::StopDebugRecording(int video_channel) {
903 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
904 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
905 if (!vie_encoder) {
906 WEBRTC_TRACE(kTraceError, kTraceVideo,
907 ViEId(shared_data_->instance_id(), video_channel),
908 "%s: No encoder %d", __FUNCTION__, video_channel);
909 return -1;
910 }
911 return vie_encoder->StopDebugRecording();
912}
913
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000914ViECaptureSnapshot::ViECaptureSnapshot()
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000915 : crit_(CriticalSectionWrapper::CreateCriticalSection()),
mflodman@webrtc.org2877bdc2012-01-17 12:18:16 +0000916 condition_varaible_(ConditionVariableWrapper::CreateConditionVariable()),
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000917 video_frame_(NULL) {
918}
919
920ViECaptureSnapshot::~ViECaptureSnapshot() {
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000921 if (video_frame_) {
922 delete video_frame_;
923 video_frame_ = NULL;
924 }
925}
926
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000927bool ViECaptureSnapshot::GetSnapshot(unsigned int max_wait_time,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000928 I420VideoFrame* video_frame) {
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000929 crit_->Enter();
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000930 video_frame_ = new I420VideoFrame();
mflodman@webrtc.org2877bdc2012-01-17 12:18:16 +0000931 if (condition_varaible_->SleepCS(*(crit_.get()), max_wait_time)) {
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000932 // Snapshot taken.
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000933 video_frame->SwapFrame(video_frame_);
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000934 delete video_frame_;
935 video_frame_ = NULL;
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000936 crit_->Leave();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000937 return true;
938 }
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000939 crit_->Leave();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000940 return false;
941}
942
mflodman@webrtc.org8baed512012-06-21 12:11:50 +0000943void ViECaptureSnapshot::DeliverFrame(int id,
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000944 I420VideoFrame* video_frame,
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000945 int num_csrcs,
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000946const uint32_t CSRC[kRtpCsrcSize]) {
mflodman@webrtc.orgd32c4472011-12-22 14:17:53 +0000947 CriticalSectionScoped cs(crit_.get());
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000948 if (!video_frame_) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000949 return;
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000950 }
mikhal@webrtc.org9fedff72012-10-24 18:33:04 +0000951 video_frame_->SwapFrame(video_frame);
mflodman@webrtc.org2877bdc2012-01-17 12:18:16 +0000952 condition_varaible_->WakeAll();
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000953 return;
niklase@google.com470e71d2011-07-07 08:21:25 +0000954}
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000955
wu@webrtc.org4ee906d2011-10-13 17:56:38 +0000956#endif
mflodman@webrtc.org813b4ef2011-12-20 10:39:30 +0000957
958} // namespace webrtc