Removes usage of ListWrapper from several files.
BUG=2164 R=andrew@webrtc.org, pbos@webrtc.org Review URL: https://webrtc-codereview.appspot.com/6269004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@5373 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
parent
d0b436a935
commit
79cf3acc79
@ -12,9 +12,9 @@
|
|||||||
#define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_
|
#define WEBRTC_MODULES_AUDIO_CONFERENCE_MIXER_SOURCE_MEMORY_POOL_GENERIC_H_
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -40,7 +40,7 @@ private:
|
|||||||
|
|
||||||
bool _terminate;
|
bool _terminate;
|
||||||
|
|
||||||
ListWrapper _memoryPool;
|
std::list<MemoryType*> _memoryPool;
|
||||||
|
|
||||||
uint32_t _initialPoolSize;
|
uint32_t _initialPoolSize;
|
||||||
uint32_t _createdMemory;
|
uint32_t _createdMemory;
|
||||||
@ -51,7 +51,6 @@ template<class MemoryType>
|
|||||||
MemoryPoolImpl<MemoryType>::MemoryPoolImpl(int32_t initialPoolSize)
|
MemoryPoolImpl<MemoryType>::MemoryPoolImpl(int32_t initialPoolSize)
|
||||||
: _crit(CriticalSectionWrapper::CreateCriticalSection()),
|
: _crit(CriticalSectionWrapper::CreateCriticalSection()),
|
||||||
_terminate(false),
|
_terminate(false),
|
||||||
_memoryPool(),
|
|
||||||
_initialPoolSize(initialPoolSize),
|
_initialPoolSize(initialPoolSize),
|
||||||
_createdMemory(0),
|
_createdMemory(0),
|
||||||
_outstandingMemory(0)
|
_outstandingMemory(0)
|
||||||
@ -76,20 +75,17 @@ int32_t MemoryPoolImpl<MemoryType>::PopMemory(MemoryType*& memory)
|
|||||||
memory = NULL;
|
memory = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ListItem* item = _memoryPool.First();
|
if (_memoryPool.empty()) {
|
||||||
if(item == NULL)
|
|
||||||
{
|
|
||||||
// _memoryPool empty create new memory.
|
// _memoryPool empty create new memory.
|
||||||
CreateMemory(_initialPoolSize);
|
CreateMemory(_initialPoolSize);
|
||||||
item = _memoryPool.First();
|
if(_memoryPool.empty())
|
||||||
if(item == NULL)
|
|
||||||
{
|
{
|
||||||
memory = NULL;
|
memory = NULL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
memory = static_cast<MemoryType*>(item->GetItem());
|
memory = _memoryPool.front();
|
||||||
_memoryPool.Erase(item);
|
_memoryPool.pop_front();
|
||||||
_outstandingMemory++;
|
_outstandingMemory++;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -103,7 +99,7 @@ int32_t MemoryPoolImpl<MemoryType>::PushMemory(MemoryType*& memory)
|
|||||||
}
|
}
|
||||||
CriticalSectionScoped cs(_crit);
|
CriticalSectionScoped cs(_crit);
|
||||||
_outstandingMemory--;
|
_outstandingMemory--;
|
||||||
if(_memoryPool.GetSize() > (_initialPoolSize << 1))
|
if(_memoryPool.size() > (_initialPoolSize << 1))
|
||||||
{
|
{
|
||||||
// Reclaim memory if less than half of the pool is unused.
|
// Reclaim memory if less than half of the pool is unused.
|
||||||
_createdMemory--;
|
_createdMemory--;
|
||||||
@ -111,7 +107,7 @@ int32_t MemoryPoolImpl<MemoryType>::PushMemory(MemoryType*& memory)
|
|||||||
memory = NULL;
|
memory = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_memoryPool.PushBack(static_cast<void*>(memory));
|
_memoryPool.push_back(memory);
|
||||||
memory = NULL;
|
memory = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -127,21 +123,15 @@ template<class MemoryType>
|
|||||||
int32_t MemoryPoolImpl<MemoryType>::Terminate()
|
int32_t MemoryPoolImpl<MemoryType>::Terminate()
|
||||||
{
|
{
|
||||||
CriticalSectionScoped cs(_crit);
|
CriticalSectionScoped cs(_crit);
|
||||||
assert(_createdMemory == _outstandingMemory + _memoryPool.GetSize());
|
assert(_createdMemory == _outstandingMemory + _memoryPool.size());
|
||||||
|
|
||||||
_terminate = true;
|
_terminate = true;
|
||||||
// Reclaim all memory.
|
// Reclaim all memory.
|
||||||
while(_createdMemory > 0)
|
while(_createdMemory > 0)
|
||||||
{
|
{
|
||||||
ListItem* item = _memoryPool.First();
|
MemoryType* memory = _memoryPool.front();
|
||||||
if(item == NULL)
|
_memoryPool.pop_front();
|
||||||
{
|
|
||||||
// There is memory that hasn't been returned yet.
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
MemoryType* memory = static_cast<MemoryType*>(item->GetItem());
|
|
||||||
delete memory;
|
delete memory;
|
||||||
_memoryPool.Erase(item);
|
|
||||||
_createdMemory--;
|
_createdMemory--;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -158,7 +148,7 @@ int32_t MemoryPoolImpl<MemoryType>::CreateMemory(
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
_memoryPool.PushBack(static_cast<void*>(memory));
|
_memoryPool.push_back(memory);
|
||||||
_createdMemory++;
|
_createdMemory++;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -37,15 +37,6 @@ const char* RecordedMicrophoneBoostFile =
|
|||||||
const char* RecordedMicrophoneAGCFile = "recorded_microphone_AGC_mono_48.pcm";
|
const char* RecordedMicrophoneAGCFile = "recorded_microphone_AGC_mono_48.pcm";
|
||||||
const char* RecordedSpeakerFile = "recorded_speaker_48.pcm";
|
const char* RecordedSpeakerFile = "recorded_speaker_48.pcm";
|
||||||
|
|
||||||
struct AudioPacket
|
|
||||||
{
|
|
||||||
uint8_t dataBuffer[4 * 960];
|
|
||||||
uint16_t nSamples;
|
|
||||||
uint16_t nBytesPerSample;
|
|
||||||
uint8_t nChannels;
|
|
||||||
uint32_t samplesPerSec;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper functions
|
// Helper functions
|
||||||
#if !defined(WEBRTC_IOS)
|
#if !defined(WEBRTC_IOS)
|
||||||
char* GetFilename(char* filename)
|
char* GetFilename(char* filename)
|
||||||
@ -103,8 +94,7 @@ AudioTransportImpl::AudioTransportImpl(AudioDeviceModule* audioDevice) :
|
|||||||
_loopBackMeasurements(false),
|
_loopBackMeasurements(false),
|
||||||
_playFile(*FileWrapper::Create()),
|
_playFile(*FileWrapper::Create()),
|
||||||
_recCount(0),
|
_recCount(0),
|
||||||
_playCount(0),
|
_playCount(0)
|
||||||
_audioList()
|
|
||||||
{
|
{
|
||||||
_resampler.Reset(48000, 48000, kResamplerSynchronousStereo);
|
_resampler.Reset(48000, 48000, kResamplerSynchronousStereo);
|
||||||
}
|
}
|
||||||
@ -115,18 +105,9 @@ AudioTransportImpl::~AudioTransportImpl()
|
|||||||
_playFile.CloseFile();
|
_playFile.CloseFile();
|
||||||
delete &_playFile;
|
delete &_playFile;
|
||||||
|
|
||||||
while (!_audioList.Empty())
|
for (AudioPacketList::iterator iter = _audioList.begin();
|
||||||
{
|
iter != _audioList.end(); ++iter) {
|
||||||
ListItem* item = _audioList.First();
|
delete *iter;
|
||||||
if (item)
|
|
||||||
{
|
|
||||||
AudioPacket* packet = static_cast<AudioPacket*> (item->GetItem());
|
|
||||||
if (packet)
|
|
||||||
{
|
|
||||||
delete packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_audioList.PopFront();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,19 +133,11 @@ void AudioTransportImpl::SetFullDuplex(bool enable)
|
|||||||
{
|
{
|
||||||
_fullDuplex = enable;
|
_fullDuplex = enable;
|
||||||
|
|
||||||
while (!_audioList.Empty())
|
for (AudioPacketList::iterator iter = _audioList.begin();
|
||||||
{
|
iter != _audioList.end(); ++iter) {
|
||||||
ListItem* item = _audioList.First();
|
delete *iter;
|
||||||
if (item)
|
|
||||||
{
|
|
||||||
AudioPacket* packet = static_cast<AudioPacket*> (item->GetItem());
|
|
||||||
if (packet)
|
|
||||||
{
|
|
||||||
delete packet;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_audioList.PopFront();
|
|
||||||
}
|
}
|
||||||
|
_audioList.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
||||||
@ -179,7 +152,7 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
|||||||
const bool keyPressed,
|
const bool keyPressed,
|
||||||
uint32_t& newMicLevel)
|
uint32_t& newMicLevel)
|
||||||
{
|
{
|
||||||
if (_fullDuplex && _audioList.GetSize() < 15)
|
if (_fullDuplex && _audioList.size() < 15)
|
||||||
{
|
{
|
||||||
AudioPacket* packet = new AudioPacket();
|
AudioPacket* packet = new AudioPacket();
|
||||||
memcpy(packet->dataBuffer, audioSamples, nSamples * nBytesPerSample);
|
memcpy(packet->dataBuffer, audioSamples, nSamples * nBytesPerSample);
|
||||||
@ -187,7 +160,7 @@ int32_t AudioTransportImpl::RecordedDataIsAvailable(
|
|||||||
packet->nBytesPerSample = nBytesPerSample;
|
packet->nBytesPerSample = nBytesPerSample;
|
||||||
packet->nChannels = nChannels;
|
packet->nChannels = nChannels;
|
||||||
packet->samplesPerSec = samplesPerSec;
|
packet->samplesPerSec = samplesPerSec;
|
||||||
_audioList.PushBack(packet);
|
_audioList.push_back(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
_recCount++;
|
_recCount++;
|
||||||
@ -323,14 +296,14 @@ int32_t AudioTransportImpl::NeedMorePlayData(
|
|||||||
{
|
{
|
||||||
if (_fullDuplex)
|
if (_fullDuplex)
|
||||||
{
|
{
|
||||||
if (_audioList.Empty())
|
if (_audioList.empty())
|
||||||
{
|
{
|
||||||
// use zero stuffing when not enough data
|
// use zero stuffing when not enough data
|
||||||
memset(audioSamples, 0, nBytesPerSample * nSamples);
|
memset(audioSamples, 0, nBytesPerSample * nSamples);
|
||||||
} else
|
} else
|
||||||
{
|
{
|
||||||
ListItem* item = _audioList.First();
|
AudioPacket* packet = _audioList.front();
|
||||||
AudioPacket* packet = static_cast<AudioPacket*> (item->GetItem());
|
_audioList.pop_front();
|
||||||
if (packet)
|
if (packet)
|
||||||
{
|
{
|
||||||
int ret(0);
|
int ret(0);
|
||||||
@ -441,7 +414,6 @@ int32_t AudioTransportImpl::NeedMorePlayData(
|
|||||||
nSamplesOut = nSamples;
|
nSamplesOut = nSamples;
|
||||||
delete packet;
|
delete packet;
|
||||||
}
|
}
|
||||||
_audioList.PopFront();
|
|
||||||
}
|
}
|
||||||
} // if (_fullDuplex)
|
} // if (_fullDuplex)
|
||||||
|
|
||||||
@ -531,12 +503,12 @@ int32_t AudioTransportImpl::NeedMorePlayData(
|
|||||||
{
|
{
|
||||||
uint16_t recDelayMS(0);
|
uint16_t recDelayMS(0);
|
||||||
uint16_t playDelayMS(0);
|
uint16_t playDelayMS(0);
|
||||||
uint32_t nItemsInList(0);
|
size_t nItemsInList(0);
|
||||||
|
|
||||||
nItemsInList = _audioList.GetSize();
|
nItemsInList = _audioList.size();
|
||||||
EXPECT_EQ(0, _audioDevice->RecordingDelay(&recDelayMS));
|
EXPECT_EQ(0, _audioDevice->RecordingDelay(&recDelayMS));
|
||||||
EXPECT_EQ(0, _audioDevice->PlayoutDelay(&playDelayMS));
|
EXPECT_EQ(0, _audioDevice->PlayoutDelay(&playDelayMS));
|
||||||
TEST_LOG("Delay (rec+play)+buf: %3u (%3u+%3u)+%3u [ms]\n",
|
TEST_LOG("Delay (rec+play)+buf: %3zu (%3u+%3u)+%3zu [ms]\n",
|
||||||
recDelayMS + playDelayMS + 10 * (nItemsInList + 1),
|
recDelayMS + playDelayMS + 10 * (nItemsInList + 1),
|
||||||
recDelayMS, playDelayMS, 10 * (nItemsInList + 1));
|
recDelayMS, playDelayMS, 10 * (nItemsInList + 1));
|
||||||
|
|
||||||
|
@ -13,13 +13,13 @@
|
|||||||
|
|
||||||
#include "webrtc/modules/audio_device/audio_device_utility.h"
|
#include "webrtc/modules/audio_device/audio_device_utility.h"
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "webrtc/common_audio/resampler/include/resampler.h"
|
#include "webrtc/common_audio/resampler/include/resampler.h"
|
||||||
#include "webrtc/modules/audio_device/include/audio_device.h"
|
#include "webrtc/modules/audio_device/include/audio_device.h"
|
||||||
#include "webrtc/modules/audio_device/test/audio_device_test_defines.h"
|
#include "webrtc/modules/audio_device/test/audio_device_test_defines.h"
|
||||||
#include "webrtc/system_wrappers/interface/file_wrapper.h"
|
#include "webrtc/system_wrappers/interface/file_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
#if defined(WEBRTC_IOS) || defined(ANDROID)
|
#if defined(WEBRTC_IOS) || defined(ANDROID)
|
||||||
@ -60,6 +60,15 @@ enum TestType
|
|||||||
TTTest = 66,
|
TTTest = 66,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct AudioPacket
|
||||||
|
{
|
||||||
|
uint8_t dataBuffer[4 * 960];
|
||||||
|
uint16_t nSamples;
|
||||||
|
uint16_t nBytesPerSample;
|
||||||
|
uint8_t nChannels;
|
||||||
|
uint32_t samplesPerSec;
|
||||||
|
};
|
||||||
|
|
||||||
class ProcessThread;
|
class ProcessThread;
|
||||||
|
|
||||||
namespace webrtc
|
namespace webrtc
|
||||||
@ -165,6 +174,7 @@ public:
|
|||||||
;
|
;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<AudioPacket*> AudioPacketList;
|
||||||
AudioDeviceModule* _audioDevice;
|
AudioDeviceModule* _audioDevice;
|
||||||
|
|
||||||
bool _playFromFile;
|
bool _playFromFile;
|
||||||
@ -181,8 +191,7 @@ private:
|
|||||||
|
|
||||||
uint32_t _recCount;
|
uint32_t _recCount;
|
||||||
uint32_t _playCount;
|
uint32_t _playCount;
|
||||||
|
AudioPacketList _audioList;
|
||||||
ListWrapper _audioList;
|
|
||||||
|
|
||||||
Resampler _resampler;
|
Resampler _resampler;
|
||||||
};
|
};
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/file_wrapper.h"
|
#include "webrtc/system_wrappers/interface/file_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/trace.h"
|
#include "webrtc/system_wrappers/interface/trace.h"
|
||||||
|
|
||||||
// http://msdn2.microsoft.com/en-us/library/ms779636.aspx
|
// http://msdn2.microsoft.com/en-us/library/ms779636.aspx
|
||||||
@ -178,8 +177,7 @@ AviFile::AviFile()
|
|||||||
_videoCodecConfigParamsLength(0),
|
_videoCodecConfigParamsLength(0),
|
||||||
_videoStreamDataChunkPrefix(0),
|
_videoStreamDataChunkPrefix(0),
|
||||||
_audioStreamDataChunkPrefix(0),
|
_audioStreamDataChunkPrefix(0),
|
||||||
_created(false),
|
_created(false)
|
||||||
_indexList(new ListWrapper())
|
|
||||||
{
|
{
|
||||||
ResetComplexMembers();
|
ResetComplexMembers();
|
||||||
}
|
}
|
||||||
@ -188,7 +186,6 @@ AviFile::~AviFile()
|
|||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
|
|
||||||
delete _indexList;
|
|
||||||
delete[] _videoCodecConfigParams;
|
delete[] _videoCodecConfigParams;
|
||||||
delete _crit;
|
delete _crit;
|
||||||
}
|
}
|
||||||
@ -1712,21 +1709,11 @@ uint32_t AviFile::StreamAndTwoCharCodeToTag(int32_t streamNum,
|
|||||||
|
|
||||||
void AviFile::ClearIndexList()
|
void AviFile::ClearIndexList()
|
||||||
{
|
{
|
||||||
while (!_indexList->Empty())
|
for (IndexList::iterator iter = _indexList.begin();
|
||||||
{
|
iter != _indexList.end(); ++iter) {
|
||||||
ListItem* listItem = _indexList->First();
|
delete *iter;
|
||||||
if (listItem == 0)
|
}
|
||||||
{
|
_indexList.clear();
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
AVIINDEXENTRY* item = static_cast<AVIINDEXENTRY*>(listItem->GetItem());
|
|
||||||
if (item != NULL)
|
|
||||||
{
|
|
||||||
delete item;
|
|
||||||
}
|
|
||||||
_indexList->PopFront();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AviFile::AddChunkToIndexList(uint32_t inChunkId,
|
void AviFile::AddChunkToIndexList(uint32_t inChunkId,
|
||||||
@ -1734,7 +1721,7 @@ void AviFile::AddChunkToIndexList(uint32_t inChunkId,
|
|||||||
uint32_t inOffset,
|
uint32_t inOffset,
|
||||||
uint32_t inSize)
|
uint32_t inSize)
|
||||||
{
|
{
|
||||||
_indexList->PushBack(new AVIINDEXENTRY(inChunkId, inFlags, inOffset,
|
_indexList.push_back(new AVIINDEXENTRY(inChunkId, inFlags, inOffset,
|
||||||
inSize));
|
inSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1747,19 +1734,13 @@ void AviFile::WriteIndex()
|
|||||||
_bytesWritten += PutLE32(0);
|
_bytesWritten += PutLE32(0);
|
||||||
const size_t idxChunkSize = _bytesWritten;
|
const size_t idxChunkSize = _bytesWritten;
|
||||||
|
|
||||||
for (ListItem* listItem = _indexList->First();
|
for (IndexList::iterator iter = _indexList.begin();
|
||||||
listItem != NULL;
|
iter != _indexList.end(); ++iter) {
|
||||||
listItem = _indexList->Next(listItem))
|
const AVIINDEXENTRY* item = *iter;
|
||||||
{
|
_bytesWritten += PutLE32(item->ckid);
|
||||||
const AVIINDEXENTRY* item =
|
_bytesWritten += PutLE32(item->dwFlags);
|
||||||
static_cast<AVIINDEXENTRY*>(listItem->GetItem());
|
_bytesWritten += PutLE32(item->dwChunkOffset);
|
||||||
if (item != NULL)
|
_bytesWritten += PutLE32(item->dwChunkLength);
|
||||||
{
|
|
||||||
_bytesWritten += PutLE32(item->ckid);
|
|
||||||
_bytesWritten += PutLE32(item->dwFlags);
|
|
||||||
_bytesWritten += PutLE32(item->dwChunkOffset);
|
|
||||||
_bytesWritten += PutLE32(item->dwChunkLength);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PutLE32LengthFromCurrent(static_cast<long>(idxChunkSize));
|
PutLE32LengthFromCurrent(static_cast<long>(idxChunkSize));
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,12 @@
|
|||||||
#define WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_
|
#define WEBRTC_MODULES_MEDIA_FILE_SOURCE_AVI_FILE_H_
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
class CriticalSectionWrapper;
|
class CriticalSectionWrapper;
|
||||||
class ListWrapper;
|
|
||||||
|
|
||||||
struct AVISTREAMHEADER
|
struct AVISTREAMHEADER
|
||||||
{
|
{
|
||||||
@ -194,6 +194,7 @@ private:
|
|||||||
void WriteIndex();
|
void WriteIndex();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<AVIINDEXENTRY*> IndexList;
|
||||||
struct AVIMAINHEADER
|
struct AVIMAINHEADER
|
||||||
{
|
{
|
||||||
AVIMAINHEADER();
|
AVIMAINHEADER();
|
||||||
@ -269,7 +270,7 @@ private:
|
|||||||
uint32_t _audioStreamDataChunkPrefix;
|
uint32_t _audioStreamDataChunkPrefix;
|
||||||
bool _created;
|
bool _created;
|
||||||
|
|
||||||
ListWrapper* _indexList; // Elements are of type AVIINDEXENTRY.
|
IndexList _indexList;
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
virtual int32_t Start() = 0;
|
virtual int32_t Start() = 0;
|
||||||
virtual int32_t Stop() = 0;
|
virtual int32_t Stop() = 0;
|
||||||
|
|
||||||
virtual int32_t RegisterModule(const Module* module) = 0;
|
virtual int32_t RegisterModule(Module* module) = 0;
|
||||||
virtual int32_t DeRegisterModule(const Module* module) = 0;
|
virtual int32_t DeRegisterModule(const Module* module) = 0;
|
||||||
protected:
|
protected:
|
||||||
virtual ~ProcessThread();
|
virtual ~ProcessThread();
|
||||||
|
@ -342,31 +342,6 @@ int32_t FileRecorderImpl::WriteEncodedAudioData(
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
|
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
|
||||||
class AudioFrameFileInfo
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
AudioFrameFileInfo(const int8_t* audioData,
|
|
||||||
const uint16_t audioSize,
|
|
||||||
const uint16_t audioMS,
|
|
||||||
const TickTime& playoutTS)
|
|
||||||
: _audioData(), _audioSize(audioSize), _audioMS(audioMS),
|
|
||||||
_playoutTS(playoutTS)
|
|
||||||
{
|
|
||||||
if(audioSize > MAX_AUDIO_BUFFER_IN_BYTES)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
_audioSize = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
memcpy(_audioData, audioData, audioSize);
|
|
||||||
};
|
|
||||||
// TODO (hellner): either turn into a struct or provide get/set functions.
|
|
||||||
int8_t _audioData[MAX_AUDIO_BUFFER_IN_BYTES];
|
|
||||||
uint16_t _audioSize;
|
|
||||||
uint16_t _audioMS;
|
|
||||||
TickTime _playoutTS;
|
|
||||||
};
|
|
||||||
|
|
||||||
AviRecorder::AviRecorder(uint32_t instanceID, FileFormats fileFormat)
|
AviRecorder::AviRecorder(uint32_t instanceID, FileFormats fileFormat)
|
||||||
: FileRecorderImpl(instanceID, fileFormat),
|
: FileRecorderImpl(instanceID, fileFormat),
|
||||||
_videoOnly(false),
|
_videoOnly(false),
|
||||||
@ -545,49 +520,39 @@ int32_t AviRecorder::ProcessAudio()
|
|||||||
{
|
{
|
||||||
// Syncronize audio to the current frame to process by throwing away
|
// Syncronize audio to the current frame to process by throwing away
|
||||||
// audio samples with older timestamp than the video frame.
|
// audio samples with older timestamp than the video frame.
|
||||||
uint32_t numberOfAudioElements =
|
size_t numberOfAudioElements =
|
||||||
_audioFramesToWrite.GetSize();
|
_audioFramesToWrite.size();
|
||||||
for (uint32_t i = 0; i < numberOfAudioElements; ++i)
|
for (size_t i = 0; i < numberOfAudioElements; ++i)
|
||||||
{
|
{
|
||||||
AudioFrameFileInfo* frameInfo =
|
AudioFrameFileInfo* frameInfo = _audioFramesToWrite.front();
|
||||||
(AudioFrameFileInfo*)_audioFramesToWrite.First()->GetItem();
|
if(TickTime::TicksToMilliseconds(
|
||||||
if(frameInfo)
|
frameInfo->_playoutTS.Ticks()) <
|
||||||
|
frameToProcess->render_time_ms())
|
||||||
{
|
{
|
||||||
if(TickTime::TicksToMilliseconds(
|
delete frameInfo;
|
||||||
frameInfo->_playoutTS.Ticks()) <
|
_audioFramesToWrite.pop_front();
|
||||||
frameToProcess->render_time_ms())
|
} else
|
||||||
{
|
{
|
||||||
delete frameInfo;
|
break;
|
||||||
_audioFramesToWrite.PopFront();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Write all audio up to current timestamp.
|
// Write all audio up to current timestamp.
|
||||||
int32_t error = 0;
|
int32_t error = 0;
|
||||||
uint32_t numberOfAudioElements = _audioFramesToWrite.GetSize();
|
size_t numberOfAudioElements = _audioFramesToWrite.size();
|
||||||
for (uint32_t i = 0; i < numberOfAudioElements; ++i)
|
for (size_t i = 0; i < numberOfAudioElements; ++i)
|
||||||
{
|
{
|
||||||
AudioFrameFileInfo* frameInfo =
|
AudioFrameFileInfo* frameInfo = _audioFramesToWrite.front();
|
||||||
(AudioFrameFileInfo*)_audioFramesToWrite.First()->GetItem();
|
if((TickTime::Now() - frameInfo->_playoutTS).Milliseconds() > 0)
|
||||||
if(frameInfo)
|
|
||||||
{
|
{
|
||||||
if((TickTime::Now() - frameInfo->_playoutTS).Milliseconds() > 0)
|
_moduleFile->IncomingAudioData(frameInfo->_audioData,
|
||||||
{
|
frameInfo->_audioSize);
|
||||||
_moduleFile->IncomingAudioData(frameInfo->_audioData,
|
_writtenAudioMS += frameInfo->_audioMS;
|
||||||
frameInfo->_audioSize);
|
delete frameInfo;
|
||||||
_writtenAudioMS += frameInfo->_audioMS;
|
_audioFramesToWrite.pop_front();
|
||||||
delete frameInfo;
|
|
||||||
_audioFramesToWrite.PopFront();
|
|
||||||
} else {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
_audioFramesToWrite.PopFront();
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
@ -762,7 +727,7 @@ int32_t AviRecorder::WriteEncodedAudioData(
|
|||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (_audioFramesToWrite.GetSize() > kMaxAudioBufferQueueLength)
|
if (_audioFramesToWrite.size() > kMaxAudioBufferQueueLength)
|
||||||
{
|
{
|
||||||
StopRecording();
|
StopRecording();
|
||||||
return -1;
|
return -1;
|
||||||
@ -771,15 +736,15 @@ int32_t AviRecorder::WriteEncodedAudioData(
|
|||||||
|
|
||||||
if(playoutTS)
|
if(playoutTS)
|
||||||
{
|
{
|
||||||
_audioFramesToWrite.PushBack(new AudioFrameFileInfo(audioBuffer,
|
_audioFramesToWrite.push_back(new AudioFrameFileInfo(audioBuffer,
|
||||||
bufferLength,
|
bufferLength,
|
||||||
millisecondsOfData,
|
millisecondsOfData,
|
||||||
*playoutTS));
|
*playoutTS));
|
||||||
} else {
|
} else {
|
||||||
_audioFramesToWrite.PushBack(new AudioFrameFileInfo(audioBuffer,
|
_audioFramesToWrite.push_back(new AudioFrameFileInfo(audioBuffer,
|
||||||
bufferLength,
|
bufferLength,
|
||||||
millisecondsOfData,
|
millisecondsOfData,
|
||||||
TickTime::Now()));
|
TickTime::Now()));
|
||||||
}
|
}
|
||||||
_timeEvent.Set();
|
_timeEvent.Set();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#ifndef WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_
|
#ifndef WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_
|
||||||
#define WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_
|
#define WEBRTC_MODULES_UTILITY_SOURCE_FILE_RECORDER_IMPL_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/common_audio/resampler/include/resampler.h"
|
#include "webrtc/common_audio/resampler/include/resampler.h"
|
||||||
#include "webrtc/common_types.h"
|
#include "webrtc/common_types.h"
|
||||||
#include "webrtc/engine_configurations.h"
|
#include "webrtc/engine_configurations.h"
|
||||||
@ -40,6 +42,8 @@ enum { MAX_AUDIO_BUFFER_IN_SAMPLES = 60*32};
|
|||||||
enum { MAX_AUDIO_BUFFER_IN_BYTES = MAX_AUDIO_BUFFER_IN_SAMPLES*2};
|
enum { MAX_AUDIO_BUFFER_IN_BYTES = MAX_AUDIO_BUFFER_IN_SAMPLES*2};
|
||||||
enum { kMaxAudioBufferQueueLength = 100 };
|
enum { kMaxAudioBufferQueueLength = 100 };
|
||||||
|
|
||||||
|
class CriticalSectionWrapper;
|
||||||
|
|
||||||
class FileRecorderImpl : public FileRecorder
|
class FileRecorderImpl : public FileRecorder
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -103,6 +107,31 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
|
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
|
||||||
|
class AudioFrameFileInfo
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AudioFrameFileInfo(const int8_t* audioData,
|
||||||
|
const uint16_t audioSize,
|
||||||
|
const uint16_t audioMS,
|
||||||
|
const TickTime& playoutTS)
|
||||||
|
: _audioData(), _audioSize(audioSize), _audioMS(audioMS),
|
||||||
|
_playoutTS(playoutTS)
|
||||||
|
{
|
||||||
|
if(audioSize > MAX_AUDIO_BUFFER_IN_BYTES)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
_audioSize = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(_audioData, audioData, audioSize);
|
||||||
|
};
|
||||||
|
// TODO (hellner): either turn into a struct or provide get/set functions.
|
||||||
|
int8_t _audioData[MAX_AUDIO_BUFFER_IN_BYTES];
|
||||||
|
uint16_t _audioSize;
|
||||||
|
uint16_t _audioMS;
|
||||||
|
TickTime _playoutTS;
|
||||||
|
};
|
||||||
|
|
||||||
class AviRecorder : public FileRecorderImpl
|
class AviRecorder : public FileRecorderImpl
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -126,6 +155,7 @@ protected:
|
|||||||
uint16_t millisecondsOfData,
|
uint16_t millisecondsOfData,
|
||||||
const TickTime* playoutTS);
|
const TickTime* playoutTS);
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<AudioFrameFileInfo*> AudioInfoList;
|
||||||
static bool Run(ThreadObj threadObj);
|
static bool Run(ThreadObj threadObj);
|
||||||
bool Process();
|
bool Process();
|
||||||
|
|
||||||
@ -141,7 +171,7 @@ private:
|
|||||||
VideoCodec _videoCodecInst;
|
VideoCodec _videoCodecInst;
|
||||||
bool _videoOnly;
|
bool _videoOnly;
|
||||||
|
|
||||||
ListWrapper _audioFramesToWrite;
|
AudioInfoList _audioFramesToWrite;
|
||||||
bool _firstAudioFrameReceived;
|
bool _firstAudioFrameReceived;
|
||||||
|
|
||||||
VideoFramesQueue* _videoFramesQueue;
|
VideoFramesQueue* _videoFramesQueue;
|
||||||
|
@ -87,25 +87,23 @@ int32_t ProcessThreadImpl::Stop()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t ProcessThreadImpl::RegisterModule(const Module* module)
|
int32_t ProcessThreadImpl::RegisterModule(Module* module)
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_critSectModules);
|
CriticalSectionScoped lock(_critSectModules);
|
||||||
|
|
||||||
// Only allow module to be registered once.
|
// Only allow module to be registered once.
|
||||||
ListItem* item = _modules.First();
|
for (ModuleList::iterator iter = _modules.begin();
|
||||||
for(uint32_t i = 0; i < _modules.GetSize() && item; i++)
|
iter != _modules.end(); ++iter) {
|
||||||
{
|
if(module == *iter)
|
||||||
if(module == item->GetItem())
|
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
item = _modules.Next(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_modules.PushFront(module);
|
_modules.push_front(module);
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
|
WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
|
||||||
"number of registered modules has increased to %d",
|
"number of registered modules has increased to %d",
|
||||||
_modules.GetSize());
|
_modules.size());
|
||||||
// Wake the thread calling ProcessThreadImpl::Process() to update the
|
// Wake the thread calling ProcessThreadImpl::Process() to update the
|
||||||
// waiting time. The waiting time for the just registered module may be
|
// waiting time. The waiting time for the just registered module may be
|
||||||
// shorter than all other registered modules.
|
// shorter than all other registered modules.
|
||||||
@ -116,19 +114,16 @@ int32_t ProcessThreadImpl::RegisterModule(const Module* module)
|
|||||||
int32_t ProcessThreadImpl::DeRegisterModule(const Module* module)
|
int32_t ProcessThreadImpl::DeRegisterModule(const Module* module)
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_critSectModules);
|
CriticalSectionScoped lock(_critSectModules);
|
||||||
|
for (ModuleList::iterator iter = _modules.begin();
|
||||||
ListItem* item = _modules.First();
|
iter != _modules.end(); ++iter) {
|
||||||
for(uint32_t i = 0; i < _modules.GetSize() && item; i++)
|
if(module == *iter)
|
||||||
{
|
|
||||||
if(module == item->GetItem())
|
|
||||||
{
|
{
|
||||||
int res = _modules.Erase(item);
|
_modules.erase(iter);
|
||||||
WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
|
WEBRTC_TRACE(kTraceInfo, kTraceUtility, -1,
|
||||||
"number of registered modules has decreased to %d",
|
"number of registered modules has decreased to %d",
|
||||||
_modules.GetSize());
|
_modules.size());
|
||||||
return res;
|
return 0;
|
||||||
}
|
}
|
||||||
item = _modules.Next(item);
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -145,16 +140,13 @@ bool ProcessThreadImpl::Process()
|
|||||||
int32_t minTimeToNext = 100;
|
int32_t minTimeToNext = 100;
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_critSectModules);
|
CriticalSectionScoped lock(_critSectModules);
|
||||||
ListItem* item = _modules.First();
|
for (ModuleList::iterator iter = _modules.begin();
|
||||||
for(uint32_t i = 0; i < _modules.GetSize() && item; i++)
|
iter != _modules.end(); ++iter) {
|
||||||
{
|
int32_t timeToNext = (*iter)->TimeUntilNextProcess();
|
||||||
int32_t timeToNext =
|
|
||||||
static_cast<Module*>(item->GetItem())->TimeUntilNextProcess();
|
|
||||||
if(minTimeToNext > timeToNext)
|
if(minTimeToNext > timeToNext)
|
||||||
{
|
{
|
||||||
minTimeToNext = timeToNext;
|
minTimeToNext = timeToNext;
|
||||||
}
|
}
|
||||||
item = _modules.Next(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,16 +164,13 @@ bool ProcessThreadImpl::Process()
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
CriticalSectionScoped lock(_critSectModules);
|
CriticalSectionScoped lock(_critSectModules);
|
||||||
ListItem* item = _modules.First();
|
for (ModuleList::iterator iter = _modules.begin();
|
||||||
for(uint32_t i = 0; i < _modules.GetSize() && item; i++)
|
iter != _modules.end(); ++iter) {
|
||||||
{
|
int32_t timeToNext = (*iter)->TimeUntilNextProcess();
|
||||||
int32_t timeToNext =
|
|
||||||
static_cast<Module*>(item->GetItem())->TimeUntilNextProcess();
|
|
||||||
if(timeToNext < 1)
|
if(timeToNext < 1)
|
||||||
{
|
{
|
||||||
static_cast<Module*>(item->GetItem())->Process();
|
(*iter)->Process();
|
||||||
}
|
}
|
||||||
item = _modules.Next(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -11,10 +11,11 @@
|
|||||||
#ifndef WEBRTC_MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_
|
#ifndef WEBRTC_MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_
|
||||||
#define WEBRTC_MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_
|
#define WEBRTC_MODULES_UTILITY_SOURCE_PROCESS_THREAD_IMPL_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/modules/utility/interface/process_thread.h"
|
#include "webrtc/modules/utility/interface/process_thread.h"
|
||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
@ -28,7 +29,7 @@ public:
|
|||||||
virtual int32_t Start();
|
virtual int32_t Start();
|
||||||
virtual int32_t Stop();
|
virtual int32_t Stop();
|
||||||
|
|
||||||
virtual int32_t RegisterModule(const Module* module);
|
virtual int32_t RegisterModule(Module* module);
|
||||||
virtual int32_t DeRegisterModule(const Module* module);
|
virtual int32_t DeRegisterModule(const Module* module);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@ -37,9 +38,10 @@ protected:
|
|||||||
bool Process();
|
bool Process();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<Module*> ModuleList;
|
||||||
EventWrapper& _timeEvent;
|
EventWrapper& _timeEvent;
|
||||||
CriticalSectionWrapper* _critSectModules;
|
CriticalSectionWrapper* _critSectModules;
|
||||||
ListWrapper _modules;
|
ModuleList _modules;
|
||||||
ThreadWrapper* _thread;
|
ThreadWrapper* _thread;
|
||||||
};
|
};
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
@ -21,36 +21,24 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
VideoFramesQueue::VideoFramesQueue()
|
VideoFramesQueue::VideoFramesQueue()
|
||||||
: _incomingFrames(),
|
: _renderDelayMs(10)
|
||||||
_renderDelayMs(10)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoFramesQueue::~VideoFramesQueue() {
|
VideoFramesQueue::~VideoFramesQueue() {
|
||||||
while (!_incomingFrames.Empty()) {
|
for (FrameList::iterator iter = _incomingFrames.begin();
|
||||||
ListItem* item = _incomingFrames.First();
|
iter != _incomingFrames.end(); ++iter) {
|
||||||
if (item) {
|
delete *iter;
|
||||||
I420VideoFrame* ptrFrame = static_cast<I420VideoFrame*>(item->GetItem());
|
|
||||||
assert(ptrFrame != NULL);
|
|
||||||
delete ptrFrame;
|
|
||||||
}
|
|
||||||
_incomingFrames.Erase(item);
|
|
||||||
}
|
}
|
||||||
while (!_emptyFrames.Empty()) {
|
for (FrameList::iterator iter = _emptyFrames.begin();
|
||||||
ListItem* item = _emptyFrames.First();
|
iter != _emptyFrames.end(); ++iter) {
|
||||||
if (item) {
|
delete *iter;
|
||||||
I420VideoFrame* ptrFrame =
|
|
||||||
static_cast<I420VideoFrame*>(item->GetItem());
|
|
||||||
assert(ptrFrame != NULL);
|
|
||||||
delete ptrFrame;
|
|
||||||
}
|
|
||||||
_emptyFrames.Erase(item);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t VideoFramesQueue::AddFrame(const I420VideoFrame& newFrame) {
|
int32_t VideoFramesQueue::AddFrame(const I420VideoFrame& newFrame) {
|
||||||
if (newFrame.native_handle() != NULL) {
|
if (newFrame.native_handle() != NULL) {
|
||||||
_incomingFrames.PushBack(new TextureVideoFrame(
|
_incomingFrames.push_back(new TextureVideoFrame(
|
||||||
static_cast<NativeHandle*>(newFrame.native_handle()),
|
static_cast<NativeHandle*>(newFrame.native_handle()),
|
||||||
newFrame.width(),
|
newFrame.width(),
|
||||||
newFrame.height(),
|
newFrame.height(),
|
||||||
@ -61,15 +49,12 @@ int32_t VideoFramesQueue::AddFrame(const I420VideoFrame& newFrame) {
|
|||||||
|
|
||||||
I420VideoFrame* ptrFrameToAdd = NULL;
|
I420VideoFrame* ptrFrameToAdd = NULL;
|
||||||
// Try to re-use a VideoFrame. Only allocate new memory if it is necessary.
|
// Try to re-use a VideoFrame. Only allocate new memory if it is necessary.
|
||||||
if (!_emptyFrames.Empty()) {
|
if (!_emptyFrames.empty()) {
|
||||||
ListItem* item = _emptyFrames.First();
|
ptrFrameToAdd = _emptyFrames.front();
|
||||||
if (item) {
|
_emptyFrames.pop_front();
|
||||||
ptrFrameToAdd = static_cast<I420VideoFrame*>(item->GetItem());
|
|
||||||
_emptyFrames.Erase(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!ptrFrameToAdd) {
|
if (!ptrFrameToAdd) {
|
||||||
if (_emptyFrames.GetSize() + _incomingFrames.GetSize() >
|
if (_emptyFrames.size() + _incomingFrames.size() >
|
||||||
KMaxNumberOfFrames) {
|
KMaxNumberOfFrames) {
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1,
|
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, -1,
|
||||||
"%s: too many frames, limit: %d", __FUNCTION__,
|
"%s: too many frames, limit: %d", __FUNCTION__,
|
||||||
@ -79,17 +64,12 @@ int32_t VideoFramesQueue::AddFrame(const I420VideoFrame& newFrame) {
|
|||||||
|
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, -1,
|
WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, -1,
|
||||||
"%s: allocating buffer %d", __FUNCTION__,
|
"%s: allocating buffer %d", __FUNCTION__,
|
||||||
_emptyFrames.GetSize() + _incomingFrames.GetSize());
|
_emptyFrames.size() + _incomingFrames.size());
|
||||||
|
|
||||||
ptrFrameToAdd = new I420VideoFrame();
|
ptrFrameToAdd = new I420VideoFrame();
|
||||||
if (!ptrFrameToAdd) {
|
|
||||||
WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, -1,
|
|
||||||
"%s: could not create new frame for", __FUNCTION__);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
ptrFrameToAdd->CopyFrame(newFrame);
|
ptrFrameToAdd->CopyFrame(newFrame);
|
||||||
_incomingFrames.PushBack(ptrFrameToAdd);
|
_incomingFrames.push_back(ptrFrameToAdd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,20 +79,16 @@ int32_t VideoFramesQueue::AddFrame(const I420VideoFrame& newFrame) {
|
|||||||
// Recycle all frames that are older than the most recent frame.
|
// Recycle all frames that are older than the most recent frame.
|
||||||
I420VideoFrame* VideoFramesQueue::FrameToRecord() {
|
I420VideoFrame* VideoFramesQueue::FrameToRecord() {
|
||||||
I420VideoFrame* ptrRenderFrame = NULL;
|
I420VideoFrame* ptrRenderFrame = NULL;
|
||||||
ListItem* item = _incomingFrames.First();
|
for (FrameList::iterator iter = _incomingFrames.begin();
|
||||||
while(item) {
|
iter != _incomingFrames.end(); ++iter) {
|
||||||
I420VideoFrame* ptrOldestFrameInList =
|
I420VideoFrame* ptrOldestFrameInList = *iter;
|
||||||
static_cast<I420VideoFrame*>(item->GetItem());
|
|
||||||
if (ptrOldestFrameInList->render_time_ms() <=
|
if (ptrOldestFrameInList->render_time_ms() <=
|
||||||
TickTime::MillisecondTimestamp() + _renderDelayMs) {
|
TickTime::MillisecondTimestamp() + _renderDelayMs) {
|
||||||
if (ptrRenderFrame) {
|
// List is traversed beginning to end. If ptrRenderFrame is not
|
||||||
// List is traversed beginning to end. If ptrRenderFrame is not
|
// NULL it must be the first, and thus oldest, VideoFrame in the
|
||||||
// NULL it must be the first, and thus oldest, VideoFrame in the
|
// queue. It can be recycled.
|
||||||
// queue. It can be recycled.
|
ReturnFrame(ptrRenderFrame);
|
||||||
ReturnFrame(ptrRenderFrame);
|
iter = _incomingFrames.erase(iter);
|
||||||
_incomingFrames.PopFront();
|
|
||||||
}
|
|
||||||
item = _incomingFrames.Next(item);
|
|
||||||
ptrRenderFrame = ptrOldestFrameInList;
|
ptrRenderFrame = ptrOldestFrameInList;
|
||||||
} else {
|
} else {
|
||||||
// All VideoFrames following this one will be even newer. No match
|
// All VideoFrames following this one will be even newer. No match
|
||||||
@ -131,7 +107,7 @@ int32_t VideoFramesQueue::ReturnFrame(I420VideoFrame* ptrOldFrame) {
|
|||||||
ptrOldFrame->set_height(0);
|
ptrOldFrame->set_height(0);
|
||||||
ptrOldFrame->set_render_time_ms(0);
|
ptrOldFrame->set_render_time_ms(0);
|
||||||
ptrOldFrame->ResetSize();
|
ptrOldFrame->ResetSize();
|
||||||
_emptyFrames.PushBack(ptrOldFrame);
|
_emptyFrames.push_back(ptrOldFrame);
|
||||||
} else {
|
} else {
|
||||||
delete ptrOldFrame;
|
delete ptrOldFrame;
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,10 @@
|
|||||||
|
|
||||||
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
|
#ifdef WEBRTC_MODULE_UTILITY_VIDEO
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/common_video/interface/i420_video_frame.h"
|
#include "webrtc/common_video/interface/i420_video_frame.h"
|
||||||
#include "webrtc/engine_configurations.h"
|
#include "webrtc/engine_configurations.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
@ -42,6 +43,7 @@ class VideoFramesQueue {
|
|||||||
int32_t ReturnFrame(I420VideoFrame* ptrOldFrame);
|
int32_t ReturnFrame(I420VideoFrame* ptrOldFrame);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<I420VideoFrame*> FrameList;
|
||||||
// Don't allow the buffer to expand beyond KMaxNumberOfFrames VideoFrames.
|
// Don't allow the buffer to expand beyond KMaxNumberOfFrames VideoFrames.
|
||||||
// 300 frames correspond to 10 seconds worth of frames at 30 fps.
|
// 300 frames correspond to 10 seconds worth of frames at 30 fps.
|
||||||
enum {KMaxNumberOfFrames = 300};
|
enum {KMaxNumberOfFrames = 300};
|
||||||
@ -49,9 +51,9 @@ class VideoFramesQueue {
|
|||||||
// List of VideoFrame pointers. The list is sorted in the order of when the
|
// List of VideoFrame pointers. The list is sorted in the order of when the
|
||||||
// VideoFrame was inserted into the list. The first VideoFrame in the list
|
// VideoFrame was inserted into the list. The first VideoFrame in the list
|
||||||
// was inserted first.
|
// was inserted first.
|
||||||
ListWrapper _incomingFrames;
|
FrameList _incomingFrames;
|
||||||
// A list of frames that are free to be re-used.
|
// A list of frames that are free to be re-used.
|
||||||
ListWrapper _emptyFrames;
|
FrameList _emptyFrames;
|
||||||
|
|
||||||
// Estimated render delay.
|
// Estimated render delay.
|
||||||
uint32_t _renderDelayMs;
|
uint32_t _renderDelayMs;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
* be found in the AUTHORS file in the root of the source tree.
|
* be found in the AUTHORS file in the root of the source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "webrtc/modules/video_render//video_render_frames.h"
|
#include "webrtc/modules/video_render/video_render_frames.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
@ -19,13 +19,12 @@
|
|||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
const int32_t KEventMaxWaitTimeMs = 200;
|
const uint32_t KEventMaxWaitTimeMs = 200;
|
||||||
const uint32_t kMinRenderDelayMs = 10;
|
const uint32_t kMinRenderDelayMs = 10;
|
||||||
const uint32_t kMaxRenderDelayMs= 500;
|
const uint32_t kMaxRenderDelayMs= 500;
|
||||||
|
|
||||||
VideoRenderFrames::VideoRenderFrames()
|
VideoRenderFrames::VideoRenderFrames()
|
||||||
: incoming_frames_(),
|
: render_delay_ms_(10) {
|
||||||
render_delay_ms_(10) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoRenderFrames::~VideoRenderFrames() {
|
VideoRenderFrames::~VideoRenderFrames() {
|
||||||
@ -37,7 +36,7 @@ int32_t VideoRenderFrames::AddFrame(I420VideoFrame* new_frame) {
|
|||||||
|
|
||||||
// Drop old frames only when there are other frames in the queue, otherwise, a
|
// Drop old frames only when there are other frames in the queue, otherwise, a
|
||||||
// really slow system never renders any frames.
|
// really slow system never renders any frames.
|
||||||
if (!incoming_frames_.Empty() &&
|
if (!incoming_frames_.empty() &&
|
||||||
new_frame->render_time_ms() + KOldRenderTimestampMS < time_now) {
|
new_frame->render_time_ms() + KOldRenderTimestampMS < time_now) {
|
||||||
WEBRTC_TRACE(kTraceWarning,
|
WEBRTC_TRACE(kTraceWarning,
|
||||||
kTraceVideoRenderer,
|
kTraceVideoRenderer,
|
||||||
@ -56,26 +55,23 @@ int32_t VideoRenderFrames::AddFrame(I420VideoFrame* new_frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (new_frame->native_handle() != NULL) {
|
if (new_frame->native_handle() != NULL) {
|
||||||
incoming_frames_.PushBack(new TextureVideoFrame(
|
incoming_frames_.push_back(new TextureVideoFrame(
|
||||||
static_cast<NativeHandle*>(new_frame->native_handle()),
|
static_cast<NativeHandle*>(new_frame->native_handle()),
|
||||||
new_frame->width(),
|
new_frame->width(),
|
||||||
new_frame->height(),
|
new_frame->height(),
|
||||||
new_frame->timestamp(),
|
new_frame->timestamp(),
|
||||||
new_frame->render_time_ms()));
|
new_frame->render_time_ms()));
|
||||||
return incoming_frames_.GetSize();
|
return static_cast<int32_t>(incoming_frames_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get an empty frame
|
// Get an empty frame
|
||||||
I420VideoFrame* frame_to_add = NULL;
|
I420VideoFrame* frame_to_add = NULL;
|
||||||
if (!empty_frames_.Empty()) {
|
if (!empty_frames_.empty()) {
|
||||||
ListItem* item = empty_frames_.First();
|
frame_to_add = empty_frames_.front();
|
||||||
if (item) {
|
empty_frames_.pop_front();
|
||||||
frame_to_add = static_cast<I420VideoFrame*>(item->GetItem());
|
|
||||||
empty_frames_.Erase(item);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!frame_to_add) {
|
if (!frame_to_add) {
|
||||||
if (empty_frames_.GetSize() + incoming_frames_.GetSize() >
|
if (empty_frames_.size() + incoming_frames_.size() >
|
||||||
KMaxNumberOfFrames) {
|
KMaxNumberOfFrames) {
|
||||||
// Already allocated too many frames.
|
// Already allocated too many frames.
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer,
|
WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer,
|
||||||
@ -87,7 +83,7 @@ int32_t VideoRenderFrames::AddFrame(I420VideoFrame* new_frame) {
|
|||||||
// Allocate new memory.
|
// Allocate new memory.
|
||||||
WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, -1,
|
WEBRTC_TRACE(kTraceMemory, kTraceVideoRenderer, -1,
|
||||||
"%s: allocating buffer %d", __FUNCTION__,
|
"%s: allocating buffer %d", __FUNCTION__,
|
||||||
empty_frames_.GetSize() + incoming_frames_.GetSize());
|
empty_frames_.size() + incoming_frames_.size());
|
||||||
|
|
||||||
frame_to_add = new I420VideoFrame();
|
frame_to_add = new I420VideoFrame();
|
||||||
if (!frame_to_add) {
|
if (!frame_to_add) {
|
||||||
@ -104,33 +100,28 @@ int32_t VideoRenderFrames::AddFrame(I420VideoFrame* new_frame) {
|
|||||||
// TODO(mflodman) Change this!
|
// TODO(mflodman) Change this!
|
||||||
// Remove const ness. Copying will be costly.
|
// Remove const ness. Copying will be costly.
|
||||||
frame_to_add->SwapFrame(new_frame);
|
frame_to_add->SwapFrame(new_frame);
|
||||||
incoming_frames_.PushBack(frame_to_add);
|
incoming_frames_.push_back(frame_to_add);
|
||||||
|
|
||||||
return incoming_frames_.GetSize();
|
return static_cast<int32_t>(incoming_frames_.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
I420VideoFrame* VideoRenderFrames::FrameToRender() {
|
I420VideoFrame* VideoRenderFrames::FrameToRender() {
|
||||||
I420VideoFrame* render_frame = NULL;
|
I420VideoFrame* render_frame = NULL;
|
||||||
while (!incoming_frames_.Empty()) {
|
FrameList::iterator iter = incoming_frames_.begin();
|
||||||
ListItem* item = incoming_frames_.First();
|
while(iter != incoming_frames_.end()) {
|
||||||
if (item) {
|
I420VideoFrame* oldest_frame_in_list = *iter;
|
||||||
I420VideoFrame* oldest_frame_in_list =
|
if (oldest_frame_in_list->render_time_ms() <=
|
||||||
static_cast<I420VideoFrame*>(item->GetItem());
|
TickTime::MillisecondTimestamp() + render_delay_ms_) {
|
||||||
if (oldest_frame_in_list->render_time_ms() <=
|
// This is the oldest one so far and it's OK to render.
|
||||||
TickTime::MillisecondTimestamp() + render_delay_ms_) {
|
if (render_frame) {
|
||||||
// This is the oldest one so far and it's OK to render.
|
// This one is older than the newly found frame, remove this one.
|
||||||
if (render_frame) {
|
ReturnFrame(render_frame);
|
||||||
// This one is older than the newly found frame, remove this one.
|
|
||||||
ReturnFrame(render_frame);
|
|
||||||
}
|
|
||||||
render_frame = oldest_frame_in_list;
|
|
||||||
incoming_frames_.Erase(item);
|
|
||||||
} else {
|
|
||||||
// We can't release this one yet, we're done here.
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
render_frame = oldest_frame_in_list;
|
||||||
|
iter = incoming_frames_.erase(iter);
|
||||||
} else {
|
} else {
|
||||||
assert(false);
|
// We can't release this one yet, we're done here.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return render_frame;
|
return render_frame;
|
||||||
@ -142,7 +133,7 @@ int32_t VideoRenderFrames::ReturnFrame(I420VideoFrame* old_frame) {
|
|||||||
old_frame->ResetSize();
|
old_frame->ResetSize();
|
||||||
old_frame->set_timestamp(0);
|
old_frame->set_timestamp(0);
|
||||||
old_frame->set_render_time_ms(0);
|
old_frame->set_render_time_ms(0);
|
||||||
empty_frames_.PushBack(old_frame);
|
empty_frames_.push_back(old_frame);
|
||||||
} else {
|
} else {
|
||||||
delete old_frame;
|
delete old_frame;
|
||||||
}
|
}
|
||||||
@ -150,40 +141,29 @@ int32_t VideoRenderFrames::ReturnFrame(I420VideoFrame* old_frame) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t VideoRenderFrames::ReleaseAllFrames() {
|
int32_t VideoRenderFrames::ReleaseAllFrames() {
|
||||||
while (!incoming_frames_.Empty()) {
|
for (FrameList::iterator iter = incoming_frames_.begin();
|
||||||
ListItem* item = incoming_frames_.First();
|
iter != incoming_frames_.end(); ++iter) {
|
||||||
if (item) {
|
delete *iter;
|
||||||
I420VideoFrame* frame = static_cast<I420VideoFrame*>(item->GetItem());
|
|
||||||
assert(frame != NULL);
|
|
||||||
delete frame;
|
|
||||||
}
|
|
||||||
incoming_frames_.Erase(item);
|
|
||||||
}
|
}
|
||||||
while (!empty_frames_.Empty()) {
|
incoming_frames_.clear();
|
||||||
ListItem* item = empty_frames_.First();
|
|
||||||
if (item) {
|
for (FrameList::iterator iter = empty_frames_.begin();
|
||||||
I420VideoFrame* frame = static_cast<I420VideoFrame*>(item->GetItem());
|
iter != empty_frames_.end(); ++iter) {
|
||||||
assert(frame != NULL);
|
delete *iter;
|
||||||
delete frame;
|
|
||||||
}
|
|
||||||
empty_frames_.Erase(item);
|
|
||||||
}
|
}
|
||||||
|
empty_frames_.clear();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t VideoRenderFrames::TimeToNextFrameRelease() {
|
uint32_t VideoRenderFrames::TimeToNextFrameRelease() {
|
||||||
int64_t time_to_release = 0;
|
if (incoming_frames_.empty()) {
|
||||||
ListItem* item = incoming_frames_.First();
|
return KEventMaxWaitTimeMs;
|
||||||
if (item) {
|
}
|
||||||
I420VideoFrame* oldest_frame =
|
I420VideoFrame* oldest_frame = incoming_frames_.front();
|
||||||
static_cast<I420VideoFrame*>(item->GetItem());
|
int64_t time_to_release = oldest_frame->render_time_ms() - render_delay_ms_
|
||||||
time_to_release = oldest_frame->render_time_ms() - render_delay_ms_
|
- TickTime::MillisecondTimestamp();
|
||||||
- TickTime::MillisecondTimestamp();
|
if (time_to_release < 0) {
|
||||||
if (time_to_release < 0) {
|
time_to_release = 0;
|
||||||
time_to_release = 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
time_to_release = KEventMaxWaitTimeMs;
|
|
||||||
}
|
}
|
||||||
return static_cast<uint32_t>(time_to_release);
|
return static_cast<uint32_t>(time_to_release);
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
#ifndef WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_VIDEO_RENDER_FRAMES_H_ // NOLINT
|
#ifndef WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_VIDEO_RENDER_FRAMES_H_ // NOLINT
|
||||||
#define WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_VIDEO_RENDER_FRAMES_H_ // NOLINT
|
#define WEBRTC_MODULES_VIDEO_RENDER_MAIN_SOURCE_VIDEO_RENDER_FRAMES_H_ // NOLINT
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/modules/video_render/include/video_render.h"
|
#include "webrtc/modules/video_render/include/video_render.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
|
|
||||||
namespace webrtc {
|
namespace webrtc {
|
||||||
|
|
||||||
@ -41,6 +42,8 @@ class VideoRenderFrames {
|
|||||||
int32_t SetRenderDelay(const uint32_t render_delay);
|
int32_t SetRenderDelay(const uint32_t render_delay);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<I420VideoFrame*> FrameList;
|
||||||
|
|
||||||
// 10 seconds for 30 fps.
|
// 10 seconds for 30 fps.
|
||||||
enum { KMaxNumberOfFrames = 300 };
|
enum { KMaxNumberOfFrames = 300 };
|
||||||
// Don't render frames with timestamp older than 500ms from now.
|
// Don't render frames with timestamp older than 500ms from now.
|
||||||
@ -49,9 +52,9 @@ class VideoRenderFrames {
|
|||||||
enum { KFutureRenderTimestampMS = 10000 };
|
enum { KFutureRenderTimestampMS = 10000 };
|
||||||
|
|
||||||
// Sorted list with framed to be rendered, oldest first.
|
// Sorted list with framed to be rendered, oldest first.
|
||||||
ListWrapper incoming_frames_;
|
FrameList incoming_frames_;
|
||||||
// Empty frames.
|
// Empty frames.
|
||||||
ListWrapper empty_frames_;
|
FrameList empty_frames_;
|
||||||
|
|
||||||
// Estimated delay from a frame is released until it's rendered.
|
// Estimated delay from a frame is released until it's rendered.
|
||||||
uint32_t render_delay_ms_;
|
uint32_t render_delay_ms_;
|
||||||
|
@ -65,14 +65,11 @@ UdpSocket2ManagerWindows::~UdpSocket2ManagerWindows()
|
|||||||
}
|
}
|
||||||
StopWorkerThreads();
|
StopWorkerThreads();
|
||||||
|
|
||||||
// All threads are stopped. Safe to delete them.
|
for (WorkerList::iterator iter = _workerThreadsList.begin();
|
||||||
ListItem* pItem = NULL;
|
iter != _workerThreadsList.end(); ++iter) {
|
||||||
while((pItem = _workerThreadsList.First()) != NULL)
|
delete *iter;
|
||||||
{
|
|
||||||
delete static_cast<UdpSocket2WorkerWindows*>(pItem->GetItem());
|
|
||||||
_workerThreadsList.PopFront();
|
|
||||||
}
|
}
|
||||||
|
_workerThreadsList.clear();
|
||||||
_ioContextPool.Free();
|
_ioContextPool.Free();
|
||||||
|
|
||||||
_numOfActiveManagers--;
|
_numOfActiveManagers--;
|
||||||
@ -134,14 +131,10 @@ bool UdpSocket2ManagerWindows::Start()
|
|||||||
// Start worker threads.
|
// Start worker threads.
|
||||||
_stopped = false;
|
_stopped = false;
|
||||||
int32_t error = 0;
|
int32_t error = 0;
|
||||||
ListItem* pItem = _workerThreadsList.First();
|
for (WorkerList::iterator iter = _workerThreadsList.begin();
|
||||||
UdpSocket2WorkerWindows* pWorker;
|
iter != _workerThreadsList.end() && !error; ++iter) {
|
||||||
while(pItem != NULL && !error)
|
if(!(*iter)->Start())
|
||||||
{
|
error = 1;
|
||||||
pWorker = (UdpSocket2WorkerWindows*)pItem->GetItem();
|
|
||||||
if(!pWorker->Start())
|
|
||||||
error = 1;
|
|
||||||
pItem = _workerThreadsList.Next(pItem);
|
|
||||||
}
|
}
|
||||||
if(error)
|
if(error)
|
||||||
{
|
{
|
||||||
@ -194,7 +187,7 @@ bool UdpSocket2ManagerWindows::StartWorkerThreads()
|
|||||||
delete pWorker;
|
delete pWorker;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_workerThreadsList.PushFront(pWorker);
|
_workerThreadsList.push_front(pWorker);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if(error)
|
if(error)
|
||||||
@ -207,12 +200,11 @@ bool UdpSocket2ManagerWindows::StartWorkerThreads()
|
|||||||
"creating work threads",
|
"creating work threads",
|
||||||
_managerNumber);
|
_managerNumber);
|
||||||
// Delete worker threads.
|
// Delete worker threads.
|
||||||
ListItem* pItem = NULL;
|
for (WorkerList::iterator iter = _workerThreadsList.begin();
|
||||||
while((pItem = _workerThreadsList.First()) != NULL)
|
iter != _workerThreadsList.end(); ++iter) {
|
||||||
{
|
delete *iter;
|
||||||
delete static_cast<UdpSocket2WorkerWindows*>(pItem->GetItem());
|
|
||||||
_workerThreadsList.PopFront();
|
|
||||||
}
|
}
|
||||||
|
_workerThreadsList.clear();
|
||||||
_pCrit->Leave();
|
_pCrit->Leave();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -281,38 +273,30 @@ bool UdpSocket2ManagerWindows::StopWorkerThreads()
|
|||||||
threadsStoped, numActicve Sockets=%d",
|
threadsStoped, numActicve Sockets=%d",
|
||||||
_managerNumber,
|
_managerNumber,
|
||||||
_numActiveSockets);
|
_numActiveSockets);
|
||||||
UdpSocket2WorkerWindows* pWorker;
|
|
||||||
ListItem* pItem = _workerThreadsList.First();
|
|
||||||
|
|
||||||
// Set worker threads to not alive so that they will stop calling
|
// Set worker threads to not alive so that they will stop calling
|
||||||
// UdpSocket2WorkerWindows::Run().
|
// UdpSocket2WorkerWindows::Run().
|
||||||
while(pItem != NULL)
|
for (WorkerList::iterator iter = _workerThreadsList.begin();
|
||||||
{
|
iter != _workerThreadsList.end(); ++iter) {
|
||||||
pWorker = (UdpSocket2WorkerWindows*)pItem->GetItem();
|
(*iter)->SetNotAlive();
|
||||||
pWorker->SetNotAlive();
|
|
||||||
pItem = _workerThreadsList.Next(pItem);
|
|
||||||
}
|
}
|
||||||
// Release all threads waiting for GetQueuedCompletionStatus(..).
|
// Release all threads waiting for GetQueuedCompletionStatus(..).
|
||||||
if(_ioCompletionHandle)
|
if(_ioCompletionHandle)
|
||||||
{
|
{
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
for(i = 0; i < _workerThreadsList.GetSize(); i++)
|
for(i = 0; i < _workerThreadsList.size(); i++)
|
||||||
{
|
{
|
||||||
PostQueuedCompletionStatus(_ioCompletionHandle, 0 ,0 , NULL);
|
PostQueuedCompletionStatus(_ioCompletionHandle, 0 ,0 , NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pItem = _workerThreadsList.First();
|
for (WorkerList::iterator iter = _workerThreadsList.begin();
|
||||||
|
iter != _workerThreadsList.end(); ++iter) {
|
||||||
while(pItem != NULL)
|
if((*iter)->Stop() == false)
|
||||||
{
|
|
||||||
pWorker = (UdpSocket2WorkerWindows*)pItem->GetItem();
|
|
||||||
if(pWorker->Stop() == false)
|
|
||||||
{
|
{
|
||||||
error = -1;
|
error = -1;
|
||||||
WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1,
|
WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1,
|
||||||
"failed to stop worker thread");
|
"failed to stop worker thread");
|
||||||
}
|
}
|
||||||
pItem = _workerThreadsList.Next(pItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(error)
|
if(error)
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
#define WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_
|
#define WEBRTC_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_
|
||||||
|
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
#include "webrtc/system_wrappers/interface/atomic32.h"
|
#include "webrtc/system_wrappers/interface/atomic32.h"
|
||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
#include "webrtc/test/channel_transport/udp_socket2_win.h"
|
#include "webrtc/test/channel_transport/udp_socket2_win.h"
|
||||||
#include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h"
|
#include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h"
|
||||||
@ -91,6 +91,27 @@ private:
|
|||||||
Atomic32 _inUse;
|
Atomic32 _inUse;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UdpSocket2WorkerWindows
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UdpSocket2WorkerWindows(HANDLE ioCompletionHandle);
|
||||||
|
virtual ~UdpSocket2WorkerWindows();
|
||||||
|
|
||||||
|
virtual bool Start();
|
||||||
|
virtual bool Stop();
|
||||||
|
virtual int32_t Init();
|
||||||
|
virtual void SetNotAlive();
|
||||||
|
protected:
|
||||||
|
static bool Run(ThreadObj obj);
|
||||||
|
bool Process();
|
||||||
|
private:
|
||||||
|
HANDLE _ioCompletionHandle;
|
||||||
|
ThreadWrapper*_pThread;
|
||||||
|
static int32_t _numOfWorkers;
|
||||||
|
int32_t _workerNumber;
|
||||||
|
volatile bool _stop;
|
||||||
|
bool _init;
|
||||||
|
};
|
||||||
|
|
||||||
class UdpSocket2ManagerWindows : public UdpSocketManager
|
class UdpSocket2ManagerWindows : public UdpSocketManager
|
||||||
{
|
{
|
||||||
@ -115,6 +136,7 @@ public:
|
|||||||
int32_t PushIoContext(PerIoContext* pIoContext);
|
int32_t PushIoContext(PerIoContext* pIoContext);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<UdpSocket2WorkerWindows*> WorkerList;
|
||||||
bool StopWorkerThreads();
|
bool StopWorkerThreads();
|
||||||
bool StartWorkerThreads();
|
bool StartWorkerThreads();
|
||||||
bool AddSocketPrv(UdpSocket2Windows* s);
|
bool AddSocketPrv(UdpSocket2Windows* s);
|
||||||
@ -129,35 +151,13 @@ private:
|
|||||||
volatile bool _stopped;
|
volatile bool _stopped;
|
||||||
bool _init;
|
bool _init;
|
||||||
int32_t _numActiveSockets;
|
int32_t _numActiveSockets;
|
||||||
ListWrapper _workerThreadsList;
|
WorkerList _workerThreadsList;
|
||||||
EventWrapper* _event;
|
EventWrapper* _event;
|
||||||
|
|
||||||
HANDLE _ioCompletionHandle;
|
HANDLE _ioCompletionHandle;
|
||||||
IoContextPool _ioContextPool;
|
IoContextPool _ioContextPool;
|
||||||
};
|
};
|
||||||
|
|
||||||
class UdpSocket2WorkerWindows
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
UdpSocket2WorkerWindows(HANDLE ioCompletionHandle);
|
|
||||||
virtual ~UdpSocket2WorkerWindows();
|
|
||||||
|
|
||||||
virtual bool Start();
|
|
||||||
virtual bool Stop();
|
|
||||||
virtual int32_t Init();
|
|
||||||
virtual void SetNotAlive();
|
|
||||||
protected:
|
|
||||||
static bool Run(ThreadObj obj);
|
|
||||||
bool Process();
|
|
||||||
private:
|
|
||||||
HANDLE _ioCompletionHandle;
|
|
||||||
ThreadWrapper*_pThread;
|
|
||||||
static int32_t _numOfWorkers;
|
|
||||||
int32_t _workerNumber;
|
|
||||||
volatile bool _stop;
|
|
||||||
bool _init;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
} // namespace webrtc
|
} // namespace webrtc
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "webrtc/system_wrappers/interface/condition_variable_wrapper.h"
|
#include "webrtc/system_wrappers/interface/condition_variable_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
#include "webrtc/system_wrappers/interface/event_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
|
#include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/trace.h"
|
#include "webrtc/system_wrappers/interface/trace.h"
|
||||||
#include "webrtc/test/channel_transport/udp_socket2_manager_win.h"
|
#include "webrtc/test/channel_transport/udp_socket2_manager_win.h"
|
||||||
|
@ -322,7 +322,7 @@ bool UdpSocketManagerPosixImpl::AddSocket(UdpSocketWrapper* s)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
_critSectList->Enter();
|
_critSectList->Enter();
|
||||||
_addList.PushBack(s);
|
_addList.push_back(s);
|
||||||
_critSectList->Leave();
|
_critSectList->Leave();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -333,26 +333,24 @@ bool UdpSocketManagerPosixImpl::RemoveSocket(UdpSocketWrapper* s)
|
|||||||
_critSectList->Enter();
|
_critSectList->Enter();
|
||||||
|
|
||||||
// If the socket is in the add list it's safe to remove and delete it.
|
// If the socket is in the add list it's safe to remove and delete it.
|
||||||
ListItem* addListItem = _addList.First();
|
for (SocketList::iterator iter = _addList.begin();
|
||||||
while(addListItem)
|
iter != _addList.end(); ++iter) {
|
||||||
{
|
UdpSocketPosix* addSocket = static_cast<UdpSocketPosix*>(*iter);
|
||||||
UdpSocketPosix* addSocket = (UdpSocketPosix*)addListItem->GetItem();
|
|
||||||
unsigned int addFD = addSocket->GetFd();
|
unsigned int addFD = addSocket->GetFd();
|
||||||
unsigned int removeFD = static_cast<UdpSocketPosix*>(s)->GetFd();
|
unsigned int removeFD = static_cast<UdpSocketPosix*>(s)->GetFd();
|
||||||
if(removeFD == addFD)
|
if(removeFD == addFD)
|
||||||
{
|
{
|
||||||
_removeList.PushBack(removeFD);
|
_removeList.push_back(removeFD);
|
||||||
_critSectList->Leave();
|
_critSectList->Leave();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
addListItem = _addList.Next(addListItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Checking the socket map is safe since all Erase and Insert calls to this
|
// Checking the socket map is safe since all Erase and Insert calls to this
|
||||||
// map are also protected by _critSectList.
|
// map are also protected by _critSectList.
|
||||||
if (_socketMap.find(static_cast<UdpSocketPosix*>(s)->GetFd()) !=
|
if (_socketMap.find(static_cast<UdpSocketPosix*>(s)->GetFd()) !=
|
||||||
_socketMap.end()) {
|
_socketMap.end()) {
|
||||||
_removeList.PushBack(static_cast<UdpSocketPosix*>(s)->GetFd());
|
_removeList.push_back(static_cast<UdpSocketPosix*>(s)->GetFd());
|
||||||
_critSectList->Leave();
|
_critSectList->Leave();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -364,25 +362,23 @@ void UdpSocketManagerPosixImpl::UpdateSocketMap()
|
|||||||
{
|
{
|
||||||
// Remove items in remove list.
|
// Remove items in remove list.
|
||||||
_critSectList->Enter();
|
_critSectList->Enter();
|
||||||
while(!_removeList.Empty())
|
for (FdList::iterator iter = _removeList.begin();
|
||||||
{
|
iter != _removeList.end(); ++iter) {
|
||||||
UdpSocketPosix* deleteSocket = NULL;
|
UdpSocketPosix* deleteSocket = NULL;
|
||||||
SOCKET removeFD = _removeList.First()->GetUnsignedItem();
|
SOCKET removeFD = *iter;
|
||||||
|
|
||||||
// If the socket is in the add list it hasn't been added to the socket
|
// If the socket is in the add list it hasn't been added to the socket
|
||||||
// map yet. Just remove the socket from the add list.
|
// map yet. Just remove the socket from the add list.
|
||||||
ListItem* addListItem = _addList.First();
|
for (SocketList::iterator iter = _addList.begin();
|
||||||
while(addListItem)
|
iter != _addList.end(); ++iter) {
|
||||||
{
|
UdpSocketPosix* addSocket = static_cast<UdpSocketPosix*>(*iter);
|
||||||
UdpSocketPosix* addSocket = (UdpSocketPosix*)addListItem->GetItem();
|
|
||||||
SOCKET addFD = addSocket->GetFd();
|
SOCKET addFD = addSocket->GetFd();
|
||||||
if(removeFD == addFD)
|
if(removeFD == addFD)
|
||||||
{
|
{
|
||||||
deleteSocket = addSocket;
|
deleteSocket = addSocket;
|
||||||
_addList.Erase(addListItem);
|
_addList.erase(iter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
addListItem = _addList.Next(addListItem);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find and remove socket from _socketMap.
|
// Find and remove socket from _socketMap.
|
||||||
@ -398,19 +394,18 @@ void UdpSocketManagerPosixImpl::UpdateSocketMap()
|
|||||||
deleteSocket->ReadyForDeletion();
|
deleteSocket->ReadyForDeletion();
|
||||||
delete deleteSocket;
|
delete deleteSocket;
|
||||||
}
|
}
|
||||||
_removeList.PopFront();
|
|
||||||
}
|
}
|
||||||
|
_removeList.clear();
|
||||||
|
|
||||||
// Add sockets from add list.
|
// Add sockets from add list.
|
||||||
while(!_addList.Empty())
|
for (SocketList::iterator iter = _addList.begin();
|
||||||
{
|
iter != _addList.end(); ++iter) {
|
||||||
UdpSocketPosix* s =
|
UdpSocketPosix* s = static_cast<UdpSocketPosix*>(*iter);
|
||||||
static_cast<UdpSocketPosix*>(_addList.First()->GetItem());
|
|
||||||
if(s) {
|
if(s) {
|
||||||
_socketMap[s->GetFd()] = s;
|
_socketMap[s->GetFd()] = s;
|
||||||
}
|
}
|
||||||
_addList.PopFront();
|
|
||||||
}
|
}
|
||||||
|
_addList.clear();
|
||||||
_critSectList->Leave();
|
_critSectList->Leave();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,10 +14,10 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
#include "webrtc/system_wrappers/interface/thread_wrapper.h"
|
||||||
#include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h"
|
#include "webrtc/test/channel_transport/udp_socket_manager_wrapper.h"
|
||||||
#include "webrtc/test/channel_transport/udp_socket_wrapper.h"
|
#include "webrtc/test/channel_transport/udp_socket_wrapper.h"
|
||||||
@ -74,14 +74,16 @@ protected:
|
|||||||
void UpdateSocketMap();
|
void UpdateSocketMap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<UdpSocketWrapper*> SocketList;
|
||||||
|
typedef std::list<SOCKET> FdList;
|
||||||
ThreadWrapper* _thread;
|
ThreadWrapper* _thread;
|
||||||
CriticalSectionWrapper* _critSectList;
|
CriticalSectionWrapper* _critSectList;
|
||||||
|
|
||||||
fd_set _readFds;
|
fd_set _readFds;
|
||||||
|
|
||||||
std::map<SOCKET, UdpSocketPosix*> _socketMap;
|
std::map<SOCKET, UdpSocketPosix*> _socketMap;
|
||||||
ListWrapper _addList;
|
SocketList _addList;
|
||||||
ListWrapper _removeList;
|
FdList _removeList;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace test
|
} // namespace test
|
||||||
|
@ -30,7 +30,7 @@ class TestProcessThread : public ProcessThread {
|
|||||||
~TestProcessThread() {}
|
~TestProcessThread() {}
|
||||||
virtual int32_t Start() { return 0; }
|
virtual int32_t Start() { return 0; }
|
||||||
virtual int32_t Stop() { return 0; }
|
virtual int32_t Stop() { return 0; }
|
||||||
virtual int32_t RegisterModule(const Module* module) { return 0; }
|
virtual int32_t RegisterModule(Module* module) { return 0; }
|
||||||
virtual int32_t DeRegisterModule(const Module* module) { return 0; }
|
virtual int32_t DeRegisterModule(const Module* module) { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class TestProcessThread : public ProcessThread {
|
|||||||
~TestProcessThread() {}
|
~TestProcessThread() {}
|
||||||
virtual int32_t Start() { return 0; }
|
virtual int32_t Start() { return 0; }
|
||||||
virtual int32_t Stop() { return 0; }
|
virtual int32_t Stop() { return 0; }
|
||||||
virtual int32_t RegisterModule(const Module* module) { return 0; }
|
virtual int32_t RegisterModule(Module* module) { return 0; }
|
||||||
virtual int32_t DeRegisterModule(const Module* module) { return 0; }
|
virtual int32_t DeRegisterModule(const Module* module) { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ int32_t ViERenderManager::RegisterVideoRenderModule(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Register module.
|
// Register module.
|
||||||
render_list_.PushBack(static_cast<void*>(render_module));
|
render_list_.push_back(render_module);
|
||||||
use_external_render_module_ = true;
|
use_external_render_module_ = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -81,24 +81,17 @@ int32_t ViERenderManager::DeRegisterVideoRenderModule(
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase the render module from the map.
|
for (RenderList::iterator iter = render_list_.begin();
|
||||||
ListItem* list_item = NULL;
|
iter != render_list_.end(); ++iter) {
|
||||||
bool found = false;
|
if (render_module == *iter) {
|
||||||
for (list_item = render_list_.First(); list_item != NULL;
|
// We've found our renderer. Erase the render module from the map.
|
||||||
list_item = render_list_.Next(list_item)) {
|
render_list_.erase(iter);
|
||||||
if (render_module == static_cast<VideoRender*>(list_item->GetItem())) {
|
return 0;
|
||||||
// We've found our renderer.
|
|
||||||
render_list_.Erase(list_item);
|
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
||||||
WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideo, ViEId(engine_id_),
|
"Module not registered");
|
||||||
"Module not registered");
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ViERenderer* ViERenderManager::AddRenderStream(const int32_t render_id,
|
ViERenderer* ViERenderManager::AddRenderStream(const int32_t render_id,
|
||||||
@ -129,7 +122,7 @@ ViERenderer* ViERenderManager::AddRenderStream(const int32_t render_id,
|
|||||||
"Could not create new render module");
|
"Could not create new render module");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
render_list_.PushBack(static_cast<void*>(render_module));
|
render_list_.push_back(render_module);
|
||||||
}
|
}
|
||||||
|
|
||||||
ViERenderer* vie_renderer = ViERenderer::CreateViERenderer(render_id,
|
ViERenderer* vie_renderer = ViERenderer::CreateViERenderer(render_id,
|
||||||
@ -176,12 +169,11 @@ int32_t ViERenderManager::RemoveRenderStream(
|
|||||||
if (!use_external_render_module_ &&
|
if (!use_external_render_module_ &&
|
||||||
renderer.GetNumIncomingRenderStreams() == 0) {
|
renderer.GetNumIncomingRenderStreams() == 0) {
|
||||||
// Erase the render module from the map.
|
// Erase the render module from the map.
|
||||||
ListItem* list_item = NULL;
|
for (RenderList::iterator iter = render_list_.begin();
|
||||||
for (list_item = render_list_.First(); list_item != NULL;
|
iter != render_list_.end(); ++iter) {
|
||||||
list_item = render_list_.Next(list_item)) {
|
if (&renderer == *iter) {
|
||||||
if (&renderer == static_cast<VideoRender*>(list_item->GetItem())) {
|
|
||||||
// We've found our renderer.
|
// We've found our renderer.
|
||||||
render_list_.Erase(list_item);
|
render_list_.erase(iter);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -192,21 +184,14 @@ int32_t ViERenderManager::RemoveRenderStream(
|
|||||||
}
|
}
|
||||||
|
|
||||||
VideoRender* ViERenderManager::FindRenderModule(void* window) {
|
VideoRender* ViERenderManager::FindRenderModule(void* window) {
|
||||||
VideoRender* renderer = NULL;
|
for (RenderList::iterator iter = render_list_.begin();
|
||||||
ListItem* list_item = NULL;
|
iter != render_list_.end(); ++iter) {
|
||||||
for (list_item = render_list_.First(); list_item != NULL;
|
if ((*iter)->Window() == window) {
|
||||||
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.
|
// We've found the render module.
|
||||||
break;
|
return *iter;
|
||||||
}
|
}
|
||||||
renderer = NULL;
|
|
||||||
}
|
}
|
||||||
return renderer;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViERenderer* ViERenderManager::ViERenderPtr(int32_t render_id) const {
|
ViERenderer* ViERenderManager::ViERenderPtr(int32_t render_id) const {
|
||||||
|
@ -11,9 +11,9 @@
|
|||||||
#ifndef WEBRTC_VIDEO_ENGINE_VIE_RENDER_MANAGER_H_
|
#ifndef WEBRTC_VIDEO_ENGINE_VIE_RENDER_MANAGER_H_
|
||||||
#define WEBRTC_VIDEO_ENGINE_VIE_RENDER_MANAGER_H_
|
#define WEBRTC_VIDEO_ENGINE_VIE_RENDER_MANAGER_H_
|
||||||
|
|
||||||
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "webrtc/system_wrappers/interface/list_wrapper.h"
|
|
||||||
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
#include "webrtc/system_wrappers/interface/scoped_ptr.h"
|
||||||
#include "webrtc/typedefs.h"
|
#include "webrtc/typedefs.h"
|
||||||
#include "webrtc/video_engine/vie_manager_base.h"
|
#include "webrtc/video_engine/vie_manager_base.h"
|
||||||
@ -46,6 +46,7 @@ class ViERenderManager : private ViEManagerBase {
|
|||||||
int32_t RemoveRenderStream(int32_t render_id);
|
int32_t RemoveRenderStream(int32_t render_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::list<VideoRender*> RenderList;
|
||||||
// Returns a pointer to the render module if it exists in the render list.
|
// Returns a pointer to the render module if it exists in the render list.
|
||||||
// Assumed protected.
|
// Assumed protected.
|
||||||
VideoRender* FindRenderModule(void* window);
|
VideoRender* FindRenderModule(void* window);
|
||||||
@ -58,8 +59,7 @@ class ViERenderManager : private ViEManagerBase {
|
|||||||
// Protected by ViEManagerBase.
|
// Protected by ViEManagerBase.
|
||||||
typedef std::map<int32_t, ViERenderer*> RendererMap;
|
typedef std::map<int32_t, ViERenderer*> RendererMap;
|
||||||
RendererMap stream_to_vie_renderer_;
|
RendererMap stream_to_vie_renderer_;
|
||||||
|
RenderList render_list_;
|
||||||
ListWrapper render_list_;
|
|
||||||
bool use_external_render_module_;
|
bool use_external_render_module_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user