uint16_t BufferCount(Buffer_t* buffer) { if(BufferIsEmpty(buffer)) return 0;//Se il buffer è vuoto restituisco 0 if(BufferIsFull(buffer)) return buffer->size;//Se il buffer è pieno restituisco la dimensione del buffer if(buffer->firstElement < buffer->firstSpace) return buffer->firstSpace - buffer->firstElement;//Se il puntatore al primo elemento si trova prima del primo spazio libero restituisco la differenza tra i due else return buffer->size - (buffer->firstElement - buffer->firstSpace);//Se il puntatore al primo elemento di trova dopo il primo spazio libero restituisco la dimensione del buffer meno la differenza tra il puntatore al primo elemento e il primo spazio libero }
uint8_t BufferPush(Buffer_t* buffer, char value) { if (BufferIsFull(buffer)) return 0;//Se il buffer è pieno restituisco false if (BufferIsEmpty(buffer)) buffer->firstElement = buffer->firstSpace;//Se il buffer è vuoto imposto il puntatore al primo elemento al primo spazio libero *buffer->firstSpace = value;//Imposto il valore nel primo spazio disponibile nel buffer buffer->firstSpace++;//Sposto il puntatore una cella in avanti if(buffer->array + buffer->size == buffer->firstSpace) buffer->firstSpace = buffer->array;//Se il puntatore sconfina in una zona al di fuori del buffer lo si reimposta alla prima cella allocata return 1;//Restituisco true se il valore è stato inserito correttamente }
DWORD WINAPI threadAvsDec(LPVOID id) { BYTE pUVrow[info->width]; for (int f = 0; f < info->num_frames; f++) { while (BufferIsFull(frameBuffer)) Sleep(250); // only bad if encodes more than 1000fps, then decrease AVS_VideoFrame *frame = avs_get_frame(clip, f); const BYTE *pYplane = avs_get_read_ptr_p(frame, AVS_PLANAR_Y); const BYTE *pUplane = avs_get_read_ptr_p(frame, AVS_PLANAR_U); const BYTE *pVplane = avs_get_read_ptr_p(frame, AVS_PLANAR_V); BYTE *frameData = (BYTE*) malloc(hostPtrSize); BYTE *pBuf = frameData; // Y plane unsigned int pitch = avs_get_pitch_p(frame, AVS_PLANAR_Y); for (int h = 0; h < info->height; h++) { memcpy(pBuf, pYplane, info->width); pBuf += alignedSurfaceWidth; pYplane += pitch; } // UV planes unsigned int uiHalfHeight = info->height >> 1; unsigned int uiHalfWidth = info->width >> 1; //chromaWidth unsigned int pos = 0; for (unsigned int h = 0; h < uiHalfHeight; h++) { for (unsigned int i = 0; i < uiHalfWidth; ++i) { pUVrow[i*2] = pUplane[pos + i]; pUVrow[i*2 + 1] = pVplane[pos + i]; } memcpy(pBuf, pUVrow, info->width); pBuf += alignedSurfaceWidth; pos += uiHalfWidth; } BufferWrite(frameBuffer, (BufferType)frameData); // not sure release is needed, but it doesn't cause an error avs_release_frame(frame); } return 0; }
STATUSCODE GrowBuffer( PBUFOBJ pBufObj ) /*++ Routine Description: Grow the buffer used for holding the entry value Arguments: pBufObj - Specifies the buffer to be enlarged Return Value: ERR_NONE if successful, error code otherwise --*/ { DWORD newLength = pBufObj->maxLength + GROW_BUFFER_SIZE; PBYTE pBuffer; if (! BufferIsFull(pBufObj)) { Warning(("Trying to grow buffer while it's not yet full.\n")); } if (! (pBuffer = MemAlloc(newLength))) { Error(("Memory allocation failed\n")); return ERR_MEMORY; } if (pBufObj->pBuffer) { memcpy(pBuffer, pBufObj->pBuffer, pBufObj->size); MemFree(pBufObj->pBuffer); } pBufObj->pBuffer = pBuffer; pBufObj->maxLength = newLength; return ERR_NONE; }
/*制造产品*/ void Produce(struct Products* products, int item) { /*原子操作*/ pthread_mutex_lock(&products->locker); /*无空间可写入*/ while (BufferIsFull(products)) { pthread_cond_wait(&products->notFull, &products->locker); } /*写入数据*/ products->buffer[products->posWriteTo] = item; products->posWriteTo++; if (products->posWriteTo >= BUFFER_SIZE) products->posWriteTo = 0; /*发信*/ pthread_cond_signal(&products->notEmpty); /*解锁*/ pthread_mutex_unlock(&products->locker); }