/****************************************************************************** * Function: RtlMBoxIdToHdl * Desc: Map a mailbox ID to the mailbox pointer. * Para: * MBoxId: The Mailbox ID * Return: The pointer of the mailbox. If didn't found match mailbox, * return NULL. * ******************************************************************************/ static PRTL_MAILBOX RtlMBoxIdToHdl( IN u8 MBoxId ) { RTL_MAILBOX *pMbox=NULL; RTL_MAILBOX *pTmpMbox; _LIST *pHead; _LIST *pList; // if the Mailbox root entry initialed ? if not, initial it if (!MBox_Entry.isInitialed) { RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox MBox_Entry.isInitialed = 1; MSG_MBOX_INFO("MBox Entry Initial...\n"); } pHead = &MBox_Entry.mbox_list; RtlDownMutex(&MBox_Entry.Mutex); pList = RtlListGetNext(&MBox_Entry.mbox_list); while (pList != pHead) { pTmpMbox = CONTAINER_OF(pList, RTL_MAILBOX, mbox_list); if (MBoxId == pTmpMbox->mbox_id) { pMbox = pTmpMbox; break; } pList = RtlListGetNext(pList); } RtlUpMutex(&MBox_Entry.Mutex); return pMbox; }
/****************************************************************************** * Function: RtlMailboxCreate * Desc: To create a mailbox with a given mailbox ID and size * Para: * MboxID: A number to identify this created mailbox. A message block can * be send to a mailbox by a given MboxID. The MboxID must be unique * in the whole system. If this MboxID is conflict with a created * mailbox, the mailbox creation will fail and return NULL. * MboxSize: The size of this mailbox to be created. It means maximum number * of message blocks can be stored in this mailbox. * pWakeSema: The semaphore to wake up the receiving task to receive the new * message. If the receiving task doesn't need a semaphore to wakeup * it, then just let this pointer is NULL. * Return: The created mailbox pointer. If it failed, return NULL. ******************************************************************************/ PRTL_MAILBOX RtlMailboxCreate( IN u8 MboxID, IN u32 MboxSize, IN _Sema *pWakeSema ) { PRTL_MAILBOX pMBox=NULL; // if the Mailbox root entry initialed ? if not, initial it if (!MBox_Entry.isInitialed) { RtlMutexInit(&MBox_Entry.Mutex); // Init the Mutex for the mailbox add/delete procedure protection RtlInitListhead(&MBox_Entry.mbox_list); // Init the link list head to chain all created mailbox MBox_Entry.isInitialed = 1; MSG_MBOX_INFO("MBox Entry Initial...\n"); } // check if this mailbox ID is ocupied ? pMBox = RtlMBoxIdToHdl(MboxID); if (NULL != pMBox) { MSG_MBOX_ERR("RtlMailboxCreate: The Mailbox ID %d is used by someone!!\n", MboxID); return NULL; } pMBox = (RTL_MAILBOX *)RtlZmalloc(sizeof(RTL_MAILBOX)); if (NULL==pMBox) { MSG_MBOX_ERR("RtlMailboxCreate: MAlloc Failed\n"); return NULL; } RtlInitListhead(&pMBox->mbox_list); // Init the link list to be chained into the created mailbox list pMBox->mbox_id = MboxID; pMBox->pWakeSema = pWakeSema; #ifdef PLATFORM_FREERTOS pMBox->mbox_hdl = xQueueCreate(MboxSize, sizeof(MSG_BLK)); if (NULL == pMBox->mbox_hdl) { MSG_MBOX_ERR("RtlMailboxCreate: xQueueCreate Failed\n"); RtlMfree((void *)pMBox, sizeof(RTL_MAILBOX)); return NULL; } #endif #ifdef PLATFORM_ECOS // TODO: Create mailbox #endif // Add this mailbox to the link list of created mailbox RtlDownMutex(&MBox_Entry.Mutex); RtlListInsertTail(&pMBox->mbox_list, &MBox_Entry.mbox_list); RtlUpMutex(&MBox_Entry.Mutex); MSG_MBOX_INFO("A Mailbox Created: Size=%d\n", MboxSize); return pMBox; }
/****************************************************************************** * Function: RtlMailboxDel * Desc: To delete a mailbox by a given mailbox handle. * Para: * MboxHdl: The handle of the mailbox to be deleted. * Return: None. ******************************************************************************/ VOID RtlMailboxDel( IN PRTL_MAILBOX MboxHdl ) { if (NULL == MboxHdl) { MSG_MBOX_ERR("RtlMailboxDel: Try to delete a NULL mailbox\n"); return; } // Remove this mailbox from the link list of created mailbox RtlDownMutex(&MBox_Entry.Mutex); RtlListDelete(&MboxHdl->mbox_list); RtlUpMutex(&MBox_Entry.Mutex); // delete the Queue/Mailbox #ifdef PLATFORM_FREERTOS vQueueDelete((xQueueHandle)(MboxHdl->mbox_hdl)); #endif #ifdef PLATFORM_ECOS // TODO: Delete mailbox #endif RtlMfree((void *)MboxHdl, sizeof(RTL_MAILBOX)); }
void uvc_entry_handle(void *param) { int i, ret, cnt; struct stream_context *stream_ctx = (struct stream_context *)param; struct uvc_buf_context buf; struct rtp_object *payload; /*initialize rtp payload*/ for(i = 0; i < VIDEO_MAX_FRAME; i++) { if(rtp_init_payload(stream_ctx, &rtp_payload[i]) < 0) { for(; i>=0; i--) { rtp_uninit_payload(stream_ctx, &rtp_payload[i]); } goto exit; } } if(uvc_set_param(stream_ctx, UVC_FORMAT_MJPEG, 640, 480, 30)<0) goto exit; if(uvc_stream_on(stream_ctx)<0) goto exit; /*do buffer queue & dequeue inside the loop*/ payload_queue.flush_err = 0; while(!(payload_queue.flush_err)) { memset(&buf, 0, sizeof(struct uvc_buf_context)); ret = uvc_dqbuf(stream_ctx, &buf); if(buf.index < 0) continue;//empty buffer retrieved if((uvc_buf_check(&buf)<0)||(ret < 0)){ RTSP_ERROR("\n\rbuffer error!"); ret = -ENOENT; goto exit; } rtp_payload[buf.index].index = buf.index; if(rtp_fill_payload(stream_ctx, &rtp_payload[buf.index], buf.data, buf.len) < 0) goto exit; /*add rtp_payload into payload queue*/ RtlDownMutex(&payload_queue.wait_mutex); list_add_tail(&rtp_payload[buf.index].rtp_list, &payload_queue.wait_queue); RtlUpMutex(&payload_queue.wait_mutex); RtlUpSema(&payload_queue.wait_sema); //check if any rtp payload is queued in done_queue while(RtlDownSemaWithTimeout(&payload_queue.done_sema, 5)==0) { if(payload_queue.flush_err) goto exit; } if(!list_empty(&payload_queue.done_queue)) { RtlDownMutex(&payload_queue.done_mutex); payload = list_first_entry(&payload_queue.done_queue, struct rtp_object, rtp_list); if(payload == NULL) { RtlUpMutex(&payload_queue.done_mutex); continue; } list_del_init(&payload->rtp_list); RtlUpMutex(&payload_queue.done_mutex); buf.index = payload->index; buf.data = payload->data; buf.len = payload->len; ret = uvc_qbuf(stream_ctx, &buf); if (ret < 0){ RTSP_ERROR("\n\rread_frame mmap method enqueue buffer failed"); ret = -ENOENT; goto exit; } } }