实现了一个 native层读写音频数据时用到的一个 音频数据缓冲区(线程安全的)(c++)

MediaBuffer.hh:

#ifndef Live555_MediaBuffer_h
#define Live555_MediaBuffer_h

#include <sys/types.h>
//#ifndef _BOOLEAN_HH
//#include "Boolean.hh"
//#endif

#include <pthread.h>

class MediaBuffer{
private:
    unsigned char *m_lpData;         // the whole buffer
    int m_iCapacity;        			// the total size of the buffer
	int m_iWriteOffset;				// where the encode begins to write to
	int m_iWritableSize;				// how many data is available to write
    int m_iReadOffset;      			// where the broadcast begins to read from
    int m_iReadableSize;    			// how many data is available to read
	//pthread_mutex_t m_lock;		// lock
    //pthread_cond_t m_writeCond; // write condition

public:
    pthread_mutex_t m_lock;	// lock
    pthread_cond_t m_readCond;  // read condition

public:
    MediaBuffer(int iCapacity);
    ~MediaBuffer();

public:
	bool hasAvailableDataToWrite() { return m_iWritableSize > 0; }
	bool hasAvailableDataToRead() { return m_iReadableSize > 0; }
	int getReadableSize(){ return m_iReadableSize;}
	int getWriteableSize(){ return m_iWritableSize;}

    //void waitUntilHasDataToWrite();
    //void waitUntilHasDataToRead();

public:
	int readOffset() { return m_iReadOffset; }
	int writeOffset() { return m_iWriteOffset; }

public:
	// return the size of bytes that are actually written to the buffer
    int write(const unsigned char *lpData, int iSize);
	// return the size of bytes that are actually read from the buffer
    int read(unsigned char *lpData, int iSize);

public:
    void reset();
};

#endif



MediaBuffer.cpp :

#include <iostream>
#include <string.h>
#include "MediaBuffer.hh"
#include <stdio.h>
#include <exception>

MediaBuffer::MediaBuffer(int iCapacity)
{
    if(iCapacity > 0){
        m_iCapacity = iCapacity;
        m_lpData = new unsigned char[m_iCapacity];

		m_iWriteOffset = 0;
		m_iWritableSize = m_iCapacity;
        m_iReadableSize = 0;
        m_iReadOffset = 0;

		pthread_mutex_init(&m_lock, NULL);
        pthread_cond_init(&m_readCond, NULL);
        //pthread_cond_init(&m_writeCond, NULL);
    }
}

MediaBuffer::~MediaBuffer()
{
	pthread_mutex_destroy(&m_lock);
    pthread_cond_destroy(&m_readCond);
    //pthread_cond_destroy(&m_writeCond);

    if(NULL != m_lpData){
        delete [] m_lpData;
    }
}

void MediaBuffer::reset()
{
    pthread_mutex_lock(&m_lock);

    m_iWriteOffset = 0;
    m_iWritableSize = m_iCapacity;
    m_iReadableSize = 0;
    m_iReadOffset = 0;

    pthread_mutex_unlock(&m_lock);
}

//void MediaBuffer::waitUntilHasDataToRead()
//{
//    pthread_mutex_lock(&m_lock);
//
//    pthread_cond_wait(&m_readCond, &m_lock);
//
//    pthread_mutex_unlock(&m_lock);
//}
//
//void MediaBuffer::waitUntilHasDataToWrite()
//{
//    pthread_mutex_lock(&m_lock);
//
//    pthread_cond_wait(&m_writeCond, &m_lock);
//
//    pthread_mutex_unlock(&m_lock);
//}

int MediaBuffer::write(const unsigned char *lpData, int iSize)
{
	pthread_mutex_lock(&m_lock);

	// determine the maximum size that can be written to the buffer
	int iMaxAllowedSize = iSize > m_iWritableSize ? m_iWritableSize : iSize;

	// write data to the buffer, need to check whether it reaches the end of the buffer
	int iNextOffset = m_iWriteOffset + iMaxAllowedSize;
	if(iNextOffset < m_iCapacity){
		// just write to the buffer
		memcpy(m_lpData + m_iWriteOffset, lpData, iMaxAllowedSize);
	}
	else{
		fprintf(stderr, "DEBUG: write reaches the end of buffer.\n");

		iNextOffset -= m_iCapacity;
		int iFirstBlockSize = m_iCapacity - m_iWriteOffset;
		int iSecondBlockSize = iMaxAllowedSize - iFirstBlockSize;

		memcpy(m_lpData + m_iWriteOffset, lpData, iFirstBlockSize);
		memcpy(m_lpData, lpData + iFirstBlockSize, iSecondBlockSize);
	}
	m_iWriteOffset = iNextOffset;
	m_iWritableSize -= iMaxAllowedSize;
	m_iReadableSize += iMaxAllowedSize;

    pthread_cond_signal(&m_readCond);

	pthread_mutex_unlock(&m_lock);

    return iMaxAllowedSize;
}

int MediaBuffer::read(unsigned char *lpData, int iSize)
{
		pthread_mutex_lock(&m_lock);

		// determine the maximum size that can be read from the buffer
		int iMaxAllowedSize = iSize > m_iReadableSize ? m_iReadableSize : iSize;

		// read data from the buffer, need to check whether it reaches the end of the buffer
		int iNextOffset = m_iReadOffset + iMaxAllowedSize;
		if(iNextOffset < m_iCapacity){
			// just read from the buffer
			memcpy(lpData, m_lpData + m_iReadOffset, iMaxAllowedSize);
		}
		else{
			//fprintf(stderr, "DEBUG: read reaches the end of buffer.\n");
			iNextOffset -= m_iCapacity;
			int iFirstBlockSize = m_iCapacity - m_iReadOffset;
			int iSecondBlockSize = iMaxAllowedSize - iFirstBlockSize;

			memcpy(lpData, m_lpData + m_iReadOffset, iFirstBlockSize);
			memcpy(lpData + iFirstBlockSize, m_lpData, iSecondBlockSize);
		}
		m_iReadOffset = iNextOffset;
		m_iReadableSize -= iMaxAllowedSize;
		m_iWritableSize += iMaxAllowedSize;

		//pthread_cond_signal(&m_writeCond);

	//	fprintf(stderr, "DEBUG: %d is read.\n", iMaxAllowedSize);

		pthread_mutex_unlock(&m_lock);

		return iMaxAllowedSize;
}



你可能感兴趣的:(C++,null,delete,buffer,Signal)