Buffer buffers[BUFFERNUM]; int readPos;//int front; int writePos;//int rear; int num;
bool validFlag;
/*Define two events to synchronize between input thread and output thread **hFullEvent is defined for the circumstance when the buffer queue is full
**and input thread is waiting for output thread to retrieve data from buffer queue
**hEmptyEvent is defined for the circumstance when the buffer queue is empty
**and output thread is waiting for input thread puts data in buffer queue */
static int numOfBuffers(){return BUFFERNUM;} };
QueueBuffer.cpp文件
#include “QueueBuffer.h” #include
BufferQueue::BufferQueue() {
readPos=writePos=NULL; numUsedBytes = 0; }
BufferQueue::~BufferQueue() { }
void BufferQueue::lockAccessMutex() {
QueueBufferMutex.lock(); }
void BufferQueue::unLockAccessMutex() {
QueueBufferMutex.unlock(); }
/*
* This is used by read thread */
Buffer* BufferQueue::getReadBuffer() {
Buffer *readBuffer;
QueueBufferMutex.lock(); if (numUsedBytes == 0)
bufferNotEmpty.wait(&QueueBufferMutex); QueueBufferMutex.unlock(); QueueBufferMutex.lock();
readBuffer=&buffers[readPos];
readPos = (readPos+1)%numOfBuffers();
–numUsedBytes;
bufferNotFull.wakeAll();
QueueBufferMutex.unlock();
return readBuffer; }
void BufferQueue::getWriteBuffer(unsigned char *e,int len) {
Buffer *writeBuffer = NULL;
QueueBufferMutex.lock();
if (numUsedBytes == numOfBuffers()) bufferNotFull.wait(&QueueBufferMutex); QueueBufferMutex.unlock();
QueueBufferMutex.lock();
buffers[writePos].buf=e;
buffers[writePos].m_dwPayloadLength=len; writePos=(writePos+1)%numOfBuffers(); ++numUsedBytes;
bufferNotEmpty.wakeAll();
QueueBufferMutex.unlock(); }
十.在qt下如何访问一个共享对象呢?
这是一个我不断思考的问题:有一个共享的视频采集缓冲区(采集线程负责把视频数据放入缓冲区,压缩线程负责从缓冲区中取出视频数据再压缩),到底这个全局的视频采集缓冲区如何可以使采集线程和压缩线程共享呢,开始时我是把这个视频采集缓冲区对象放到采集线程中的,这样采集线程就能访问到这个视频采集缓冲区,但是压缩线程如何共享这个视频采集缓冲区呢?(由于这个压缩线程要读这个视频缓冲区要用到视频缓冲对象的一个读函数,但这个视频缓冲对象是在采集线程中定义的,压缩线程是不能访问采集线程下的子对象(视频采集缓冲区)这成了一个问题),经过两天的思考终于找到了一种办法(由于qt跟vc的编程方法有很大不同,加上网上的资料比较少),我决定把视频缓冲区对象放到主线程(界面对象)中,然后在采集线程和压缩线程中加上一个主线程对像(通过这个对象就能方便地使采集线程和压缩线程访问共享这个视频采集缓冲区).代码如下
MainWindow::MainWindow()//主线程 {
setWindowTitle(tr(“No movie loaded”)); setMinimumSize(320,240); resize(520,420);
label=new QLabel(this); setCentralWidget(label);
label->setBackgroundRole(QPalette::Dark); btn_start = new QPushButton(“start”,this);
btn_start ->setGeometry( QRect(50, 300, 80, 40)) ;
connect(btn_start,SIGNAL(clicked()),this, SLOT(save())) ;
piturebuf = (unsigned char *)malloc(320*240*4);
capbuff=new RingBuff();//新建一个视频采集缓冲区
m_enc = new CXvidEnc(this) ; //新建一个压缩对象(注意this) m_enc->AttachCaller(320, 240) ; CXvidEnc::XVID_GLOBAL_INIT() ; m_enc->Open() ;
m_enc->start();//启动压缩线程
a = new CapThread(this);//新建一个采集对象(注意this)
a->start();//启动采集线程 };
//主线程中对视频采集缓冲区的操作
void MainWindow::readCapBuff(unsigned char *data, int size) {
//unsigned char*piturebuf = (unsigned char *)malloc(320*240*4) ; capbuff->ring_read(data,size);
}
void MainWindow::writeCapBuff(unsigned char *data, int size) {
capbuff->ring_write(data,size); }
//采集线程
CapThread::CapThread(MainWindow *parent){
this->parent = parent;(与上面的this对应)
v4l_open(DEFAULT_DEVICE, &v4l_dev) ; v4l_get_capability(&v4l_dev); v4l_set_picture( &v4l_dev ); v4l_get_picture(&v4l_dev); v4l_init_mbuf(&v4l_dev); v4l_get_mbuf(&v4l_dev);
v4l_dev.picture.contrast = 110000; v4l_set_picture(&v4l_dev); }
//采集线程执行的任务 (把采集到的数据pBuffer放到视频采集缓冲区中) void CapThread::run() {
for(;;){
v4l_grab_movie(&v4l_dev);
unsigned char *pBuffer= v4l_dev.buffer;
parent->writeCapBuff(pBuffer,320*240*3);(这样就可以访问到共享的视频采集缓冲区了) } }
//压缩线程
CXvidEnc::CXvidEnc(MainWindow *parent) {
this->parent = parent; m_closed = true ;
//m_enc_caller = NULL ; m_enc_handle = NULL ; m_key = 0 ;

