
BUG=314 Review URL: https://webrtc-codereview.appspot.com/1302005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3801 4adac7df-926f-26a2-2b94-8c16560cd09d
231 lines
8.1 KiB
C++
231 lines
8.1 KiB
C++
/*
|
|
* 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 "video_engine/vie_render_manager.h"
|
|
|
|
#include "engine_configurations.h" // NOLINT
|
|
#include "webrtc/modules/video_render/include/video_render.h"
|
|
#include "webrtc/modules/video_render/include/video_render_defines.h"
|
|
#include "system_wrappers/interface/critical_section_wrapper.h"
|
|
#include "system_wrappers/interface/rw_lock_wrapper.h"
|
|
#include "system_wrappers/interface/trace.h"
|
|
#include "video_engine/vie_defines.h"
|
|
#include "video_engine/vie_renderer.h"
|
|
|
|
namespace webrtc {
|
|
|
|
ViERenderManagerScoped::ViERenderManagerScoped(
|
|
const ViERenderManager& vie_render_manager)
|
|
: ViEManagerScopedBase(vie_render_manager) {
|
|
}
|
|
|
|
ViERenderer* ViERenderManagerScoped::Renderer(int32_t render_id) const {
|
|
return static_cast<const ViERenderManager*>(vie_manager_)->ViERenderPtr(
|
|
render_id);
|
|
}
|
|
|
|
ViERenderManager::ViERenderManager(int32_t engine_id)
|
|
: list_cs_(CriticalSectionWrapper::CreateCriticalSection()),
|
|
engine_id_(engine_id),
|
|
use_external_render_module_(false) {
|
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id),
|
|
"ViERenderManager::ViERenderManager(engine_id: %d) - "
|
|
"Constructor", engine_id);
|
|
}
|
|
|
|
ViERenderManager::~ViERenderManager() {
|
|
WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"ViERenderManager Destructor, engine_id: %d", engine_id_);
|
|
|
|
while (stream_to_vie_renderer_.Size() != 0) {
|
|
MapItem* item = stream_to_vie_renderer_.First();
|
|
assert(item);
|
|
const int32_t render_id = item->GetId();
|
|
// The renderer is delete in RemoveRenderStream.
|
|
item = NULL;
|
|
RemoveRenderStream(render_id);
|
|
}
|
|
}
|
|
|
|
int32_t ViERenderManager::RegisterVideoRenderModule(
|
|
VideoRender* render_module) {
|
|
// See if there is already a render module registered for the window that
|
|
// the registrant render module is associated with.
|
|
VideoRender* current_module = FindRenderModule(render_module->Window());
|
|
if (current_module) {
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"A module is already registered for this window (window=%p, "
|
|
"current module=%p, registrant module=%p.",
|
|
render_module->Window(), current_module, render_module);
|
|
return -1;
|
|
}
|
|
|
|
// Register module.
|
|
render_list_.PushBack(static_cast<void*>(render_module));
|
|
use_external_render_module_ = true;
|
|
return 0;
|
|
}
|
|
|
|
int32_t ViERenderManager::DeRegisterVideoRenderModule(
|
|
VideoRender* render_module) {
|
|
// Check if there are streams in the module.
|
|
uint32_t n_streams = render_module->GetNumIncomingRenderStreams();
|
|
if (n_streams != 0) {
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"There are still %d streams in this module, cannot "
|
|
"de-register", n_streams);
|
|
return -1;
|
|
}
|
|
|
|
// Erase the render module from the map.
|
|
ListItem* list_item = NULL;
|
|
bool found = false;
|
|
for (list_item = render_list_.First(); list_item != NULL;
|
|
list_item = render_list_.Next(list_item)) {
|
|
if (render_module == static_cast<VideoRender*>(list_item->GetItem())) {
|
|
// We've found our renderer.
|
|
render_list_.Erase(list_item);
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found) {
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"Module not registered");
|
|
return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ViERenderer* ViERenderManager::AddRenderStream(const int32_t render_id,
|
|
void* window,
|
|
const uint32_t z_order,
|
|
const float left,
|
|
const float top,
|
|
const float right,
|
|
const float bottom) {
|
|
CriticalSectionScoped cs(list_cs_.get());
|
|
|
|
if (stream_to_vie_renderer_.Find(render_id) != NULL) {
|
|
// This stream is already added to a renderer, not allowed!
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"Render stream already exists");
|
|
return NULL;
|
|
}
|
|
|
|
// Get the render module for this window.
|
|
VideoRender* render_module = FindRenderModule(window);
|
|
if (render_module == NULL) {
|
|
// No render module for this window, create a new one.
|
|
render_module = VideoRender::CreateVideoRender(ViEModuleId(engine_id_, -1),
|
|
window, false);
|
|
if (!render_module) {
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"Could not create new render module");
|
|
return NULL;
|
|
}
|
|
render_list_.PushBack(static_cast<void*>(render_module));
|
|
}
|
|
|
|
ViERenderer* vie_renderer = ViERenderer::CreateViERenderer(render_id,
|
|
engine_id_,
|
|
*render_module,
|
|
*this, z_order,
|
|
left, top, right,
|
|
bottom);
|
|
if (!vie_renderer) {
|
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo,
|
|
ViEId(engine_id_, render_id),
|
|
"Could not create new render stream");
|
|
return NULL;
|
|
}
|
|
stream_to_vie_renderer_.Insert(render_id, vie_renderer);
|
|
return vie_renderer;
|
|
}
|
|
|
|
int32_t ViERenderManager::RemoveRenderStream(
|
|
const int32_t render_id) {
|
|
// We need exclusive right to the items in the render manager to delete a
|
|
// stream.
|
|
ViEManagerWriteScoped scope(this);
|
|
|
|
CriticalSectionScoped cs(list_cs_.get());
|
|
MapItem* map_item = stream_to_vie_renderer_.Find(render_id);
|
|
if (!map_item) {
|
|
// No such stream
|
|
WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceVideo, ViEId(engine_id_),
|
|
"No renderer for this stream found, channel_id");
|
|
return 0;
|
|
}
|
|
|
|
ViERenderer* vie_renderer = static_cast<ViERenderer*>(map_item->GetItem());
|
|
assert(vie_renderer);
|
|
|
|
// Get the render module pointer for this vie_render object.
|
|
VideoRender& renderer = vie_renderer->RenderModule();
|
|
|
|
// Delete the vie_render.
|
|
// This deletes the stream in the render module.
|
|
delete vie_renderer;
|
|
|
|
// Remove from the stream map.
|
|
stream_to_vie_renderer_.Erase(map_item);
|
|
|
|
// Check if there are other streams in the module.
|
|
if (!use_external_render_module_ &&
|
|
renderer.GetNumIncomingRenderStreams() == 0) {
|
|
// Erase the render module from the map.
|
|
ListItem* list_item = NULL;
|
|
for (list_item = render_list_.First(); list_item != NULL;
|
|
list_item = render_list_.Next(list_item)) {
|
|
if (&renderer == static_cast<VideoRender*>(list_item->GetItem())) {
|
|
// We've found our renderer.
|
|
render_list_.Erase(list_item);
|
|
break;
|
|
}
|
|
}
|
|
// Destroy the module.
|
|
VideoRender::DestroyVideoRender(&renderer);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
VideoRender* ViERenderManager::FindRenderModule(void* window) {
|
|
VideoRender* renderer = NULL;
|
|
ListItem* list_item = NULL;
|
|
for (list_item = render_list_.First(); list_item != NULL;
|
|
list_item = render_list_.Next(list_item)) {
|
|
renderer = static_cast<VideoRender*>(list_item->GetItem());
|
|
if (renderer == NULL) {
|
|
break;
|
|
}
|
|
if (renderer->Window() == window) {
|
|
// We've found the render module.
|
|
break;
|
|
}
|
|
renderer = NULL;
|
|
}
|
|
return renderer;
|
|
}
|
|
|
|
ViERenderer* ViERenderManager::ViERenderPtr(int32_t render_id) const {
|
|
ViERenderer* renderer = NULL;
|
|
MapItem* map_item = stream_to_vie_renderer_.Find(render_id);
|
|
if (!map_item) {
|
|
// No such stream in any renderer.
|
|
return NULL;
|
|
}
|
|
renderer = static_cast<ViERenderer*>(map_item->GetItem());
|
|
|
|
return renderer;
|
|
}
|
|
|
|
} // namespace webrtc
|