301 lines
10 KiB
C++
301 lines
10 KiB
C++
|
/*
|
||
|
* Copyright (c) 2011 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.
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* ViERenderManager.cpp
|
||
|
*/
|
||
|
|
||
|
#include "vie_render_manager.h"
|
||
|
#include "engine_configurations.h"
|
||
|
#include "vie_defines.h"
|
||
|
|
||
|
#include "critical_section_wrapper.h"
|
||
|
#include "video_render.h"
|
||
|
#include "video_render_defines.h"
|
||
|
#include "rw_lock_wrapper.h"
|
||
|
#include "trace.h"
|
||
|
|
||
|
namespace webrtc {
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Constructor
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
|
||
|
ViERenderManagerScoped::ViERenderManagerScoped(const ViERenderManager& vieRenderManager)
|
||
|
:
|
||
|
ViEManagerScopedBase(vieRenderManager)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Renderer()
|
||
|
//
|
||
|
// Returns a pointer to the ViERender object
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViERenderer* ViERenderManagerScoped::Renderer(WebRtc_Word32 renderId) const
|
||
|
{
|
||
|
return static_cast<const ViERenderManager*> (_vieManager)->ViERenderPtr(renderId);
|
||
|
}
|
||
|
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Constructor
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViERenderManager::ViERenderManager(WebRtc_Word32 engineId) :
|
||
|
_listCritsect(*CriticalSectionWrapper::CreateCriticalSection()),
|
||
|
_engineId(engineId),
|
||
|
_streamToViERenderer(),
|
||
|
_renderList(),
|
||
|
_useExternalRenderModule(false)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engineId),
|
||
|
"ViERenderManager::ViERenderManager(engineId: %d) - Constructor", engineId);
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// Destructor
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViERenderManager::~ViERenderManager()
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(_engineId),
|
||
|
"ViERenderManager Destructor, engineId: %d", _engineId);
|
||
|
|
||
|
while(_streamToViERenderer.Size()!=0)
|
||
|
{
|
||
|
MapItem* item=_streamToViERenderer.First();
|
||
|
assert(item);
|
||
|
const WebRtc_Word32 renderId=item->GetId();
|
||
|
item=NULL;// Deleted be RemoveRenderStream;
|
||
|
RemoveRenderStream(renderId);
|
||
|
}
|
||
|
delete &_listCritsect;
|
||
|
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// RegisterVideoRenderModule
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
WebRtc_Word32 ViERenderManager::RegisterVideoRenderModule(VideoRender& renderModule)
|
||
|
{
|
||
|
// See if there is already a render module registered for the window that
|
||
|
// the registrant render module is associated with
|
||
|
VideoRender* ptrCurrentModule = FindRenderModule(renderModule.Window());
|
||
|
if (ptrCurrentModule)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
|
||
|
"A module is already registered for this window (window=%p, current module=%p, registrant module=%p",
|
||
|
renderModule.Window(), ptrCurrentModule, &renderModule);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Register module
|
||
|
_renderList.PushBack(static_cast<void*>(&renderModule));
|
||
|
_useExternalRenderModule=true;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// DeRegisterVideoRenderModule
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
WebRtc_Word32 ViERenderManager::DeRegisterVideoRenderModule(VideoRender& renderModule)
|
||
|
{
|
||
|
// Check if there are streams in the module
|
||
|
WebRtc_UWord32 nStreams = renderModule.GetNumIncomingRenderStreams();
|
||
|
if (nStreams != 0)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId),
|
||
|
"There are still %d streams in this module, cannot de-register", nStreams);
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
// Erase the render module from the map
|
||
|
ListItem* listItem = NULL;
|
||
|
bool found = false;
|
||
|
for (listItem = _renderList.First(); listItem != NULL; listItem = _renderList.Next(listItem))
|
||
|
{
|
||
|
if (&renderModule == static_cast<VideoRender*>(listItem->GetItem()))
|
||
|
{
|
||
|
// We've found our renderer
|
||
|
_renderList.Erase(listItem);
|
||
|
found = true;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (!found)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId), "Module not registered");
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// AddRenderStream
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
ViERenderer* ViERenderManager::AddRenderStream(const WebRtc_Word32 renderId,
|
||
|
void* window,
|
||
|
const WebRtc_UWord32 zOrder,
|
||
|
const float left,
|
||
|
const float top,
|
||
|
const float right,
|
||
|
const float bottom)
|
||
|
{
|
||
|
CriticalSectionScoped cs(_listCritsect);
|
||
|
|
||
|
if (_streamToViERenderer.Find(renderId) != NULL)
|
||
|
{
|
||
|
// This stream is already added to a renderer, not allowed!
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId), "Render stream already exists");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
// Get the render module for this window
|
||
|
VideoRender* ptrRenderer = FindRenderModule(window);
|
||
|
if (ptrRenderer == NULL)
|
||
|
{
|
||
|
// No render module for this window, create a new one
|
||
|
#ifndef WEBRTC_VIDEO_EXTERNAL_CAPTURE_AND_RENDER
|
||
|
ptrRenderer = VideoRender::CreateVideoRender(ViEModuleId(_engineId, -1), window, false);
|
||
|
#else
|
||
|
ptrRenderer = VideoRender::CreateVideoRender(ViEModuleId(_engineId, -1), window, false, kRenderExternal);
|
||
|
#endif //WEBRTC_VIDEO_EXTERNAL_CAPTURE_AND_RENDER
|
||
|
if (!ptrRenderer)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId), "Could not create new render module");
|
||
|
return NULL;
|
||
|
}
|
||
|
_renderList.PushBack((void*) ptrRenderer);
|
||
|
}
|
||
|
|
||
|
ViERenderer* vieRenderer= ViERenderer::CreateViERenderer(renderId,_engineId,*ptrRenderer,*this,zOrder,left,top,right,bottom);
|
||
|
if(!vieRenderer)
|
||
|
{
|
||
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(_engineId,renderId), "Could not create new render stream");
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
_streamToViERenderer.Insert(renderId, vieRenderer);
|
||
|
|
||
|
return vieRenderer;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// RemoveRenderStream
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
WebRtc_Word32 ViERenderManager::RemoveRenderStream(const WebRtc_Word32 renderId)
|
||
|
{
|
||
|
// We need exclusive right to the items in the rendermanager to delete a stream
|
||
|
ViEManagerWriteScoped(*this);
|
||
|
|
||
|
// Protect the list/map
|
||
|
CriticalSectionScoped cs(_listCritsect);
|
||
|
|
||
|
MapItem* mapItem = _streamToViERenderer.Find(renderId);
|
||
|
if (mapItem == NULL)
|
||
|
{
|
||
|
// No such stream
|
||
|
WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, ViEId(_engineId), "No renderer for this stream found, channelId");
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Get the vieRender object.
|
||
|
ViERenderer* ptrViERenderer = static_cast<ViERenderer*>(mapItem->GetItem());
|
||
|
assert(ptrViERenderer);
|
||
|
|
||
|
// Get the render module pointer for this vieRender object
|
||
|
VideoRender& renderer=ptrViERenderer->RenderModule();
|
||
|
|
||
|
// Delete the vieRender.
|
||
|
// This deletes the stream in the render module.
|
||
|
delete ptrViERenderer;
|
||
|
|
||
|
// Remove from the stream map
|
||
|
_streamToViERenderer.Erase(mapItem);
|
||
|
|
||
|
// Check if there are other streams in the module
|
||
|
if (!_useExternalRenderModule && renderer.GetNumIncomingRenderStreams() == 0)
|
||
|
{
|
||
|
// Erase the render module from the map
|
||
|
ListItem* listItem = NULL;
|
||
|
for (listItem = _renderList.First(); listItem != NULL; listItem = _renderList.Next(listItem))
|
||
|
{
|
||
|
if (&renderer == static_cast<VideoRender*>(listItem->GetItem()))
|
||
|
{
|
||
|
// We've found our renderer
|
||
|
_renderList.Erase(listItem);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
// Destroy the module
|
||
|
VideoRender::DestroyVideoRender(&renderer);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// ----------------------------------------------------------------------------
|
||
|
// FindRenderModule
|
||
|
//
|
||
|
// Returns a pointer to the render module if it exists in the render list.
|
||
|
// Assumed protected
|
||
|
// ----------------------------------------------------------------------------
|
||
|
|
||
|
VideoRender* ViERenderManager::FindRenderModule(void* window)
|
||
|
{
|
||
|
VideoRender* ptrRenderer = NULL;
|
||
|
ListItem* listItem = NULL;
|
||
|
for (listItem = _renderList.First(); listItem != NULL; listItem = _renderList.Next(listItem))
|
||
|
{
|
||
|
ptrRenderer = static_cast<VideoRender*>(listItem->GetItem());
|
||
|
if (ptrRenderer == NULL)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
if (ptrRenderer->Window() == window)
|
||
|
{
|
||
|
// We've found the render module
|
||
|
break;
|
||
|
}
|
||
|
ptrRenderer = NULL;
|
||
|
}
|
||
|
return ptrRenderer;
|
||
|
}
|
||
|
|
||
|
ViERenderer* ViERenderManager::ViERenderPtr(WebRtc_Word32 renderId) const
|
||
|
{
|
||
|
ViERenderer* ptrRenderer = NULL;
|
||
|
|
||
|
MapItem* mapItem = _streamToViERenderer.Find(renderId);
|
||
|
if (mapItem == NULL)
|
||
|
{
|
||
|
// No such stream in any renderer
|
||
|
return NULL;
|
||
|
}
|
||
|
ptrRenderer = static_cast<ViERenderer*>(mapItem->GetItem());
|
||
|
|
||
|
return ptrRenderer;
|
||
|
}
|
||
|
|
||
|
} //namespace webrtc
|
||
|
|