Index: webrtc/modules/video_render/video_render_impl.cc |
diff --git a/webrtc/modules/video_render/video_render_impl.cc b/webrtc/modules/video_render/video_render_impl.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f3d12dce8f6e871b2c59262d542bb2668d8dcd21 |
--- /dev/null |
+++ b/webrtc/modules/video_render/video_render_impl.cc |
@@ -0,0 +1,550 @@ |
+/* |
+ * 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 <assert.h> |
+ |
+#include "webrtc/common_video/include/incoming_video_stream.h" |
+#include "webrtc/engine_configurations.h" |
+#include "webrtc/modules/video_render/external/video_render_external_impl.h" |
+#include "webrtc/modules/video_render/i_video_render.h" |
+#include "webrtc/modules/video_render/video_render_defines.h" |
+#include "webrtc/modules/video_render/video_render_impl.h" |
+#include "webrtc/system_wrappers/include/critical_section_wrapper.h" |
+#include "webrtc/system_wrappers/include/trace.h" |
+ |
+namespace webrtc { |
+ |
+VideoRender* |
+VideoRender::CreateVideoRender(const int32_t id, |
+ void* window, |
+ const bool fullscreen, |
+ const VideoRenderType videoRenderType/*=kRenderDefault*/) |
+{ |
+ VideoRenderType resultVideoRenderType = videoRenderType; |
+ if (videoRenderType == kRenderDefault) |
+ { |
+ resultVideoRenderType = kRenderExternal; |
+ } |
+ return new ModuleVideoRenderImpl(id, resultVideoRenderType, window, |
+ fullscreen); |
+} |
+ |
+void VideoRender::DestroyVideoRender( |
+ VideoRender* module) |
+{ |
+ if (module) |
+ { |
+ delete module; |
+ } |
+} |
+ |
+ModuleVideoRenderImpl::ModuleVideoRenderImpl( |
+ const int32_t id, |
+ const VideoRenderType videoRenderType, |
+ void* window, |
+ const bool fullscreen) : |
+ _id(id), _moduleCrit(*CriticalSectionWrapper::CreateCriticalSection()), |
+ _ptrWindow(window), _fullScreen(fullscreen), _ptrRenderer(NULL) |
+{ |
+ |
+ // Create platform specific renderer |
+ switch (videoRenderType) |
+ { |
+ case kRenderExternal: |
+ { |
+ VideoRenderExternalImpl* ptrRenderer(NULL); |
+ ptrRenderer = new VideoRenderExternalImpl(_id, videoRenderType, |
+ window, _fullScreen); |
+ if (ptrRenderer) |
+ { |
+ _ptrRenderer = reinterpret_cast<IVideoRender*> (ptrRenderer); |
+ } |
+ } |
+ break; |
+ default: |
+ // Error... |
+ break; |
+ } |
+ if (_ptrRenderer) |
+ { |
+ if (_ptrRenderer->Init() == -1) |
+ { |
+ } |
+ } |
+} |
+ |
+ModuleVideoRenderImpl::~ModuleVideoRenderImpl() |
+{ |
+ delete &_moduleCrit; |
+ |
+ for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); |
+ it != _streamRenderMap.end(); |
+ ++it) { |
+ delete it->second; |
+ } |
+ |
+ // Delete platform specific renderer |
+ if (_ptrRenderer) |
+ { |
+ VideoRenderType videoRenderType = _ptrRenderer->RenderType(); |
+ |
+ switch (videoRenderType) |
+ { |
+ case kRenderExternal: |
+ { |
+ VideoRenderExternalImpl |
+ * ptrRenderer = |
+ reinterpret_cast<VideoRenderExternalImpl*> (_ptrRenderer); |
+ _ptrRenderer = NULL; |
+ delete ptrRenderer; |
+ } |
+ break; |
+ |
+ default: |
+ // Error... |
+ break; |
+ } |
+ } |
+} |
+ |
+int64_t ModuleVideoRenderImpl::TimeUntilNextProcess() |
+{ |
+ // Not used |
+ return 50; |
+} |
+void ModuleVideoRenderImpl::Process() {} |
+ |
+void* |
+ModuleVideoRenderImpl::Window() |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ return _ptrWindow; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::ChangeWindow(void* window) |
+{ |
+ return -1; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::Id() |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ return _id; |
+} |
+ |
+uint32_t ModuleVideoRenderImpl::GetIncomingFrameRate(const uint32_t streamId) { |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ IncomingVideoStreamMap::iterator it = _streamRenderMap.find(streamId); |
+ |
+ if (it == _streamRenderMap.end()) { |
+ // This stream doesn't exist |
+ WEBRTC_TRACE(kTraceError, |
+ kTraceVideoRenderer, |
+ _id, |
+ "%s: stream doesn't exist", |
+ __FUNCTION__); |
+ return 0; |
+ } |
+ assert(it->second != NULL); |
+ return it->second->IncomingRate(); |
+} |
+ |
+VideoRenderCallback* |
+ModuleVideoRenderImpl::AddIncomingRenderStream(const uint32_t streamId, |
+ const uint32_t zOrder, |
+ const float left, |
+ const float top, |
+ const float right, |
+ const float bottom) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return NULL; |
+ } |
+ |
+ if (_streamRenderMap.find(streamId) != _streamRenderMap.end()) { |
+ // The stream already exists... |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: stream already exists", __FUNCTION__); |
+ return NULL; |
+ } |
+ |
+ VideoRenderCallback* ptrRenderCallback = |
+ _ptrRenderer->AddIncomingRenderStream(streamId, zOrder, left, top, |
+ right, bottom); |
+ if (ptrRenderCallback == NULL) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: Can't create incoming stream in renderer", |
+ __FUNCTION__); |
+ return NULL; |
+ } |
+ |
+ // Create platform independant code |
+ IncomingVideoStream* ptrIncomingStream = |
+ new IncomingVideoStream(streamId, false); |
+ ptrIncomingStream->SetRenderCallback(ptrRenderCallback); |
+ VideoRenderCallback* moduleCallback = ptrIncomingStream->ModuleCallback(); |
+ |
+ // Store the stream |
+ _streamRenderMap[streamId] = ptrIncomingStream; |
+ |
+ return moduleCallback; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::DeleteIncomingRenderStream( |
+ const uint32_t streamId) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return -1; |
+ } |
+ |
+ IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); |
+ if (item == _streamRenderMap.end()) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: stream doesn't exist", __FUNCTION__); |
+ return -1; |
+ } |
+ |
+ delete item->second; |
+ |
+ _ptrRenderer->DeleteIncomingRenderStream(streamId); |
+ |
+ _streamRenderMap.erase(item); |
+ |
+ return 0; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::AddExternalRenderCallback( |
+ const uint32_t streamId, |
+ VideoRenderCallback* renderObject) { |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); |
+ |
+ if (item == _streamRenderMap.end()) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: stream doesn't exist", __FUNCTION__); |
+ return -1; |
+ } |
+ |
+ if (item->second == NULL) { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: could not get stream", __FUNCTION__); |
+ return -1; |
+ } |
+ item->second->SetExternalCallback(renderObject); |
+ return 0; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::GetIncomingRenderStreamProperties( |
+ const uint32_t streamId, |
+ uint32_t& zOrder, |
+ float& left, |
+ float& top, |
+ float& right, |
+ float& bottom) const { |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return -1; |
+ } |
+ |
+ return _ptrRenderer->GetIncomingRenderStreamProperties(streamId, zOrder, |
+ left, top, right, |
+ bottom); |
+} |
+ |
+uint32_t ModuleVideoRenderImpl::GetNumIncomingRenderStreams() const |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ return static_cast<uint32_t>(_streamRenderMap.size()); |
+} |
+ |
+bool ModuleVideoRenderImpl::HasIncomingRenderStream( |
+ const uint32_t streamId) const { |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ return _streamRenderMap.find(streamId) != _streamRenderMap.end(); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::RegisterRawFrameCallback( |
+ const uint32_t streamId, |
+ VideoRenderCallback* callbackObj) { |
+ return -1; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::StartRender(const uint32_t streamId) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return -1; |
+ } |
+ |
+ // Start the stream |
+ IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); |
+ |
+ if (item == _streamRenderMap.end()) |
+ { |
+ return -1; |
+ } |
+ |
+ if (item->second->Start() == -1) |
+ { |
+ return -1; |
+ } |
+ |
+ // Start the HW renderer |
+ if (_ptrRenderer->StartRender() == -1) |
+ { |
+ return -1; |
+ } |
+ return 0; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::StopRender(const uint32_t streamId) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s(%d): No renderer", __FUNCTION__, streamId); |
+ return -1; |
+ } |
+ |
+ // Stop the incoming stream |
+ IncomingVideoStreamMap::iterator item = _streamRenderMap.find(streamId); |
+ |
+ if (item == _streamRenderMap.end()) |
+ { |
+ return -1; |
+ } |
+ |
+ if (item->second->Stop() == -1) |
+ { |
+ return -1; |
+ } |
+ |
+ return 0; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::ResetRender() |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ int32_t ret = 0; |
+ // Loop through all incoming streams and reset them |
+ for (IncomingVideoStreamMap::iterator it = _streamRenderMap.begin(); |
+ it != _streamRenderMap.end(); |
+ ++it) { |
+ if (it->second->Reset() == -1) |
+ ret = -1; |
+ } |
+ return ret; |
+} |
+ |
+RawVideoType ModuleVideoRenderImpl::PreferredVideoType() const |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (_ptrRenderer == NULL) |
+ { |
+ return kVideoI420; |
+ } |
+ |
+ return _ptrRenderer->PerferedVideoType(); |
+} |
+ |
+bool ModuleVideoRenderImpl::IsFullScreen() |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ return _ptrRenderer->FullScreen(); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::GetScreenResolution( |
+ uint32_t& screenWidth, |
+ uint32_t& screenHeight) const |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ return _ptrRenderer->GetScreenResolution(screenWidth, screenHeight); |
+} |
+ |
+uint32_t ModuleVideoRenderImpl::RenderFrameRate( |
+ const uint32_t streamId) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ return _ptrRenderer->RenderFrameRate(streamId); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::SetStreamCropping( |
+ const uint32_t streamId, |
+ const float left, |
+ const float top, |
+ const float right, |
+ const float bottom) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ return _ptrRenderer->SetStreamCropping(streamId, left, top, right, bottom); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::SetTransparentBackground(const bool enable) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ return _ptrRenderer->SetTransparentBackground(enable); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::FullScreenRender(void* window, const bool enable) |
+{ |
+ return -1; |
+} |
+ |
+int32_t ModuleVideoRenderImpl::SetText( |
+ const uint8_t textId, |
+ const uint8_t* text, |
+ const int32_t textLength, |
+ const uint32_t textColorRef, |
+ const uint32_t backgroundColorRef, |
+ const float left, const float top, |
+ const float right, |
+ const float bottom) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return -1; |
+ } |
+ return _ptrRenderer->SetText(textId, text, textLength, textColorRef, |
+ backgroundColorRef, left, top, right, bottom); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::SetBitmap(const void* bitMap, |
+ const uint8_t pictureId, |
+ const void* colorKey, |
+ const float left, |
+ const float top, |
+ const float right, |
+ const float bottom) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return -1; |
+ } |
+ return _ptrRenderer->SetBitmap(bitMap, pictureId, colorKey, left, top, |
+ right, bottom); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::SetExpectedRenderDelay( |
+ uint32_t stream_id, int32_t delay_ms) { |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ |
+ IncomingVideoStreamMap::const_iterator item = |
+ _streamRenderMap.find(stream_id); |
+ if (item == _streamRenderMap.end()) { |
+ // This stream doesn't exist |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s(%u, %d): stream doesn't exist", __FUNCTION__, stream_id, |
+ delay_ms); |
+ return -1; |
+ } |
+ |
+ assert(item->second != NULL); |
+ return item->second->SetExpectedRenderDelay(delay_ms); |
+} |
+ |
+int32_t ModuleVideoRenderImpl::ConfigureRenderer( |
+ const uint32_t streamId, |
+ const unsigned int zOrder, |
+ const float left, |
+ const float top, |
+ const float right, |
+ const float bottom) |
+{ |
+ CriticalSectionScoped cs(&_moduleCrit); |
+ |
+ if (!_ptrRenderer) |
+ { |
+ WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, |
+ "%s: No renderer", __FUNCTION__); |
+ return false; |
+ } |
+ return _ptrRenderer->ConfigureRenderer(streamId, zOrder, left, top, right, |
+ bottom); |
+} |
+ |
+} // namespace webrtc |