int ARSTREAM2_H264_NaluFifoPushFreeItem(ARSTREAM2_H264_NaluFifo_t *fifo, ARSTREAM2_H264_NaluFifoItem_t *item) { if ((!fifo) || (!item)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (fifo->free) { fifo->free->prev = item; item->next = fifo->free; } else { item->next = NULL; } fifo->free = item; item->prev = NULL; ARSAL_Mutex_Unlock(&(fifo->mutex)); return 0; }
eARNETWORK_ERROR ARNETWORK_RingBuffer_PopFrontWithSize(ARNETWORK_RingBuffer_t *ringBuffer, uint8_t *dataPop, int dataSize) { /* -- Pop the oldest data -- */ /* local declarations */ uint8_t *buffer = NULL; eARNETWORK_ERROR error = ARNETWORK_OK; ARSAL_Mutex_Lock(&(ringBuffer->mutex)); if (!ARNETWORK_RingBuffer_IsEmptyUnlocked(ringBuffer)) { if(dataPop != NULL) { /* get the address of the front data */ buffer = ringBuffer->dataBuffer + (ringBuffer->indexOutput % (ringBuffer->numberOfCell * ringBuffer->cellSize)); memcpy(dataPop, buffer, dataSize); } /* No else: the data popped is not returned */ (ringBuffer->indexOutput) += ringBuffer->cellSize; ARNETWORK_RingBuffer_NormalizeIndexes(ringBuffer); } else { error = ARNETWORK_ERROR_BUFFER_EMPTY; } ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); return error; }
float ARSTREAM_Reader_GetEstimatedEfficiency (ARSTREAM_Reader_t *reader) { if (reader == NULL) { return -1.0f; } float retVal = 1.0f; uint32_t totalPackets = 0; uint32_t usefulPackets = 0; int i; ARSAL_Mutex_Lock (&(reader->ackPacketMutex)); for (i = 0; i < ARSTREAM_READER_EFFICIENCY_AVERAGE_NB_FRAMES; i++) { totalPackets += reader->efficiency_nbTotal [i]; usefulPackets += reader->efficiency_nbUseful [i]; } ARSAL_Mutex_Unlock (&(reader->ackPacketMutex)); if (totalPackets == 0) { retVal = 0.0f; // We didn't receive anything yet ... not really efficient } else if (usefulPackets > totalPackets) { retVal = 1.0f; // If this happens, it means that we have a big problem ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Computed efficiency is greater that 1.0 ..."); } else { retVal = (1.f * usefulPackets) / (1.f * totalPackets); } return retVal; }
int ARSTREAM2_H264_AuFifoAddQueue(ARSTREAM2_H264_AuFifo_t *fifo, ARSTREAM2_H264_AuFifoQueue_t *queue) { if ((!fifo) || (!queue)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } int mutexRet = ARSAL_Mutex_Init(&(queue->mutex)); if (mutexRet != 0) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Mutex creation failed (%d)", mutexRet); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); queue->count = 0; queue->head = NULL; queue->tail = NULL; queue->prev = NULL; queue->next = fifo->queue; if (queue->next) { queue->next->prev = queue; } fifo->queue = queue; fifo->queueCount++; ARSAL_Mutex_Unlock(&(fifo->mutex)); return 0; }
int ARSTREAM2_H264_AuFifoPushFreeItem(ARSTREAM2_H264_AuFifo_t *fifo, ARSTREAM2_H264_AuFifoItem_t *item) { if ((!fifo) || (!item)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } int ret = ARSTREAM2_H264_AuNaluFifoFlush(&item->au); if (ret != 0) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "ARSTREAM2_H264_AuNaluFifoFlush() failed (%d)", ret); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (fifo->itemFree) { fifo->itemFree->prev = item; item->next = fifo->itemFree; } else { item->next = NULL; } fifo->itemFree = item; item->prev = NULL; ARSAL_Mutex_Unlock(&(fifo->mutex)); return 0; }
eARNETWORK_ERROR ARNETWORK_RingBuffer_Front(ARNETWORK_RingBuffer_t *ringBuffer, uint8_t *frontData) { /* -- Return a pointer on the front data -- */ /* local declarations */ eARNETWORK_ERROR error = ARNETWORK_OK; uint8_t *buffer = NULL; ARSAL_Mutex_Lock(&(ringBuffer->mutex)); /* get the address of the front data */ buffer = ringBuffer->dataBuffer + (ringBuffer->indexOutput % (ringBuffer->numberOfCell * ringBuffer->cellSize)); if( !ARNETWORK_RingBuffer_IsEmptyUnlocked(ringBuffer) ) { memcpy(frontData, buffer, ringBuffer->cellSize); } else { error = ARNETWORK_ERROR_BUFFER_EMPTY; } ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); return error; }
ARSTREAM2_H264_AuFifoItem_t* ARSTREAM2_H264_AuFifoPopFreeItem(ARSTREAM2_H264_AuFifo_t *fifo) { if (!fifo) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return NULL; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (fifo->itemFree) { ARSTREAM2_H264_AuFifoItem_t* cur = fifo->itemFree; fifo->itemFree = cur->next; if (cur->next) cur->next->prev = NULL; cur->prev = NULL; cur->next = NULL; ARSAL_Mutex_Unlock(&(fifo->mutex)); return cur; } else { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "AU FIFO is full"); ARSAL_Mutex_Unlock(&(fifo->mutex)); return NULL; } }
void ARNETWORK_RingBuffer_DataPrint(ARNETWORK_RingBuffer_t *ringBuffer) { /* -- Print the contents of the ring buffer -- */ /* local declarations */ uint8_t *byteIterator = NULL; unsigned int cellIndex = 0; unsigned int byteIndex = 0; ARSAL_Mutex_Lock(&(ringBuffer->mutex)); /* for all cell of the ringBuffer */ for (cellIndex = ringBuffer->indexOutput ; cellIndex < ringBuffer->indexInput ; cellIndex += ringBuffer->cellSize ) { byteIterator = ringBuffer->dataBuffer + (cellIndex % (ringBuffer->numberOfCell * ringBuffer->cellSize) ); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," - 0x: "); /* for all byte of the cell */ for(byteIndex = 0 ; byteIndex < ringBuffer->cellSize ; ++byteIndex) { ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG,"%2x | ",*((uint8_t*)byteIterator)); ++byteIterator; } ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG,"\n"); } ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); }
int ARSTREAM2_H264_AuFifoEnqueueItem(ARSTREAM2_H264_AuFifoQueue_t *queue, ARSTREAM2_H264_AuFifoItem_t *item) { if ((!queue) || (!item)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } ARSAL_Mutex_Lock(&(queue->mutex)); item->next = NULL; if (queue->tail) { queue->tail->next = item; item->prev = queue->tail; } else { item->prev = NULL; } queue->tail = item; if (!queue->head) { queue->head = item; } queue->count++; ARSAL_Mutex_Unlock(&(queue->mutex)); return 0; }
ARSTREAM2_H264_AuFifoBuffer_t* ARSTREAM2_H264_AuFifoGetBuffer(ARSTREAM2_H264_AuFifo_t *fifo) { if (!fifo) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return NULL; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (fifo->bufferFree) { ARSTREAM2_H264_AuFifoBuffer_t* cur = fifo->bufferFree; fifo->bufferFree = cur->next; if (cur->next) cur->next->prev = NULL; cur->prev = NULL; cur->next = NULL; cur->refCount = 1; ARSAL_Mutex_Unlock(&(fifo->mutex)); return cur; } else { ARSAL_Mutex_Unlock(&(fifo->mutex)); ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "No free buffer in pool"); return NULL; } }
void* ARSTREAM_Reader_RunAckThread (void *ARSTREAM_Reader_t_Param) { ARSTREAM_NetworkHeaders_AckPacket_t sendPacket = {0}; ARSTREAM_Reader_t *reader = (ARSTREAM_Reader_t *)ARSTREAM_Reader_t_Param; memset(&sendPacket, 0, sizeof(sendPacket)); ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Ack sender thread running"); reader->ackThreadStarted = 1; while (reader->threadsShouldStop == 0) { int isPeriodicAck = 0; ARSAL_Mutex_Lock (&(reader->ackSendMutex)); if (reader->maxAckInterval <= 0) { ARSAL_Cond_Wait (&(reader->ackSendCond), &(reader->ackSendMutex)); } else { int retval = ARSAL_Cond_Timedwait (&(reader->ackSendCond), &(reader->ackSendMutex), reader->maxAckInterval); if (retval == -1 && errno == ETIMEDOUT) { isPeriodicAck = 1; } } ARSAL_Mutex_Unlock (&(reader->ackSendMutex)); /* Only send an ACK if the maxAckInterval value allows it. */ if ((reader->maxAckInterval > 0) || ((reader->maxAckInterval == 0) && (isPeriodicAck == 0))) { ARSAL_Mutex_Lock (&(reader->ackPacketMutex)); sendPacket.frameNumber = htods (reader->ackPacket.frameNumber); sendPacket.highPacketsAck = htodll (reader->ackPacket.highPacketsAck); sendPacket.lowPacketsAck = htodll (reader->ackPacket.lowPacketsAck); ARSAL_Mutex_Unlock (&(reader->ackPacketMutex)); ARNETWORK_Manager_SendData (reader->manager, reader->ackBufferID, (uint8_t *)&sendPacket, sizeof (sendPacket), NULL, ARSTREAM_Reader_NetworkCallback, 1); } } ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Ack sender thread ended"); reader->ackThreadStarted = 0; return (void *)0; }
void ARNETWORK_Sender_GotPingAck (ARNETWORK_Sender_t *senderPtr, struct timespec *startTime, struct timespec *endTime) { ARSAL_Mutex_Lock (&(senderPtr->pingMutex)); if ((senderPtr->isPingRunning == 1) && (ARSAL_Time_TimespecEquals (startTime, &(senderPtr->pingStartTime)))) { senderPtr->lastPingValue = ARSAL_Time_ComputeTimespecMsTimeDiff (startTime, endTime); senderPtr->isPingRunning = 0; } ARSAL_Mutex_Unlock (&(senderPtr->pingMutex)); }
int ARNETWORK_RingBuffer_GetFreeCellNumber(ARNETWORK_RingBuffer_t *ringBuffer) { int numberOfFreeCell = -1; ARSAL_Mutex_Lock(&(ringBuffer->mutex)); numberOfFreeCell = ringBuffer->numberOfCell - ( (ringBuffer->indexInput - ringBuffer->indexOutput) / ringBuffer->cellSize ); ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); return numberOfFreeCell; }
int ARNETWORK_RingBuffer_IsEmpty(ARNETWORK_RingBuffer_t *ringBuffer) { int isEmpty = 0; ARSAL_Mutex_Lock(&(ringBuffer->mutex)); isEmpty = (ringBuffer->indexInput == ringBuffer->indexOutput) ? 1 : 0; ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); return isEmpty; }
void ARSTREAM_Reader_StopReader (ARSTREAM_Reader_t *reader) { if (reader != NULL) { reader->threadsShouldStop = 1; /* Force unblock the ACK thread to allow it to shutdown quickly. * This is necessary if maxAckInterval is set to -1, 0 or a large value. * If maxAckInterval >= 0, an ACK packet will be sent as a side-effect. */ if (reader->ackThreadStarted == 1) { ARSAL_Mutex_Lock (&(reader->ackSendMutex)); ARSAL_Cond_Signal (&(reader->ackSendCond)); ARSAL_Mutex_Unlock (&(reader->ackSendMutex)); } } }
int ARSTREAM2_H264_AuFifoBufferAddRef(ARSTREAM2_H264_AuFifo_t *fifo, ARSTREAM2_H264_AuFifoBuffer_t *buffer) { if (!buffer) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); buffer->refCount++; ARSAL_Mutex_Unlock(&(fifo->mutex)); return 0; }
int ARSAL_Sem_Getvalue(ARSAL_Sem_t *sem, int *value) { int result = -1; if (NULL == sem || NULL == *sem || NULL == value) { errno = EINVAL; return result; } /* No else. */ #if __SAL_USE_POSIX_SEM result = sem_getvalue((sem_t *)*sem, value); #else /* * Custom getvalue algo: * Lock mutex * Read counter to *value * Unlock mutex */ ARSAL_Sem_CustomImpl_t *psem = (ARSAL_Sem_CustomImpl_t *)*sem; int unlockRes = 0; result = ARSAL_Mutex_Lock (&(psem->lock)); ARSAL_SEM_ERRNO_TRANSFORM (result); if (0 == result) { *value = psem->count; } /* No else. */ unlockRes = ARSAL_Mutex_Unlock (&(psem->lock)); if (0 != unlockRes) { result = -1; errno = unlockRes; } /* No else. */ #endif return result; }
eARCONTROLLER_ERROR ARCONTROLLER_Network_Resume (ARCONTROLLER_Network_t *networkController) { // -- Resumes the Network Controller -- eARCONTROLLER_ERROR error = ARCONTROLLER_OK; // Check parameters if (networkController == NULL) { error = ARCONTROLLER_ERROR_BAD_PARAMETER; } // No Else: the checking parameters sets error to ARNETWORK_ERROR_BAD_PARAMETER and stop the processing if (error == ARCONTROLLER_OK) { if (ARSAL_Mutex_Lock (&(networkController->mutex)) != 0) { error = ARCONTROLLER_ERROR_MUTEX; } } if (error == ARCONTROLLER_OK) { switch (networkController->state) { case ARCONTROLLER_NETWORK_STATE_PAUSE: networkController->state = ARCONTROLLER_NETWORK_STATE_RUNNING; break; case ARCONTROLLER_NETWORK_STATE_RUNNING: ARSAL_PRINT(ARSAL_PRINT_WARNING, ARCONTROLLER_NETWORK_TAG, "Nothing to do ; Network controller state : %d ", networkController->state); break; case ARCONTROLLER_NETWORK_STATE_STOPPED: error = ARCONTROLLER_ERROR_STATE; break; default: ARSAL_PRINT(ARSAL_PRINT_ERROR, ARCONTROLLER_NETWORK_TAG, "State : %d not known", networkController->state); break; } ARSAL_Mutex_Unlock (&(networkController->mutex)); } return error; }
eARCONTROLLER_ERROR ARCONTROLLER_Network_SetVideoReceiveCallback (ARCONTROLLER_Network_t *networkController, ARCONTROLLER_Stream_DecoderConfigCallback_t decoderConfigCallback, ARCONTROLLER_Stream_DidReceiveFrameCallback_t receiveFrameCallback, ARCONTROLLER_Stream_TimeoutFrameCallback_t timeoutFrameCallback, void *customData) { // -- Set Video Receive Callback -- eARCONTROLLER_ERROR error = ARCONTROLLER_OK; int locked = 0; // Check parameters if (networkController == NULL) { error = ARCONTROLLER_ERROR_BAD_PARAMETER; } // No Else: the checking parameters sets error to ARNETWORK_ERROR_BAD_PARAMETER and stop the processing if (error == ARCONTROLLER_OK) { if (ARSAL_Mutex_Lock (&(networkController->mutex)) != 0) { error = ARCONTROLLER_ERROR_MUTEX; } else { locked = 1; } } if (error == ARCONTROLLER_OK) { if (networkController->videoController != NULL) { error = ARCONTROLLER_Stream_SetReceiveFrameCallback (networkController->videoController, decoderConfigCallback, receiveFrameCallback, timeoutFrameCallback, customData); } else { error = ARCONTROLLER_ERROR_NO_VIDEO; } } if (locked) { ARSAL_Mutex_Unlock (&(networkController->mutex)); } return error; }
void ARNETWORK_RingBuffer_Print(ARNETWORK_RingBuffer_t *ringBuffer) { /* -- Print the state of the ring buffer -- */ ARSAL_Mutex_Lock(&(ringBuffer->mutex)); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," pointer dataBuffer :%p \n",ringBuffer->dataBuffer); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," numberOfCell :%d \n",ringBuffer->numberOfCell); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," cellSize :%d \n",ringBuffer->cellSize); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," indexOutput :%d \n",ringBuffer->indexOutput); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," indexInput :%d \n",ringBuffer->indexInput); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," overwriting :%d \n",ringBuffer->isOverwriting); ARSAL_PRINT(ARSAL_PRINT_WARNING, ARNETWORK_RINGBUFFER_TAG," data : \n"); ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); ARNETWORK_RingBuffer_DataPrint(ringBuffer); }
int ARNETWORK_Sender_GetPing (ARNETWORK_Sender_t *senderPtr) { int retVal = -1; ARSAL_Mutex_Lock (&(senderPtr->pingMutex)); if (senderPtr->isPingRunning == 1) { struct timespec now; ARSAL_Time_GetTime(&now); retVal = ARSAL_Time_ComputeTimespecMsTimeDiff (&(senderPtr->pingStartTime), &now); } if ((senderPtr->lastPingValue > retVal) || (senderPtr->lastPingValue == -1)) { retVal = senderPtr->lastPingValue; } ARSAL_Mutex_Unlock (&(senderPtr->pingMutex)); return retVal; }
eARCONTROLLER_ERROR ARCONTROLLER_Network_SetVideoStreamMP4Compliant (ARCONTROLLER_Network_t *networkController, int isMP4Compliant) { // -- Set video stream compliant with the mp4 format -- eARCONTROLLER_ERROR error = ARCONTROLLER_OK; int locked = 0; // Check parameters if (networkController == NULL) { error = ARCONTROLLER_ERROR_BAD_PARAMETER; } // No Else: the checking parameters sets error to ARCONTROLLER_ERROR_BAD_PARAMETER and stop the processing if (error == ARCONTROLLER_OK) { if (ARSAL_Mutex_Lock (&(networkController->mutex)) != 0) { error = ARCONTROLLER_ERROR_MUTEX; } else { locked = 1; } } if (error == ARCONTROLLER_OK) { // Check if the device has video if (networkController->hasVideo) { error = ARCONTROLLER_Stream_SetMP4Compliant (networkController->videoController, isMP4Compliant); } //NO else ; device has not video } // No else: skipped by an error if (locked) { ARSAL_Mutex_Unlock (&(networkController->mutex)); } return error; }
eARCONTROLLER_ERROR ARCONTROLLER_Network_StartVideoStream (ARCONTROLLER_Network_t *networkController) { // -- Start Video stream -- eARCONTROLLER_ERROR error = ARCONTROLLER_OK; int locked = 0; // Check parameters if (networkController == NULL) { error = ARCONTROLLER_ERROR_BAD_PARAMETER; } // No Else: the checking parameters sets error to ARNETWORK_ERROR_BAD_PARAMETER and stop the processing if (error == ARCONTROLLER_OK) { if (ARSAL_Mutex_Lock (&(networkController->mutex)) != 0) { error = ARCONTROLLER_ERROR_MUTEX; } else { locked = 1; } } if (error == ARCONTROLLER_OK) { // Check if the device has video if (networkController->hasVideo) { error = ARCONTROLLER_Stream_Start (networkController->videoController, networkController->networkManager); } //NO else ; device has not video } // No else: skipped by an error if (locked) { ARSAL_Mutex_Unlock (&(networkController->mutex)); } return error; }
eARNETWORK_ERROR ARNETWORK_RingBuffer_PushBackWithSize(ARNETWORK_RingBuffer_t *ringBuffer, const uint8_t *newData, int dataSize, uint8_t **dataCopy) { /* -- Add the new data at the back of the ring buffer with specification of the data size -- */ /* local declarations */ int error = ARNETWORK_OK; uint8_t* buffer = NULL; ARSAL_Mutex_Lock(&(ringBuffer->mutex)); /* check if the has enough free cell or the buffer is overwriting */ if ((ARNETWORK_RingBuffer_GetFreeCellNumberUnlocked(ringBuffer)) || (ringBuffer->isOverwriting)) { if (!ARNETWORK_RingBuffer_GetFreeCellNumberUnlocked(ringBuffer)) { (ringBuffer->indexOutput) += ringBuffer->cellSize; } /* No else: the ringBuffer is not full */ buffer = ringBuffer->dataBuffer + ( ringBuffer->indexInput % (ringBuffer->numberOfCell * ringBuffer->cellSize) ); memcpy(buffer, newData, dataSize); /* return the pointer on the data copy in the ring buffer */ if(dataCopy != NULL) { *dataCopy = buffer; } /* No else: data are not returned */ ringBuffer->indexInput += ringBuffer->cellSize; ARNETWORK_RingBuffer_NormalizeIndexes(ringBuffer); } else { error = ARNETWORK_ERROR_BUFFER_SIZE; } ARSAL_Mutex_Unlock(&(ringBuffer->mutex)); return error; }
ARSTREAM2_H264_AuFifoItem_t* ARSTREAM2_H264_AuFifoDequeueItem(ARSTREAM2_H264_AuFifoQueue_t *queue) { ARSTREAM2_H264_AuFifoItem_t* cur; if (!queue) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return NULL; } ARSAL_Mutex_Lock(&(queue->mutex)); if ((!queue->head) || (!queue->count)) { ARSAL_Mutex_Unlock(&(queue->mutex)); //ARSAL_PRINT(ARSAL_PRINT_VERBOSE, ARSTREAM2_H264_TAG, "FIFO is empty"); return NULL; } cur = queue->head; if (cur->next) { cur->next->prev = NULL; queue->head = cur->next; queue->count--; } else { queue->head = NULL; queue->count = 0; queue->tail = NULL; } cur->prev = NULL; cur->next = NULL; ARSAL_Mutex_Unlock(&(queue->mutex)); return cur; }
ARSTREAM2_H264_NaluFifoItem_t* ARSTREAM2_H264_NaluFifoDequeueItem(ARSTREAM2_H264_NaluFifo_t *fifo) { ARSTREAM2_H264_NaluFifoItem_t* cur; if (!fifo) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return NULL; } ARSAL_Mutex_Lock(&(fifo->mutex)); if ((!fifo->head) || (!fifo->count)) { ARSAL_Mutex_Unlock(&(fifo->mutex)); //ARSAL_PRINT(ARSAL_PRINT_VERBOSE, ARSTREAM2_H264_TAG, "NALU FIFO is empty"); return NULL; } cur = fifo->head; if (cur->next) { cur->next->prev = NULL; fifo->head = cur->next; fifo->count--; } else { fifo->head = NULL; fifo->count = 0; fifo->tail = NULL; } cur->prev = NULL; cur->next = NULL; ARSAL_Mutex_Unlock(&(fifo->mutex)); return cur; }
int ARSTREAM2_H264_NaluFifoEnqueueItem(ARSTREAM2_H264_NaluFifo_t *fifo, ARSTREAM2_H264_NaluFifoItem_t *item) { if ((!fifo) || (!item)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (fifo->count >= fifo->size) { ARSAL_Mutex_Unlock(&(fifo->mutex)); ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "NALU FIFO is full"); return -2; } item->next = NULL; if (fifo->tail) { fifo->tail->next = item; item->prev = fifo->tail; } else { item->prev = NULL; } fifo->tail = item; if (!fifo->head) { fifo->head = item; } fifo->count++; ARSAL_Mutex_Unlock(&(fifo->mutex)); return 0; }
int ARSTREAM2_H264_AuFifoUnrefBuffer(ARSTREAM2_H264_AuFifo_t *fifo, ARSTREAM2_H264_AuFifoBuffer_t *buffer) { if ((!fifo) || (!buffer)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (buffer->refCount != 0) { buffer->refCount--; } else { ARSAL_PRINT(ARSAL_PRINT_WARNING, ARSTREAM2_H264_TAG, "FIXME! Ref count is already null, this should not happen!"); } if (buffer->refCount == 0) { if (fifo->bufferFree) { fifo->bufferFree->prev = buffer; buffer->next = fifo->bufferFree; } else { buffer->next = NULL; } fifo->bufferFree = buffer; buffer->prev = NULL; } ARSAL_Mutex_Unlock(&(fifo->mutex)); return 0; }
int ARSTREAM2_H264_AuFifoRemoveQueue(ARSTREAM2_H264_AuFifo_t *fifo, ARSTREAM2_H264_AuFifoQueue_t *queue) { if ((!fifo) || (!queue)) { ARSAL_PRINT(ARSAL_PRINT_ERROR, ARSTREAM2_H264_TAG, "Invalid pointer"); return -1; } ARSAL_Mutex_Lock(&(fifo->mutex)); if (queue->prev) { queue->prev->next = queue->next; } if (queue->next) { queue->next->prev = queue->prev; } if ((!queue->prev) && (!queue->next)) { fifo->queue = NULL; } fifo->queueCount--; queue->prev = NULL; queue->next = NULL; queue->count = 0; queue->head = NULL; queue->tail = NULL; ARSAL_Mutex_Unlock(&(fifo->mutex)); ARSAL_Mutex_Destroy(&(queue->mutex)); return 0; }
void* ARSTREAM_Reader_RunDataThread (void *ARSTREAM_Reader_t_Param) { uint8_t *recvData = NULL; int recvSize; uint16_t previousFNum = UINT16_MAX; int skipCurrentFrame = 0; int packetWasAlreadyAck = 0; ARSTREAM_Reader_t *reader = (ARSTREAM_Reader_t *)ARSTREAM_Reader_t_Param; ARSTREAM_NetworkHeaders_DataHeader_t *header = NULL; int recvDataLen = reader->maxFragmentSize + sizeof (ARSTREAM_NetworkHeaders_DataHeader_t); /* Parameters check */ if (reader == NULL) { ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Error while starting %s, bad parameters", __FUNCTION__); return (void *)0; } /* Alloc and check */ recvData = malloc (recvDataLen); if (recvData == NULL) { ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Error while starting %s, can not alloc memory", __FUNCTION__); return (void *)0; } header = (ARSTREAM_NetworkHeaders_DataHeader_t *)recvData; ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Stream reader thread running"); reader->dataThreadStarted = 1; while (reader->threadsShouldStop == 0) { eARNETWORK_ERROR err = ARNETWORK_Manager_ReadDataWithTimeout (reader->manager, reader->dataBufferID, recvData, recvDataLen, &recvSize, ARSTREAM_READER_DATAREAD_TIMEOUT_MS); if (ARNETWORK_OK != err) { if (ARNETWORK_ERROR_BUFFER_EMPTY != err) { ARSAL_PRINT (ARSAL_PRINT_ERROR, ARSTREAM_READER_TAG, "Error while reading stream data: %s", ARNETWORK_Error_ToString (err)); } } else { int cpIndex, cpSize, endIndex; ARSAL_Mutex_Lock (&(reader->ackPacketMutex)); if (header->frameNumber != reader->ackPacket.frameNumber) { reader->efficiency_index ++; reader->efficiency_index %= ARSTREAM_READER_EFFICIENCY_AVERAGE_NB_FRAMES; reader->efficiency_nbTotal [reader->efficiency_index] = 0; reader->efficiency_nbUseful [reader->efficiency_index] = 0; skipCurrentFrame = 0; reader->currentFrameSize = 0; reader->ackPacket.frameNumber = header->frameNumber; #ifdef DEBUG uint32_t nackPackets = ARSTREAM_NetworkHeaders_AckPacketCountNotSet (&(reader->ackPacket), header->fragmentsPerFrame); if (nackPackets != 0) { ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Dropping a frame (missing %d fragments)", nackPackets); } #endif ARSTREAM_NetworkHeaders_AckPacketResetUpTo (&(reader->ackPacket), header->fragmentsPerFrame); } packetWasAlreadyAck = ARSTREAM_NetworkHeaders_AckPacketFlagIsSet (&(reader->ackPacket), header->fragmentNumber); ARSTREAM_NetworkHeaders_AckPacketSetFlag (&(reader->ackPacket), header->fragmentNumber); reader->efficiency_nbTotal [reader->efficiency_index] ++; if (packetWasAlreadyAck == 0) { reader->efficiency_nbUseful [reader->efficiency_index] ++; } ARSAL_Mutex_Unlock (&(reader->ackPacketMutex)); ARSAL_Mutex_Lock (&(reader->ackSendMutex)); ARSAL_Cond_Signal (&(reader->ackSendCond)); ARSAL_Mutex_Unlock (&(reader->ackSendMutex)); cpIndex = reader->maxFragmentSize * header->fragmentNumber; cpSize = recvSize - sizeof (ARSTREAM_NetworkHeaders_DataHeader_t); endIndex = cpIndex + cpSize; while ((endIndex > reader->currentFrameBufferSize) && (skipCurrentFrame == 0) && (packetWasAlreadyAck == 0)) { uint32_t nextFrameBufferSize = reader->maxFragmentSize * header->fragmentsPerFrame; uint32_t dummy; uint8_t *nextFrameBuffer = reader->callback (ARSTREAM_READER_CAUSE_FRAME_TOO_SMALL, reader->currentFrameBuffer, reader->currentFrameSize, 0, 0, &nextFrameBufferSize, reader->custom); if (nextFrameBufferSize >= reader->currentFrameSize && nextFrameBufferSize > 0) { memcpy (nextFrameBuffer, reader->currentFrameBuffer, reader->currentFrameSize); } else { skipCurrentFrame = 1; } //TODO: Add "SKIP_FRAME" reader->callback (ARSTREAM_READER_CAUSE_COPY_COMPLETE, reader->currentFrameBuffer, reader->currentFrameSize, 0, skipCurrentFrame, &dummy, reader->custom); reader->currentFrameBuffer = nextFrameBuffer; reader->currentFrameBufferSize = nextFrameBufferSize; } if (skipCurrentFrame == 0) { if (packetWasAlreadyAck == 0) { memcpy (&(reader->currentFrameBuffer)[cpIndex], &recvData[sizeof (ARSTREAM_NetworkHeaders_DataHeader_t)], recvSize - sizeof (ARSTREAM_NetworkHeaders_DataHeader_t)); } if (endIndex > reader->currentFrameSize) { reader->currentFrameSize = endIndex; } ARSAL_Mutex_Lock (&(reader->ackPacketMutex)); if (ARSTREAM_NetworkHeaders_AckPacketAllFlagsSet (&(reader->ackPacket), header->fragmentsPerFrame)) { if (header->frameNumber != previousFNum) { int nbMissedFrame = 0; int isFlushFrame = ((header->frameFlags & ARSTREAM_NETWORK_HEADERS_FLAG_FLUSH_FRAME) != 0) ? 1 : 0; ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Ack all in frame %d (isFlush : %d)", header->frameNumber, isFlushFrame); if (header->frameNumber != previousFNum + 1) { nbMissedFrame = header->frameNumber - previousFNum - 1; ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Missed %d frames !", nbMissedFrame); } previousFNum = header->frameNumber; skipCurrentFrame = 1; reader->currentFrameBuffer = reader->callback (ARSTREAM_READER_CAUSE_FRAME_COMPLETE, reader->currentFrameBuffer, reader->currentFrameSize, nbMissedFrame, isFlushFrame, &(reader->currentFrameBufferSize), reader->custom); } } ARSAL_Mutex_Unlock (&(reader->ackPacketMutex)); } } } free (recvData); reader->callback (ARSTREAM_READER_CAUSE_CANCEL, reader->currentFrameBuffer, reader->currentFrameSize, 0, 0, &(reader->currentFrameBufferSize), reader->custom); ARSAL_PRINT (ARSAL_PRINT_DEBUG, ARSTREAM_READER_TAG, "Stream reader thread ended"); reader->dataThreadStarted = 0; return (void *)0; }