📄 zc030x_isochron.c
字号:
/* Implementation file for isochronous *//* Zc030x -- Driver -- Zc030x *//* This file is under GPL *//* Copyright : Martin Braun Cyril Russo---------------------------------------*//* Include the header */#include "zc030x_isochron.h"/* Include JPEG decoding */#include "zc030x_jpeg.h"/* Include allocating urbs */#include "zc030x_mm.h"/* Include V4L data */#include "zc030x_v4l.h"/* Include gamma things */#include "zc030x_cameras.h"// for 2.4 compatibility#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)#define URB_ISO_ASAP USB_ISO_ASAP#endif /* Define the implementation */DECLARE_TASKLET (decodetasklet,decode_tasklet,(unsigned long)NULL);/* Return the next free frame to grab into */zc030x_frame * zc030x_get_free_frame_tmp(struct usb_zc030x *dev){ int iFrameNext; /* Return object */ zc030x_frame * frame=NULL; if( dev->frame[dev->curframe].GrabState == FRAME_ERROR) { /* recycle the bad one */ frame=&dev->frame[dev->curframe]; } else { /* Cycle through the frame buffer looking for a free frame to overwrite */ iFrameNext = (dev->curframe + 1) % ZC030X_NUMFRAMES; while(frame==NULL && iFrameNext!=(dev->curframe)) { if (dev->frame[iFrameNext].GrabState == FRAME_READY || dev->frame[iFrameNext].GrabState == FRAME_UNUSED || dev->frame[iFrameNext].GrabState == FRAME_ERROR) { dev->curframe = iFrameNext; frame = &dev->frame[iFrameNext]; break; } else { iFrameNext=(iFrameNext + 1) % ZC030X_NUMFRAMES; } } } if(frame==NULL) { PDEBUG(3,"Can't find a free frame to grab into...using next. " "This is caused by the application not reading fast enough."); dev->curframe=(dev->curframe+1)%ZC030X_NUMFRAMES; frame = &dev->frame[dev->curframe]; } /* Change its state */ frame->GrabState = FRAME_GRABBING; /* Reset its available compressed size */ frame->CompLen = 0; frame->SeqNumber = 0; frame->ScanState = STATE_LINES; frame->last_packet=-1; /* Release it */ up(&frame->Lock); /* Okay, return */ up(&dev->buf_lock); return frame;}/* Return the next free frame to grab into */zc030x_frame * zc030x_get_free_frame_new(struct usb_zc030x *dev){ /* Iterator */ int iFrameNext, iNbFrame = 0; /* Return object */ zc030x_frame * frame=NULL; /* Check argument */ if (dev == NULL) { PDEBUG(2, "[ZCISO] Null argument to this function, exiting!"); dev->curframe = -1; return NULL; } /* Wait until the frame buffer is unlocked */ if(down_trylock(&dev->buf_lock)) { dev->curframe = -1; return NULL; } /* Check if a frame is trashed */ for (iFrameNext = 0; iFrameNext < ZC030X_NUMFRAMES; iFrameNext++) { /* Lock the frame to look to it*/ down(&dev->frame[iFrameNext].Lock); if (dev->frame[iFrameNext].GrabState == FRAME_ERROR) { up(&dev->frame[iFrameNext].Lock); frame = &dev->frame[iFrameNext]; dev->curframe = iFrameNext; iNbFrame ++; break; } if (dev->frame[iFrameNext].GrabState == FRAME_READY) { up(&dev->frame[iFrameNext].Lock); frame = &dev->frame[iFrameNext]; dev->curframe = iFrameNext; iNbFrame ++; break; } /* Unlock it */ up(&dev->frame[iFrameNext].Lock); } /* Check if we haven't found a frame */ if (frame == NULL) { PDEBUG(4,"ERROR: Can't find a free frame to grab into...using a waiting-to-be-presented frame. "); /* Check for an unused frame */ for (iFrameNext = 0; iFrameNext < ZC030X_NUMFRAMES; iFrameNext++) { /* Lock the frame to look to it*/ down(&dev->frame[iFrameNext].Lock); if (dev->frame[iFrameNext].GrabState == FRAME_DONE) { up(&dev->frame[iFrameNext].Lock); frame = &dev->frame[iFrameNext]; dev->curframe = iFrameNext; iNbFrame ++; break; } /* Unlock it */ up(&dev->frame[iFrameNext].Lock); } /* Not found a done frame, so leave now */ if (frame == NULL) { PDEBUG(4,"ERROR: Can't find a free frame to grab into...using an unused frame. "); /* Check for an unused frame */ for (iFrameNext = 0; iFrameNext < ZC030X_NUMFRAMES; iFrameNext++) { /* Lock the frame to look to it*/ down(&dev->frame[iFrameNext].Lock); if (dev->frame[iFrameNext].GrabState == FRAME_UNUSED) { up(&dev->frame[iFrameNext].Lock); frame = &dev->frame[iFrameNext]; dev->curframe = iFrameNext; iNbFrame ++; break; } /* Unlock it */ up(&dev->frame[iFrameNext].Lock); } if (frame == NULL) { /* Cannot get the frame now, so release the driver */ up(&dev->buf_lock); dev->curframe = -1; return NULL; } } } /* Set the frame state */ /* So lock the frame */ if(down_trylock(&frame->Lock)) { /* Cannot get the frame now, so release the driver */ up(&dev->buf_lock); dev->curframe = -1; return NULL; } /* Change its state */ frame->GrabState = FRAME_GRABBING; /* Reset its available compressed size */ frame->CompLen = 0; frame->SeqNumber = 0; frame->ScanState = STATE_LINES; frame->last_packet=-1; /* Release it */ up(&frame->Lock); /* Okay, return */ up(&dev->buf_lock); return frame;}/* Return the next free frame to grab into */zc030x_frame * zc030x_get_current_frame(struct usb_zc030x *dev){ /* Check argument */ if (dev == NULL) { PDEBUG(2, "[ZCISO] Null argument to this function, exiting!"); return NULL; } if (dev->curframe == -1) { return NULL; } else return &dev->frame[dev->curframe]; }/* Tasklet main function */void decode_tasklet (unsigned long ptr){ /* Error object */ int err; /* Lock the frame we get */ zc030x_frame * pFrame = (zc030x_frame *)ptr; PDEBUG(4, "decode_tasklet %p", pFrame); if (pFrame == NULL) { PDEBUG(2, "Decoding tasklet called without argument - exiting"); return; } if (down_trylock(&pFrame->Lock)) { PDEBUG(2, "Someone else is trying to access this frame - exiting"); return; } /* Debug the received frame */ PDEBUG(4, "Got Header(%dx%d) frame", pFrame->HeaderWidth, pFrame->HeaderHeight); /* And decode it */ err = zc030x_decode_frame( pFrame, pFrame->Format); PDEBUG(4, "zc030x_decodeFrame returned with code=%d",err); /* Check return */ if (err == 0) { PDEBUG(2, "frame decoding failed (%d)", err); /* Change its state */ pFrame->GrabState = FRAME_ERROR; } else { /* Change its state */ pFrame->GrabState = FRAME_DONE; } /* Release the lock */ up(&pFrame->Lock); /* Call next tasklet if needed */ if (waitqueue_active(&pFrame->wq)) wake_up_interruptible(&pFrame->wq); /* Debug this */ }/* Move the isochronous data received to decoder */int zc030x_move_data (struct usb_zc030x *dev, struct urb *urb){ /* Iterator */ int i; /* The data length */ int datalength; /* The status */ int st; /* Total length of this buffer */ int totlen = 0; /* Next packet buffer */ unsigned char *cData; /* Frame pointer */ zc030x_frame * frame = NULL; //Pointer to frame data /* Lock the buffer pool */ if(down_trylock(&dev->buf_lock)) return -ENOBUFS; /* Verify the V4L buffers still exist */ if(!dev->fbuf) { up(&dev->buf_lock); return -ENOBUFS; } /* Release the buffer lock */ up(&dev->buf_lock); /* Get pointer to a frame */ frame = zc030x_get_current_frame(dev); if (frame == NULL) { return -ENOBUFS; } /* Now copy the packet to the frame */ for (i = 0; i < urb->number_of_packets; i++) { datalength = urb->iso_frame_desc[i].actual_length; st = urb->iso_frame_desc[i].status; /* Debug errors if any */ if (st)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -