您的位置:首页 > 移动开发

WebRTC音视频引擎研究(3)--临界区设计、临界资源访问--CriticalSectionWrapper

2014-12-04 10:49 459 查看

1、临界区与临界资源相关概念

临界区

不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。每个进程中访问临界资源的那段代码称为临界区(Critical Section)。

  每个进程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区,进入后不允许其他进程进入。不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。

  多个进程中涉及到同一个临界资源的临界区称为相关临界区。

  进程进入临界区的调度原则是:

①如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入。

②任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待。

③进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区。

④如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。

  如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

  临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。

2、WebRTC中临界区和临界资源

在WebRTC源码里,对线程互斥访问临界资源设计一个良好的面向对象的实现方法。

大体框图:




图示说明:

(1)CriticalSectionWrapper类用于封装临界区的操作,包括windows平台和非windows平台的;直接使用CriticalSectionWrapper定义临界区;

(2)CriticalSectionWrapper类是CriticalSectionWindows和CriticalSectionPosix的父类;CriticalSectionWindows表示Windows平台下使用Windows API定义临界区,同理CriticalSectionPosix表示非Windows平台下使用Posix定义临界区;

(3)CriticalSectionScoped类的构造函数为CriticalSectionScoped(CriticalSectionWrapper& critsec),CriticalSectionWrapper的引用作为参数,(注意:CriticalSectionWrapper构造函数返回的并不是它本身,而是根据平台选择返回它的派生类对象,返回CriticalSectionWindows对象或者CriticalSectionPosix对象,以此达到CriticalSectionWrapper封装的目的)并且在定义CriticalSectionScoped的同时进入临界区;CriticalSectionScoped析构函数离开临界区;

定义CriticalSectionWrapper类和CriticalSectionScoped类:(critical_section_wrapper.h)

[cpp] view
plaincopy

//=========critical_section_wrapper.h

#ifndef CRITICAL_SECTION_WRAPPER_H

#define CRITICAL_SECTION_WRAPPER_H



namespace webrtc {

class CriticalSectionWrapper

{

public:

// Factory method, constructor disabled

static CriticalSectionWrapper* CreateCriticalSection();//工厂方法,创建临界区,返回指针



virtual ~CriticalSectionWrapper() {}



// Tries to grab lock, beginning of a critical section. Will wait for the

// lock to become available if the grab failed.

virtual void Enter() = 0;



// Returns a grabbed lock, end of critical section.

virtual void Leave() = 0;

};



// RAII extension of the critical section. Prevents Enter/Leave missmatches and

// provides more compact critical section syntax.

class CriticalSectionScoped

{

public:

CriticalSectionScoped(CriticalSectionWrapper& critsec) //构造函数,进入临界区

:

_ptrCritSec(&critsec)

{

_ptrCritSec->Enter();

}



~CriticalSectionScoped() //析构函数,保证离开临界区

{

if (_ptrCritSec)

{

Leave();

}

}



private:

void Leave()

{

_ptrCritSec->Leave();

_ptrCritSec = 0;

}



CriticalSectionWrapper* _ptrCritSec;

};

} // namespace

#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_

[b]CriticalSectionWrapper类实现:(critical_section.cpp)

[/b]

[cpp] view
plaincopy

//=========== critical_section.cpp

#if defined(_WIN32)

#include <windows.h>

#include "critical_section_windows.h" //使用Windows平台API

#else

#include "critical_section_posix.h" //使用posix

#endif



namespace webrtc {

CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection()

{

#ifdef _WIN32

return new CriticalSectionWindows();//Windows平台,返回CriticalSectionWindows对象

#else

return new CriticalSectionPosix(); //非Windows平台,返回CriticalSectionPosix对象

#endif

}

} // namespace webrt<strong>

</strong>



Windows平台下临界区操作CriticalSectionWindows API 定义头文件(critical_section_windows.h)

[cpp] view
plaincopy

//============== critical_section_windows.h

#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_

#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_



//#include "typedefs.h"

#include "critical_section_wrapper.h"

#include <windows.h> //使用Windows平台API



namespace webrtc {

class CriticalSectionWindows : public CriticalSectionWrapper

{

public:

CriticalSectionWindows();



virtual ~CriticalSectionWindows();



virtual void Enter();

virtual void Leave();



private:

CRITICAL_SECTION crit;



//friend class ConditionVariableWindows;

};

} // namespace webrtc



#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_

Windows平台下临界区操作CriticalSectionWindows类 API 实现文件(critical_section_windows.cpp)

[cpp] view
plaincopy

//============= critical_section_windows.cpp

#include "critical_section_windows.h"



namespace webrtc {

CriticalSectionWindows::CriticalSectionWindows()

{

InitializeCriticalSection(&crit); //构造函数初始化临界区

}



CriticalSectionWindows::~CriticalSectionWindows()

{

DeleteCriticalSection(&crit);//析构函数删除临界区,利用类来管理资源的思想,Effective C++思想

}



void

CriticalSectionWindows::Enter()

{

EnterCriticalSection(&crit); //进入临界资源

}



void

CriticalSectionWindows::Leave()

{

LeaveCriticalSection(&crit); //离开临界资源

}

} // namespace webrtc<strong>

</strong>

非Windows平台下临界区操作CriticalSectionPosix API 定义头文件(critical_section_posix.h)

[cpp] view
plaincopy

#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_

#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_



//非Windows平台使用Posix的临界资源



#include "critical_section_wrapper.h"



#include <pthread.h> //使用Posix



namespace webrtc {

class CriticalSectionPosix : public CriticalSectionWrapper

{

public:

CriticalSectionPosix();



virtual ~CriticalSectionPosix();



virtual void Enter();

virtual void Leave();



private:

pthread_mutex_t _mutex;

//friend class ConditionVariablePosix;

};

} // namespace webrtc



#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_

非Windows平台下临界区操作CriticalSectionPosix类 API 实现文件(critical_section_posix.cpp)

[cpp] view
plaincopy

#include "critical_section_posix.h"



namespace webrtc {

CriticalSectionPosix::CriticalSectionPosix()

{

pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);

pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

pthread_mutex_init(&_mutex, &attr);

}



CriticalSectionPosix::~CriticalSectionPosix()

{

pthread_mutex_destroy(&_mutex);

}



void

CriticalSectionPosix::Enter()

{

pthread_mutex_lock(&_mutex);

}



void

CriticalSectionPosix::Leave()

{

pthread_mutex_unlock(&_mutex);

}

} // namespace webrtc<strong>

</strong>

3、使用CriticalSectionWrapper和CriticalSectionScoped示例

设备池数据是临界资源,为保证临界资源不被破坏,必须使用临界区实现互斥访问:

头文件:...src\video_engine\main\test\WindowsTest\CaptureDevicePool.h

[cpp] view
plaincopy

#pragma once



#include "common_types.h"



#include "vie_base.h"

#include "vie_capture.h"

#include "vie_file.h"

#include "map_wrapper.h"



namespace webrtc {

class CriticalSectionWrapper;

}

using namespace webrtc;

class CaptureDevicePool

{

public:

CaptureDevicePool(VideoEngine* videoEngine);

~CaptureDevicePool(void);

WebRtc_Word32 GetCaptureDevice(int& captureId, const char uniqeDeviceName[256]);

WebRtc_Word32 ReturnCaptureDevice(int captureId);



private:

struct DeviceItem

{

int captureId;

WebRtc_Word32 refCount;

char uniqeDeviceName[256];

DeviceItem()

{

captureId=-1;

refCount=0;

}

};

CriticalSectionWrapper& _critSect;

ViECapture* _vieCapture;

ViEFile* _vieFile;

MapWrapper _deviceMap;



};

实现:...src\video_engine\main\test\WindowsTest\CaptureDevicePool.cpp

[cpp] view
plaincopy

#include "CaptureDevicePool.h"

#include "map_wrapper.h"

#include <string.h>

#include <assert.h>

#include "critical_section_wrapper.h"

#include "vie_file.h"



CaptureDevicePool::CaptureDevicePool(VideoEngine* videoEngine):

_critSect(*CriticalSectionWrapper::CreateCriticalSection()),

_vieCapture(ViECapture::GetInterface(videoEngine)),

_vieFile(ViEFile::GetInterface(videoEngine))

{

}



CaptureDevicePool::~CaptureDevicePool(void)

{

assert(_deviceMap.Size()==0);

_vieCapture->Release();

_vieFile->Release();

delete &_critSect;

}



WebRtc_Word32 CaptureDevicePool::GetCaptureDevice(int& captureId, const char* uniqeDeviceName)

{

CriticalSectionScoped cs(_critSect); //创建CriticalSectionScoped cs即立刻进入临界区,它的析构函数保证释放临界资源,保护对设备信息MapWrapper _deviceMap的访问

DeviceItem* device=NULL;



for(MapItem* item=_deviceMap.First();

item!=NULL;

item=_deviceMap.Next(item))

{

//Found the device?先从临界资源_deviceMap中查找Device,如果没有的话就定位一个新的DeviceIterm

if(strcmp(uniqeDeviceName,(static_cast<DeviceItem*>( item->GetItem()))->uniqeDeviceName)==0)

{

device=static_cast<DeviceItem*>( item->GetItem());

device->refCount++;

captureId=device->captureId;

return 0;

}

}

//没找到Device定位一个新的Device

device = new DeviceItem;

strncpy(device->uniqeDeviceName,uniqeDeviceName,255);





// Device does not exist. Create it.并将获取到的设备放到DeviceItem device中去

WebRtc_Word32 result=_vieCapture->AllocateCaptureDevice(device->uniqeDeviceName,strlen(device->uniqeDeviceName),device->captureId);

if(result==0)

{

//配置设备的属性

//CaptureCapability cap;

/*cap.height=1080;

cap.width=1920;

cap.maxFPS=25;

cap.interlaced=true;*/

// result=_vieCapture->StartCapture(device->captureId,cap);

//设置捕捉设备初始图片

result=_vieFile->SetCaptureDeviceImage(device->captureId,"captureDeviceImage.jpg");

}

captureId=device->captureId; //返回新设备的ID给函数

_deviceMap.Insert(captureId,device);//插入到MapWrapper _deviceMap中去

device->refCount++; //引用加1



return result;





}

WebRtc_Word32 CaptureDevicePool::ReturnCaptureDevice(int captureId)

{

CriticalSectionScoped cs(_critSect);



MapItem* mapItem=_deviceMap.Find(captureId);

if(!mapItem)

return -1;



DeviceItem* item=static_cast<DeviceItem*> (mapItem->GetItem());

if(!item)

return 0;

item->refCount--;

WebRtc_Word32 result=0;



if(item->refCount==0)

{

result=_vieCapture->ReleaseCaptureDevice(captureId);



_deviceMap.Erase(mapItem);

delete item;



}

return result;

}

1、临界区与临界资源相关概念

临界区

不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。每个进程中访问临界资源的那段代码称为临界区(Critical Section)。

  每个进程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区,进入后不允许其他进程进入。不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。

  多个进程中涉及到同一个临界资源的临界区称为相关临界区。

  进程进入临界区的调度原则是:

①如果有若干进程要求进入空闲的临界区,一次仅允许一个进程进入。

②任何时候,处于临界区内的进程不可多于一个。如已有进程进入自己的临界区,则其它所有试图进入临界区的进程必须等待。

③进入临界区的进程要在有限时间内退出,以便其它进程能及时进入自己的临界区。

④如果进程不能进入自己的临界区,则应让出CPU,避免进程出现“忙等”现象。

  如果有多个线程试图同时访问临界区,那么在有一个线程进入后其他所有试图访问此临界区的线程将被挂起,并一直持续到进入临界区的线程离开。临界区在被释放后,其他线程可以继续抢占,并以此达到用原子方式操作共享资源的目的。

  临界区在使用时以CRITICAL_SECTION结构对象保护共享资源,并分别用EnterCriticalSection()和LeaveCriticalSection()函数去标识和释放一个临界区。所用到的CRITICAL_SECTION结构对象必须经过InitializeCriticalSection()的初始化后才能使用,而且必须确保所有线程中的任何试图访问此共享资源的代码都处在此临界区的保护之下。否则临界区将不会起到应有的作用,共享资源依然有被破坏的可能。

2、WebRTC中临界区和临界资源

在WebRTC源码里,对线程互斥访问临界资源设计一个良好的面向对象的实现方法。

大体框图:




图示说明:

(1)CriticalSectionWrapper类用于封装临界区的操作,包括windows平台和非windows平台的;直接使用CriticalSectionWrapper定义临界区;

(2)CriticalSectionWrapper类是CriticalSectionWindows和CriticalSectionPosix的父类;CriticalSectionWindows表示Windows平台下使用Windows API定义临界区,同理CriticalSectionPosix表示非Windows平台下使用Posix定义临界区;

(3)CriticalSectionScoped类的构造函数为CriticalSectionScoped(CriticalSectionWrapper& critsec),CriticalSectionWrapper的引用作为参数,(注意:CriticalSectionWrapper构造函数返回的并不是它本身,而是根据平台选择返回它的派生类对象,返回CriticalSectionWindows对象或者CriticalSectionPosix对象,以此达到CriticalSectionWrapper封装的目的)并且在定义CriticalSectionScoped的同时进入临界区;CriticalSectionScoped析构函数离开临界区;

定义CriticalSectionWrapper类和CriticalSectionScoped类:(critical_section_wrapper.h)

[cpp] view
plaincopy

//=========critical_section_wrapper.h

#ifndef CRITICAL_SECTION_WRAPPER_H

#define CRITICAL_SECTION_WRAPPER_H



namespace webrtc {

class CriticalSectionWrapper

{

public:

// Factory method, constructor disabled

static CriticalSectionWrapper* CreateCriticalSection();//工厂方法,创建临界区,返回指针



virtual ~CriticalSectionWrapper() {}



// Tries to grab lock, beginning of a critical section. Will wait for the

// lock to become available if the grab failed.

virtual void Enter() = 0;



// Returns a grabbed lock, end of critical section.

virtual void Leave() = 0;

};



// RAII extension of the critical section. Prevents Enter/Leave missmatches and

// provides more compact critical section syntax.

class CriticalSectionScoped

{

public:

CriticalSectionScoped(CriticalSectionWrapper& critsec) //构造函数,进入临界区

:

_ptrCritSec(&critsec)

{

_ptrCritSec->Enter();

}



~CriticalSectionScoped() //析构函数,保证离开临界区

{

if (_ptrCritSec)

{

Leave();

}

}



private:

void Leave()

{

_ptrCritSec->Leave();

_ptrCritSec = 0;

}



CriticalSectionWrapper* _ptrCritSec;

};

} // namespace

#endif // WEBRTC_SYSTEM_WRAPPERS_INTERFACE_CRITICAL_SECTION_WRAPPER_H_

[b]CriticalSectionWrapper类实现:(critical_section.cpp)

[/b]

[cpp] view
plaincopy

//=========== critical_section.cpp

#if defined(_WIN32)

#include <windows.h>

#include "critical_section_windows.h" //使用Windows平台API

#else

#include "critical_section_posix.h" //使用posix

#endif



namespace webrtc {

CriticalSectionWrapper* CriticalSectionWrapper::CreateCriticalSection()

{

#ifdef _WIN32

return new CriticalSectionWindows();//Windows平台,返回CriticalSectionWindows对象

#else

return new CriticalSectionPosix(); //非Windows平台,返回CriticalSectionPosix对象

#endif

}

} // namespace webrt<strong>

</strong>



Windows平台下临界区操作CriticalSectionWindows API 定义头文件(critical_section_windows.h)

[cpp] view
plaincopy

//============== critical_section_windows.h

#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_

#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_



//#include "typedefs.h"

#include "critical_section_wrapper.h"

#include <windows.h> //使用Windows平台API



namespace webrtc {

class CriticalSectionWindows : public CriticalSectionWrapper

{

public:

CriticalSectionWindows();



virtual ~CriticalSectionWindows();



virtual void Enter();

virtual void Leave();



private:

CRITICAL_SECTION crit;



//friend class ConditionVariableWindows;

};

} // namespace webrtc



#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_WINDOWS_H_

Windows平台下临界区操作CriticalSectionWindows类 API 实现文件(critical_section_windows.cpp)

[cpp] view
plaincopy

//============= critical_section_windows.cpp

#include "critical_section_windows.h"



namespace webrtc {

CriticalSectionWindows::CriticalSectionWindows()

{

InitializeCriticalSection(&crit); //构造函数初始化临界区

}



CriticalSectionWindows::~CriticalSectionWindows()

{

DeleteCriticalSection(&crit);//析构函数删除临界区,利用类来管理资源的思想,Effective C++思想

}



void

CriticalSectionWindows::Enter()

{

EnterCriticalSection(&crit); //进入临界资源

}



void

CriticalSectionWindows::Leave()

{

LeaveCriticalSection(&crit); //离开临界资源

}

} // namespace webrtc<strong>

</strong>

非Windows平台下临界区操作CriticalSectionPosix API 定义头文件(critical_section_posix.h)

[cpp] view
plaincopy

#ifndef WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_

#define WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_



//非Windows平台使用Posix的临界资源



#include "critical_section_wrapper.h"



#include <pthread.h> //使用Posix



namespace webrtc {

class CriticalSectionPosix : public CriticalSectionWrapper

{

public:

CriticalSectionPosix();



virtual ~CriticalSectionPosix();



virtual void Enter();

virtual void Leave();



private:

pthread_mutex_t _mutex;

//friend class ConditionVariablePosix;

};

} // namespace webrtc



#endif // WEBRTC_SYSTEM_WRAPPERS_SOURCE_CRITICAL_SECTION_POSIX_H_

非Windows平台下临界区操作CriticalSectionPosix类 API 实现文件(critical_section_posix.cpp)

[cpp] view
plaincopy

#include "critical_section_posix.h"



namespace webrtc {

CriticalSectionPosix::CriticalSectionPosix()

{

pthread_mutexattr_t attr;

pthread_mutexattr_init(&attr);

pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);

pthread_mutex_init(&_mutex, &attr);

}



CriticalSectionPosix::~CriticalSectionPosix()

{

pthread_mutex_destroy(&_mutex);

}



void

CriticalSectionPosix::Enter()

{

pthread_mutex_lock(&_mutex);

}



void

CriticalSectionPosix::Leave()

{

pthread_mutex_unlock(&_mutex);

}

} // namespace webrtc<strong>

</strong>

3、使用CriticalSectionWrapper和CriticalSectionScoped示例

设备池数据是临界资源,为保证临界资源不被破坏,必须使用临界区实现互斥访问:

头文件:...src\video_engine\main\test\WindowsTest\CaptureDevicePool.h

[cpp] view
plaincopy

#pragma once



#include "common_types.h"



#include "vie_base.h"

#include "vie_capture.h"

#include "vie_file.h"

#include "map_wrapper.h"



namespace webrtc {

class CriticalSectionWrapper;

}

using namespace webrtc;

class CaptureDevicePool

{

public:

CaptureDevicePool(VideoEngine* videoEngine);

~CaptureDevicePool(void);

WebRtc_Word32 GetCaptureDevice(int& captureId, const char uniqeDeviceName[256]);

WebRtc_Word32 ReturnCaptureDevice(int captureId);



private:

struct DeviceItem

{

int captureId;

WebRtc_Word32 refCount;

char uniqeDeviceName[256];

DeviceItem()

{

captureId=-1;

refCount=0;

}

};

CriticalSectionWrapper& _critSect;

ViECapture* _vieCapture;

ViEFile* _vieFile;

MapWrapper _deviceMap;



};

实现:...src\video_engine\main\test\WindowsTest\CaptureDevicePool.cpp

[cpp] view
plaincopy

#include "CaptureDevicePool.h"

#include "map_wrapper.h"

#include <string.h>

#include <assert.h>

#include "critical_section_wrapper.h"

#include "vie_file.h"



CaptureDevicePool::CaptureDevicePool(VideoEngine* videoEngine):

_critSect(*CriticalSectionWrapper::CreateCriticalSection()),

_vieCapture(ViECapture::GetInterface(videoEngine)),

_vieFile(ViEFile::GetInterface(videoEngine))

{

}



CaptureDevicePool::~CaptureDevicePool(void)

{

assert(_deviceMap.Size()==0);

_vieCapture->Release();

_vieFile->Release();

delete &_critSect;

}



WebRtc_Word32 CaptureDevicePool::GetCaptureDevice(int& captureId, const char* uniqeDeviceName)

{

CriticalSectionScoped cs(_critSect); //创建CriticalSectionScoped cs即立刻进入临界区,它的析构函数保证释放临界资源,保护对设备信息MapWrapper _deviceMap的访问

DeviceItem* device=NULL;



for(MapItem* item=_deviceMap.First();

item!=NULL;

item=_deviceMap.Next(item))

{

//Found the device?先从临界资源_deviceMap中查找Device,如果没有的话就定位一个新的DeviceIterm

if(strcmp(uniqeDeviceName,(static_cast<DeviceItem*>( item->GetItem()))->uniqeDeviceName)==0)

{

device=static_cast<DeviceItem*>( item->GetItem());

device->refCount++;

captureId=device->captureId;

return 0;

}

}

//没找到Device定位一个新的Device

device = new DeviceItem;

strncpy(device->uniqeDeviceName,uniqeDeviceName,255);





// Device does not exist. Create it.并将获取到的设备放到DeviceItem device中去

WebRtc_Word32 result=_vieCapture->AllocateCaptureDevice(device->uniqeDeviceName,strlen(device->uniqeDeviceName),device->captureId);

if(result==0)

{

//配置设备的属性

//CaptureCapability cap;

/*cap.height=1080;

cap.width=1920;

cap.maxFPS=25;

cap.interlaced=true;*/

// result=_vieCapture->StartCapture(device->captureId,cap);

//设置捕捉设备初始图片

result=_vieFile->SetCaptureDeviceImage(device->captureId,"captureDeviceImage.jpg");

}

captureId=device->captureId; //返回新设备的ID给函数

_deviceMap.Insert(captureId,device);//插入到MapWrapper _deviceMap中去

device->refCount++; //引用加1



return result;





}

WebRtc_Word32 CaptureDevicePool::ReturnCaptureDevice(int captureId)

{

CriticalSectionScoped cs(_critSect);



MapItem* mapItem=_deviceMap.Find(captureId);

if(!mapItem)

return -1;



DeviceItem* item=static_cast<DeviceItem*> (mapItem->GetItem());

if(!item)

return 0;

item->refCount--;

WebRtc_Word32 result=0;



if(item->refCount==0)

{

result=_vieCapture->ReleaseCaptureDevice(captureId);



_deviceMap.Erase(mapItem);

delete item;



}

return result;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: