Removed MapWrapper from ViEFrameProviderBase.

BUG=C-10189

Review URL: https://webrtc-codereview.appspot.com/356002

git-svn-id: http://webrtc.googlecode.com/svn/trunk@1560 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
mflodman@webrtc.org 2012-01-27 09:31:34 +00:00
parent 194a93ac66
commit 832adebca2
2 changed files with 63 additions and 129 deletions

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -10,6 +10,9 @@
#include "video_engine/vie_frame_provider_base.h" #include "video_engine/vie_frame_provider_base.h"
#include <algorithm>
#include "modules/interface/module_common_types.h"
#include "system_wrappers/interface/critical_section_wrapper.h" #include "system_wrappers/interface/critical_section_wrapper.h"
#include "system_wrappers/interface/tick_util.h" #include "system_wrappers/interface/tick_util.h"
#include "system_wrappers/interface/trace.h" #include "system_wrappers/interface/trace.h"
@ -20,27 +23,22 @@ namespace webrtc {
ViEFrameProviderBase::ViEFrameProviderBase(int Id, int engine_id) ViEFrameProviderBase::ViEFrameProviderBase(int Id, int engine_id)
: id_(Id), : id_(Id),
engine_id_(engine_id), engine_id_(engine_id),
frame_callbacks_(),
provider_cs_(CriticalSectionWrapper::CreateCriticalSection()), provider_cs_(CriticalSectionWrapper::CreateCriticalSection()),
extra_frame_(NULL),
frame_delay_(0) { frame_delay_(0) {
} }
ViEFrameProviderBase::~ViEFrameProviderBase() { ViEFrameProviderBase::~ViEFrameProviderBase() {
if (frame_callbacks_.Size() > 0) { if (frame_callbacks_.size() > 0) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, id_), WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, id_),
"FrameCallbacks still exist when Provider deleted %d", "FrameCallbacks still exist when Provider deleted %d",
frame_callbacks_.Size()); frame_callbacks_.size());
}
for (MapItem* item = frame_callbacks_.First(); item != NULL;
item = frame_callbacks_.Next(item)) {
static_cast<ViEFrameCallback*>(item->GetItem())->ProviderDestroyed(id_);
} }
while (frame_callbacks_.Erase(frame_callbacks_.First()) == 0) { for (FrameCallbacks::iterator it = frame_callbacks_.begin();
it != frame_callbacks_.end(); ++it) {
(*it)->ProviderDestroyed(id_);
} }
frame_callbacks_.clear();
delete extra_frame_;
} }
int ViEFrameProviderBase::Id() { int ViEFrameProviderBase::Id() {
@ -57,29 +55,19 @@ void ViEFrameProviderBase::DeliverFrame(
CriticalSectionScoped cs(provider_cs_.get()); CriticalSectionScoped cs(provider_cs_.get());
// Deliver the frame to all registered callbacks. // Deliver the frame to all registered callbacks.
if (frame_callbacks_.Size() > 0) { if (frame_callbacks_.size() > 0) {
if (frame_callbacks_.Size() == 1) { if (frame_callbacks_.size() == 1) {
// We don't have to copy the frame. // We don't have to copy the frame.
ViEFrameCallback* frame_observer = frame_callbacks_.front()->DeliverFrame(id_, video_frame, num_csrcs, CSRC);
static_cast<ViEFrameCallback*>(frame_callbacks_.First()->GetItem());
frame_observer->DeliverFrame(id_, video_frame, num_csrcs, CSRC);
} else { } else {
// Make a copy of the frame for all callbacks. // Make a copy of the frame for all callbacks.callback
for (MapItem* map_item = frame_callbacks_.First(); map_item != NULL; for (FrameCallbacks::iterator it = frame_callbacks_.begin();
map_item = frame_callbacks_.Next(map_item)) { it != frame_callbacks_.end(); ++it) {
if (extra_frame_ == NULL) { if (!extra_frame_.get()) {
extra_frame_ = new VideoFrame(); extra_frame_.reset(new VideoFrame());
}
if (map_item != NULL) {
ViEFrameCallback* frame_observer =
static_cast<ViEFrameCallback*>(map_item->GetItem());
if (frame_observer != NULL) {
// We must copy the frame each time since the previous receiver
// might swap it to avoid a copy.
extra_frame_->CopyFrame(video_frame);
frame_observer->DeliverFrame(id_, *extra_frame_, num_csrcs, CSRC);
}
} }
extra_frame_->CopyFrame(video_frame);
(*it)->DeliverFrame(id_, *(extra_frame_.get()), num_csrcs, CSRC);
} }
} }
} }
@ -98,12 +86,9 @@ void ViEFrameProviderBase::SetFrameDelay(int frame_delay) {
CriticalSectionScoped cs(provider_cs_.get()); CriticalSectionScoped cs(provider_cs_.get());
frame_delay_ = frame_delay; frame_delay_ = frame_delay;
for (MapItem* map_item = frame_callbacks_.First(); map_item != NULL; for (FrameCallbacks::iterator it = frame_callbacks_.begin();
map_item = frame_callbacks_.Next(map_item)) { it != frame_callbacks_.end(); ++it) {
ViEFrameCallback* frame_observer = (*it)->DelayChanged(id_, frame_delay);
static_cast<ViEFrameCallback*>(map_item->GetItem());
assert(frame_observer);
frame_observer->DelayChanged(id_, frame_delay);
} }
} }
@ -119,20 +104,13 @@ int ViEFrameProviderBase::GetBestFormat(int& best_width,
int highest_frame_rate = 0; int highest_frame_rate = 0;
CriticalSectionScoped cs(provider_cs_.get()); CriticalSectionScoped cs(provider_cs_.get());
for (FrameCallbacks::iterator it = frame_callbacks_.begin();
// Check if this one already exists. it != frame_callbacks_.end(); ++it) {
for (MapItem* map_item = frame_callbacks_.First(); map_item != NULL;
map_item = frame_callbacks_.Next(map_item)) {
int prefered_width = 0; int prefered_width = 0;
int prefered_height = 0; int prefered_height = 0;
int prefered_frame_rate = 0; int prefered_frame_rate = 0;
if ((*it)->GetPreferedFrameSettings(prefered_width, prefered_height,
ViEFrameCallback* callback_object = prefered_frame_rate) == 0) {
static_cast<ViEFrameCallback*>(map_item->GetItem());
assert(callback_object);
if (callback_object->GetPreferedFrameSettings(prefered_width,
prefered_height,
prefered_frame_rate) == 0) {
if (prefered_width > largest_width) { if (prefered_width > largest_width) {
largest_width = prefered_width; largest_width = prefered_width;
} }
@ -144,51 +122,31 @@ int ViEFrameProviderBase::GetBestFormat(int& best_width,
} }
} }
} }
best_width = largest_width; best_width = largest_width;
best_height = largest_height; best_height = largest_height;
best_frame_rate = highest_frame_rate; best_frame_rate = highest_frame_rate;
return 0; return 0;
} }
int ViEFrameProviderBase::RegisterFrameCallback( int ViEFrameProviderBase::RegisterFrameCallback(
int observer_id, ViEFrameCallback* callback_object) { int observer_id, ViEFrameCallback* callback_object) {
if (callback_object == NULL) { assert(callback_object);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, id_),
"%s: No argument", __FUNCTION__);
return -1;
}
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_), "%s(0x%p)", WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_), "%s(0x%p)",
__FUNCTION__, callback_object); __FUNCTION__, callback_object);
{ {
CriticalSectionScoped cs(provider_cs_.get()); CriticalSectionScoped cs(provider_cs_.get());
if (std::find(frame_callbacks_.begin(), frame_callbacks_.end(),
// Check if the callback already exists. callback_object) != frame_callbacks_.end()) {
for (MapItem* map_item = frame_callbacks_.First(); // This object is already registered.
map_item != NULL; WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, id_),
map_item = frame_callbacks_.Next(map_item)) { "%s 0x%p already registered", __FUNCTION__,
const ViEFrameCallback* observer =
static_cast<ViEFrameCallback*>(map_item->GetItem());
if (observer == callback_object) {
// This callback is already registered.
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, id_),
"%s 0x%p already registered", __FUNCTION__,
callback_object);
assert("!frameObserver already registered");
return -1;
}
}
if (frame_callbacks_.Insert(observer_id, callback_object) != 0) {
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, id_),
"%s: Could not add 0x%p to list", __FUNCTION__,
callback_object); callback_object);
assert("!frameObserver already registered");
return -1; return -1;
} }
frame_callbacks_.push_back(callback_object);
} }
// Report current capture delay // Report current capture delay.
callback_object->DelayChanged(id_, frame_delay_); callback_object->DelayChanged(id_, frame_delay_);
// Notify implementer of this class that the callback list have changed. // Notify implementer of this class that the callback list have changed.
@ -198,38 +156,23 @@ int ViEFrameProviderBase::RegisterFrameCallback(
int ViEFrameProviderBase::DeregisterFrameCallback( int ViEFrameProviderBase::DeregisterFrameCallback(
const ViEFrameCallback* callback_object) { const ViEFrameCallback* callback_object) {
if (!callback_object) { assert(callback_object);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, id_),
"%s: No argument", __FUNCTION__);
return -1;
}
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_), "%s(0x%p)", WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_), "%s(0x%p)",
__FUNCTION__, callback_object); __FUNCTION__, callback_object);
CriticalSectionScoped cs(provider_cs_.get());
{ FrameCallbacks::iterator it = std::find(frame_callbacks_.begin(),
CriticalSectionScoped cs(provider_cs_.get()); frame_callbacks_.end(),
bool item_found = false; callback_object);
if (it == frame_callbacks_.end()) {
// Try to find the callback in our list. WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, id_),
for (MapItem* map_item = frame_callbacks_.First(); map_item != NULL; "%s 0x%p not found", __FUNCTION__, callback_object);
map_item = frame_callbacks_.Next(map_item)) { return -1;
const ViEFrameCallback* observer =
static_cast<ViEFrameCallback*>(map_item->GetItem());
if (observer == callback_object) {
// We found it, remove it!
frame_callbacks_.Erase(map_item);
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_),
"%s 0x%p deregistered", __FUNCTION__, callback_object);
item_found = true;
break;
}
}
if (!item_found) {
WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, id_),
"%s 0x%p not found", __FUNCTION__, callback_object);
return -1;
}
} }
frame_callbacks_.erase(it);
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_),
"%s 0x%p deregistered", __FUNCTION__, callback_object);
// Notify implementer of this class that the callback list have changed. // Notify implementer of this class that the callback list have changed.
FrameCallbackChanged(); FrameCallbackChanged();
return 0; return 0;
@ -237,30 +180,18 @@ int ViEFrameProviderBase::DeregisterFrameCallback(
bool ViEFrameProviderBase::IsFrameCallbackRegistered( bool ViEFrameProviderBase::IsFrameCallbackRegistered(
const ViEFrameCallback* callback_object) { const ViEFrameCallback* callback_object) {
if (!callback_object) { assert(callback_object);
WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, id_),
"%s: No argument", __FUNCTION__);
return false;
}
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_), WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_),
"%s(0x%p)", __FUNCTION__, callback_object); "%s(0x%p)", __FUNCTION__, callback_object);
for (MapItem* map_item = frame_callbacks_.First(); map_item != NULL; CriticalSectionScoped cs(provider_cs_.get());
map_item = frame_callbacks_.Next(map_item)) { return std::find(frame_callbacks_.begin(), frame_callbacks_.end(),
if (callback_object == map_item->GetItem()) { callback_object) != frame_callbacks_.end();
// We found the callback.
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_),
"%s 0x%p is registered", __FUNCTION__, callback_object);
return true;
}
}
WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, id_),
"%s 0x%p not registered", __FUNCTION__, callback_object);
return false;
} }
int ViEFrameProviderBase::NumberOfRegisteredFrameCallbacks() { int ViEFrameProviderBase::NumberOfRegisteredFrameCallbacks() {
CriticalSectionScoped cs(provider_cs_.get()); CriticalSectionScoped cs(provider_cs_.get());
return frame_callbacks_.Size(); return frame_callbacks_.size();
} }
} // namespac webrtc } // namespac webrtc

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
* *
* Use of this source code is governed by a BSD-style license * 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 * that can be found in the LICENSE file in the root of the source
@ -11,8 +11,9 @@
#ifndef WEBRTC_VIDEO_ENGINE_VIE_FRAME_PROVIDER_BASE_H_ #ifndef WEBRTC_VIDEO_ENGINE_VIE_FRAME_PROVIDER_BASE_H_
#define WEBRTC_VIDEO_ENGINE_VIE_FRAME_PROVIDER_BASE_H_ #define WEBRTC_VIDEO_ENGINE_VIE_FRAME_PROVIDER_BASE_H_
#include "modules/interface/module_common_types.h" #include <vector>
#include "system_wrappers/interface/map_wrapper.h"
#include "common_types.h"
#include "system_wrappers/interface/scoped_ptr.h" #include "system_wrappers/interface/scoped_ptr.h"
#include "typedefs.h" #include "typedefs.h"
@ -20,6 +21,7 @@ namespace webrtc {
class CriticalSectionWrapper; class CriticalSectionWrapper;
class VideoEncoder; class VideoEncoder;
class VideoFrame;
// ViEFrameCallback shall be implemented by all classes receiving frames from a // ViEFrameCallback shall be implemented by all classes receiving frames from a
// frame provider. // frame provider.
@ -86,11 +88,12 @@ class ViEFrameProviderBase {
int engine_id_; int engine_id_;
// Frame callbacks. // Frame callbacks.
MapWrapper frame_callbacks_; typedef std::vector<ViEFrameCallback*> FrameCallbacks;
FrameCallbacks frame_callbacks_;
scoped_ptr<CriticalSectionWrapper> provider_cs_; scoped_ptr<CriticalSectionWrapper> provider_cs_;
private: private:
VideoFrame* extra_frame_; scoped_ptr<VideoFrame> extra_frame_;
int frame_delay_; int frame_delay_;
}; };