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 | |
11 #include <assert.h> | |
12 | |
13 #include "webrtc/common_video/include/incoming_video_stream.h" | |
14 #include "webrtc/engine_configurations.h" | |
15 #include "webrtc/modules/video_render/external/video_render_external_impl.h" | |
16 #include "webrtc/modules/video_render/i_video_render.h" | |
17 #include "webrtc/modules/video_render/video_render_defines.h" | |
18 #include "webrtc/modules/video_render/video_render_impl.h" | |
19 #include "webrtc/system_wrappers/include/critical_section_wrapper.h" | |
20 #include "webrtc/system_wrappers/include/trace.h" | |
21 | |
22 namespace webrtc { | |
23 | |
24 VideoRender* | |
25 VideoRender::CreateVideoRender(const int32_t id, | |
26 void* window, | |
27 const bool fullscreen, | |
28 const VideoRenderType videoRenderType/*=kRenderDe
fault*/) | |
29 { | |
30 VideoRenderType resultVideoRenderType = videoRenderType; | |
31 if (videoRenderType == kRenderDefault) | |
32 { | |
33 resultVideoRenderType = kRenderExternal; | |
34 } | |
35 return new ModuleVideoRenderImpl(id, resultVideoRenderType, window, | |
36 fullscreen); | |
37 } | |
38 | |
39 void VideoRender::DestroyVideoRender( | |
40 VideoRender* module) | |
41 { | |
42 if (module) | |
43 { | |
44 delete module; | |
45 } | |
46 } | |
47 | |
48 ModuleVideoRenderImpl::ModuleVideoRenderImpl( | |
49 const int32_t id, | |
50 const VideoRenderType videoRenderTy
pe, | |
51 void* window, | |
52 const bool fullscreen) : | |
53 _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()), | |
54 _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL) | |
55 { | |
56 | |
57 // Create platform specific renderer | |
58 switch (videoRenderType) | |
59 { | |
60 case kRenderExternal: | |
61 { | |
62 VideoRenderExternalImpl* ptrRenderer(NULL); | |
63 ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType, | |
64 window, _fullScreen); | |
65 if (ptrRenderer) | |
66 { | |
67 _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer); | |
68 } | |
69 } | |
70 break; | |
71 default: | |
72 // Error... | |
73 break; | |
74 } | |
75 if (_ptrRenderer) | |
76 { | |
77 if (_ptrRenderer->Init() == -1) | |
78 { | |
79 } | |
80 } | |
81 } | |
82 | |
83 ModuleVideoRenderImpl::~ModuleVideoRenderImpl() | |
84 { | |
85 delete &_moduleCrit; | |
86 | |
87 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); | |
88 it != _streamRenderMap.end(); | |
89 ++it) { | |
90 delete it->second; | |
91 } | |
92 | |
93 // Delete platform specific renderer | |
94 if (_ptrRenderer) | |
95 { | |
96 VideoRenderType videoRenderType = _ptrRenderer->RenderType(); | |
97 | |
98 switch (videoRenderType) | |
99 { | |
100 case kRenderExternal: | |
101 { | |
102 VideoRenderExternalImpl | |
103 * ptrRenderer = | |
104 reinterpret_cast<VideoRenderExternalImpl*> (_ptr
Renderer); | |
105 _ptrRenderer = NULL; | |
106 delete ptrRenderer; | |
107 } | |
108 break; | |
109 | |
110 default: | |
111 // Error... | |
112 break; | |
113 } | |
114 } | |
115 } | |
116 | |
117 int64_t ModuleVideoRenderImpl::TimeUntilNextProcess() | |
118 { | |
119 // Not used | |
120 return 50; | |
121 } | |
122 void ModuleVideoRenderImpl::Process() {} | |
123 | |
124 void* | |
125 ModuleVideoRenderImpl::Window() | |
126 { | |
127 CriticalSectionScoped cs(&_moduleCrit); | |
128 return _ptrWindow; | |
129 } | |
130 | |
131 int32_t ModuleVideoRenderImpl::ChangeWindow(void* window) | |
132 { | |
133 return -1; | |
134 } | |
135 | |
136 int32_t ModuleVideoRenderImpl::Id() | |
137 { | |
138 CriticalSectionScoped cs(&_moduleCrit); | |
139 return _id; | |
140 } | |
141 | |
142 uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) { | |
143 CriticalSectionScoped cs(&_moduleCrit); | |
144 | |
145 IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId); | |
146 | |
147 if (it == _streamRenderMap.end()) { | |
148 // This stream doesn't exist | |
149 WEBRTC_TRACE(kTraceError, | |
150 kTraceVideoRenderer, | |
151 _id, | |
152 "%s: stream doesn't exist", | |
153 __FUNCTION__); | |
154 return 0; | |
155 } | |
156 assert(it->second != NULL); | |
157 return it->second->IncomingRate(); | |
158 } | |
159 | |
160 VideoRenderCallback* | |
161 ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId, | |
162 const uint32_t zOrder, | |
163 const float left, | |
164 const float top, | |
165 const float right, | |
166 const float bottom) | |
167 { | |
168 CriticalSectionScoped cs(&_moduleCrit); | |
169 | |
170 if (!_ptrRenderer) | |
171 { | |
172 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
173 "%s: No renderer", __FUNCTION__); | |
174 return NULL; | |
175 } | |
176 | |
177 if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) { | |
178 // The stream already exists... | |
179 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
180 "%s: stream already exists", __FUNCTION__); | |
181 return NULL; | |
182 } | |
183 | |
184 VideoRenderCallback* ptrRenderCallback = | |
185 _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top, | |
186 right, bottom); | |
187 if (ptrRenderCallback == NULL) | |
188 { | |
189 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
190 "%s: Can't create incoming stream in renderer", | |
191 __FUNCTION__); | |
192 return NULL; | |
193 } | |
194 | |
195 // Create platform independant code | |
196 IncomingVideoStream* ptrIncomingStream = | |
197 new IncomingVideoStream(streamId, false); | |
198 ptrIncomingStream->SetRenderCallback(ptrRenderCallback); | |
199 VideoRenderCallback* moduleCallback = ptrIncomingStream->ModuleCallback(); | |
200 | |
201 // Store the stream | |
202 _streamRenderMap[streamId] = ptrIncomingStream; | |
203 | |
204 return moduleCallback; | |
205 } | |
206 | |
207 int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream( | |
208 const uint32_t s
treamId) | |
209 { | |
210 CriticalSectionScoped cs(&_moduleCrit); | |
211 | |
212 if (!_ptrRenderer) | |
213 { | |
214 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
215 "%s: No renderer", __FUNCTION__); | |
216 return -1; | |
217 } | |
218 | |
219 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); | |
220 if (item == _streamRenderMap.end()) | |
221 { | |
222 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
223 "%s: stream doesn't exist", __FUNCTION__); | |
224 return -1; | |
225 } | |
226 | |
227 delete item->second; | |
228 | |
229 _ptrRenderer->DeleteIncomingRenderStream(streamId); | |
230 | |
231 _streamRenderMap.erase(item); | |
232 | |
233 return 0; | |
234 } | |
235 | |
236 int32_t ModuleVideoRenderImpl::AddExternalRenderCallback( | |
237 const uint32_t streamId, | |
238 VideoRenderCallback* renderObject) { | |
239 CriticalSectionScoped cs(&_moduleCrit); | |
240 | |
241 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); | |
242 | |
243 if (item == _streamRenderMap.end()) | |
244 { | |
245 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
246 "%s: stream doesn't exist", __FUNCTION__); | |
247 return -1; | |
248 } | |
249 | |
250 if (item->second == NULL) { | |
251 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
252 "%s: could not get stream", __FUNCTION__); | |
253 return -1; | |
254 } | |
255 item->second->SetExternalCallback(renderObject); | |
256 return 0; | |
257 } | |
258 | |
259 int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties( | |
260 const uint32_t streamId, | |
261 uint32_t& zOrder, | |
262 float& left, | |
263 float& top, | |
264 float& right, | |
265 float& bottom) const { | |
266 CriticalSectionScoped cs(&_moduleCrit); | |
267 | |
268 if (!_ptrRenderer) | |
269 { | |
270 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
271 "%s: No renderer", __FUNCTION__); | |
272 return -1; | |
273 } | |
274 | |
275 return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder, | |
276 left, top, right, | |
277 bottom); | |
278 } | |
279 | |
280 uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const | |
281 { | |
282 CriticalSectionScoped cs(&_moduleCrit); | |
283 | |
284 return static_cast<uint32_t>(_streamRenderMap.size()); | |
285 } | |
286 | |
287 bool ModuleVideoRenderImpl::HasIncomingRenderStream( | |
288 const uint32_t streamId) const { | |
289 CriticalSectionScoped cs(&_moduleCrit); | |
290 | |
291 return _streamRenderMap.find(streamId) != _streamRenderMap.end(); | |
292 } | |
293 | |
294 int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback( | |
295 const uint32_t streamId, | |
296 VideoRenderCallback* callbackObj) { | |
297 return -1; | |
298 } | |
299 | |
300 int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId) | |
301 { | |
302 CriticalSectionScoped cs(&_moduleCrit); | |
303 | |
304 if (!_ptrRenderer) | |
305 { | |
306 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
307 "%s: No renderer", __FUNCTION__); | |
308 return -1; | |
309 } | |
310 | |
311 // Start the stream | |
312 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); | |
313 | |
314 if (item == _streamRenderMap.end()) | |
315 { | |
316 return -1; | |
317 } | |
318 | |
319 if (item->second->Start() == -1) | |
320 { | |
321 return -1; | |
322 } | |
323 | |
324 // Start the HW renderer | |
325 if (_ptrRenderer->StartRender() == -1) | |
326 { | |
327 return -1; | |
328 } | |
329 return 0; | |
330 } | |
331 | |
332 int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId) | |
333 { | |
334 CriticalSectionScoped cs(&_moduleCrit); | |
335 | |
336 if (!_ptrRenderer) | |
337 { | |
338 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
339 "%s(%d): No renderer", __FUNCTION__, streamId); | |
340 return -1; | |
341 } | |
342 | |
343 // Stop the incoming stream | |
344 IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); | |
345 | |
346 if (item == _streamRenderMap.end()) | |
347 { | |
348 return -1; | |
349 } | |
350 | |
351 if (item->second->Stop() == -1) | |
352 { | |
353 return -1; | |
354 } | |
355 | |
356 return 0; | |
357 } | |
358 | |
359 int32_t ModuleVideoRenderImpl::ResetRender() | |
360 { | |
361 CriticalSectionScoped cs(&_moduleCrit); | |
362 | |
363 int32_t ret = 0; | |
364 // Loop through all incoming streams and reset them | |
365 for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); | |
366 it != _streamRenderMap.end(); | |
367 ++it) { | |
368 if (it->second->Reset() == -1) | |
369 ret = -1; | |
370 } | |
371 return ret; | |
372 } | |
373 | |
374 RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const | |
375 { | |
376 CriticalSectionScoped cs(&_moduleCrit); | |
377 | |
378 if (_ptrRenderer == NULL) | |
379 { | |
380 return kVideoI420; | |
381 } | |
382 | |
383 return _ptrRenderer->PerferedVideoType(); | |
384 } | |
385 | |
386 bool ModuleVideoRenderImpl::IsFullScreen() | |
387 { | |
388 CriticalSectionScoped cs(&_moduleCrit); | |
389 | |
390 if (!_ptrRenderer) | |
391 { | |
392 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
393 "%s: No renderer", __FUNCTION__); | |
394 return false; | |
395 } | |
396 return _ptrRenderer->FullScreen(); | |
397 } | |
398 | |
399 int32_t ModuleVideoRenderImpl::GetScreenResolution( | |
400 uint32_t& screenWidth, | |
401 uint32_t& screenHeight)
const | |
402 { | |
403 CriticalSectionScoped cs(&_moduleCrit); | |
404 | |
405 if (!_ptrRenderer) | |
406 { | |
407 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
408 "%s: No renderer", __FUNCTION__); | |
409 return false; | |
410 } | |
411 return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight); | |
412 } | |
413 | |
414 uint32_t ModuleVideoRenderImpl::RenderFrameRate( | |
415 const uint32_t streamId) | |
416 { | |
417 CriticalSectionScoped cs(&_moduleCrit); | |
418 | |
419 if (!_ptrRenderer) | |
420 { | |
421 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
422 "%s: No renderer", __FUNCTION__); | |
423 return false; | |
424 } | |
425 return _ptrRenderer->RenderFrameRate(streamId); | |
426 } | |
427 | |
428 int32_t ModuleVideoRenderImpl::SetStreamCropping( | |
429 const uint32_t streamId, | |
430 const float left, | |
431 const float top, | |
432 const float right, | |
433 const float bottom) | |
434 { | |
435 CriticalSectionScoped cs(&_moduleCrit); | |
436 | |
437 if (!_ptrRenderer) | |
438 { | |
439 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
440 "%s: No renderer", __FUNCTION__); | |
441 return false; | |
442 } | |
443 return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom); | |
444 } | |
445 | |
446 int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable) | |
447 { | |
448 CriticalSectionScoped cs(&_moduleCrit); | |
449 | |
450 if (!_ptrRenderer) | |
451 { | |
452 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
453 "%s: No renderer", __FUNCTION__); | |
454 return false; | |
455 } | |
456 return _ptrRenderer->SetTransparentBackground(enable); | |
457 } | |
458 | |
459 int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable) | |
460 { | |
461 return -1; | |
462 } | |
463 | |
464 int32_t ModuleVideoRenderImpl::SetText( | |
465 const uint8_t textId, | |
466 const uint8_t* text, | |
467 const int32_t textLength, | |
468 const uint32_t textColorRef, | |
469 const uint32_t backgroundColorRef, | |
470 const float left, const float top, | |
471 const float right, | |
472 const float bottom) | |
473 { | |
474 CriticalSectionScoped cs(&_moduleCrit); | |
475 | |
476 if (!_ptrRenderer) | |
477 { | |
478 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
479 "%s: No renderer", __FUNCTION__); | |
480 return -1; | |
481 } | |
482 return _ptrRenderer->SetText(textId, text, textLength, textColorRef, | |
483 backgroundColorRef, left, top, right, bottom); | |
484 } | |
485 | |
486 int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap, | |
487 const uint8_t pictureId, | |
488 const void* colorKey, | |
489 const float left, | |
490 const float top, | |
491 const float right, | |
492 const float bottom) | |
493 { | |
494 CriticalSectionScoped cs(&_moduleCrit); | |
495 | |
496 if (!_ptrRenderer) | |
497 { | |
498 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
499 "%s: No renderer", __FUNCTION__); | |
500 return -1; | |
501 } | |
502 return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top, | |
503 right, bottom); | |
504 } | |
505 | |
506 int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay( | |
507 uint32_t stream_id, int32_t delay_ms) { | |
508 CriticalSectionScoped cs(&_moduleCrit); | |
509 | |
510 if (!_ptrRenderer) { | |
511 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
512 "%s: No renderer", __FUNCTION__); | |
513 return false; | |
514 } | |
515 | |
516 IncomingVideoStreamMap::const_iterator item = | |
517 _streamRenderMap.find(stream_id); | |
518 if (item == _streamRenderMap.end()) { | |
519 // This stream doesn't exist | |
520 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
521 "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id, | |
522 delay_ms); | |
523 return -1; | |
524 } | |
525 | |
526 assert(item->second != NULL); | |
527 return item->second->SetExpectedRenderDelay(delay_ms); | |
528 } | |
529 | |
530 int32_t ModuleVideoRenderImpl::ConfigureRenderer( | |
531 const uint32_t streamId, | |
532 const unsigned int zOrder
, | |
533 const float left, | |
534 const float top, | |
535 const float right, | |
536 const float bottom) | |
537 { | |
538 CriticalSectionScoped cs(&_moduleCrit); | |
539 | |
540 if (!_ptrRenderer) | |
541 { | |
542 WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, | |
543 "%s: No renderer", __FUNCTION__); | |
544 return false; | |
545 } | |
546 return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right, | |
547 bottom); | |
548 } | |
549 | |
550 } // namespace webrtc | |
OLD | NEW |