In the development process will often encounter the need to use the ring buffer, such as in the context of streaming, for the received audio and video data storage, as well as the storage of the PCM data after decoding, it is best to use a ring buffer, received, or decoded into the buffer, in the need to decode, or need to plug into the sound card , and then read from the buffer, so that the same buffer is pressed in and out, both convenient and efficient, and safe and effective. The source code is as follows:
typedef char s8;typedef unsigned char u8;typedef short s16;typedef unsigned short u16;typedef int s32;typedef unsigned int u32;typedef unsigned uint32_t;typedef void *fifobufferhandle; //defines a pointer, Convenient external reference #ifndef _max#define _max (A,&NBSP;B) a > b ? a : b#endif# Ifndef _min#define _min (a, b) a > b ? b : a#endif// Defines a struct that records the start, read, write, and receive memory addresses of the buffer typedef struct _tfifobuffer{ u8 * Pu8buffer, *pu8read, *pu8write, *pu8end;} tfifobuffer, *ptfifobuffer;//creates a buffer of a specified size fifobufferhandle fifobuffercreate (s32 s32size) { PTFIFOBUFFER ptFifoBuffer = NULL; do { ptFifoBuffer = (PTFifobuffer) malloc (sizeof (Tfifobuffer)); if (null == Ptfifobuffer) { break; } memset (ptfifobuffer, 0, sizeof (tfifobuffer)); ptFifoBuffer->pu8Buffer = (u8 *) malloc (s32size); if (Null == ptfifobuffer->pu8buffer) { break; } memset (PtFifoBuffer->pu8Buffer, 0, s32size); ptfifobuffer->pu8write = Ptfifobuffer->pu8reaD = ptfifobuffer->pu8buffer; ptfifobuffer-> pu8end = ptfifobuffer->pu8buffer + s32size; if (Null == ptfifobuffer->pu8buffer) { break; } return (Fifobufferhandle) ptfifobuffer; }while (false); if (Null != ptfifobuffer) { if (Null != ptfifobuffer->pu8buffer) { free (Ptfifobuffer->pu8buffer); ptfifobuffer->pu8buffer = null; } free (Ptfifobuffer); ptfifobuffer = null; } return null;} Release a buffer Void fifobufferdestroy (fifobufferhandle phandle) { ptfifobuffer ptfifobuffer = (Ptfifobuffer) phandle; if (Null != ptfifobuffer) { if (NULL != ptFifoBuffer- >pu8buffer) { free (Ptfifobuffer->pu8buffer); ptFifoBuffer->pu8Buffer = NULL; } free (ptfifobufFER); ptfifobuffer = null; }}/ /reset buffer in read-write pointer void fifobufferreset (fifobufferhandle phandle) { ptfifobuffer ptfifobuffer = (Ptfifobuffer) phandle; if (Null != ptfifobuffer) { ptfifobuffer->pu8write = ptfifobuffer->pu8read = ptfifobuffer->pu8buffer; }}//Get size int fifobuffersize (Fifobufferhandle phandle) { s32 s32size = 0; PTFIFOBUFFER ptFifoBuffer = (Ptfifobuffer) phandle; if (Null != ptfifobuffer) { s32Size = ptFifoBuffer->pu8Write - ptFifoBuffer->pu8Read; if (s32size < 0) { s32Size += ptFifoBuffer->pu8End - ptFifoBuffer-> pu8buffer; } } Return s32size;} Writes data to the buffer S32 fifobufferwrite (fifobufferhandle phandle, u8 *pu8buffer, s32 S32size) { s32 s32length = 0; ptfifobuffer ptfifobuffer = (Ptfifobuffer) phandle; if (Null == ptfifobuffer) { return 0; } do { S32length = _min (ptfifobuffer->pu8end - ptfifobuffer->pu8write, s32size); memcpy (ptfifobuffer->pu8write, pu8buffer, s32length); pu8Buffer = pu8Buffer + s32Length; ptfifobuffer->pu8write += s32length; //backward Offset Write pointer //if the buffer write pointer reaches the tail of the buffer, Move the write pointer to the buffer start address to achieve a true ring //buffer if (ptfifobuffer->pu8write >= ptfifobuffer->pu8end) { ptfifobuffer->pu8write = ptfifobuffer->pu8buffer; } s32Size -= s32Length; }while (s32size > 0); return 1;} Read Data S32 fifobufferread (fifobufferhandle phandle, u8 *pu8buffer, s32 *ps32size) { s32 s32Length = 0, pTempSize = (*ps32size); PTFIFOBUFFER ptFifoBuffer = (Ptfifobuffer) phandle; if (NULL == ptfifobuffer | | null == pu8buffer | | 0 > ptempsize) { Return 0; } if (0 == ptempsize) { (*ps32size) = 0; return 1; } (*ps32size) = 0; do { S32length = _min (FifObuffersize (Phandle), ptempsize); s32length = _ Min (ptfifobuffer->pu8end - ptfifobuffer->pu8read, s32length); if (0 == s32length) { break; } memcpy (Pu8buffer, ptfifobuffer->pu8read, s32length); pu8buffer = pu8buffer + s32length; ptfifobuffer->pu8read = ptfifobuffer- >pu8read + s32length;//backward offset Read pointer //if the buffer read pointer reaches the end of the buffer, move the read pointer to the buffer start address to achieve a true ring //-Shaped buffer if (Ptfifobuffer->pu8read >= ptfifobuffer->pu8end ) { ptFifoBuffer->pu8Read = ptFifoBuffer->pu8Buffer; } pTempSize -= s32Length; (*ps32size) += s32length; }while ( ptempsize > 0); return 1;} S32 fifobuffershade (Fifobufferhandle phandle, s32 s32offset) { ptfifobuffer ptfifobuffer = (Ptfifobuffer) phandle; if (NULL != Ptfifobuffer) { if ((ptFifoBuffer-> Pu8read + s32offset) > ptfifobuffer->pu8end) { return * (ptfifobuffer->pu8buffer + (s32offset - (ptFifoBuffer-> Pu8end - ptfifobuffer->pu8read)); } else { return * (ptfifobuffer->pu8read + S32offset); } } return 0;}
When using this buffer, initialize a piece of appropriate size memory, and lock externally, while the read and write operations are kept basically consistent, if the user set the buffer too small, or the read-write rate gap is large, it will result in loss of user data.
The above code using pure C write, of course, can also be written in C + +, write a class, with the help of the string class can develop a more concise buffer buffer code, as long as the logical implementation of the problem can be.
This article is from the "Big bro" blog, make sure to keep this source http://9662841.blog.51cto.com/9652841/1585962
A/C + + implementation ring buffer