/****************************************************************************** * xrunRecovery * ***************************************************************************/ static Int xrunRecovery(snd_pcm_t *rc, Int err) { if (err == -EPIPE) { if (snd_pcm_prepare(rc) < 0) { Dmai_err1("Failed to recover from over or underrun on %s\n", AUDIO_DEVICE); return Dmai_EFAIL; } } else if (err == -ESTRPIPE) { while ((err = snd_pcm_resume(rc)) == -EAGAIN) { sleep (1); /* wait until the suspend flag is released */ } if (snd_pcm_prepare(rc) < 0) { Dmai_err1("Failed to recover from over or underrun on %s\n", AUDIO_DEVICE); return Dmai_EFAIL; } } else { return Dmai_EFAIL; } return Dmai_EOK; }
/****************************************************************************** * Framecopy_resizer_accel_execute ******************************************************************************/ Int Framecopy_resizer_accel_execute(Framecopy_Handle hFc, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { #if defined(CONFIG_VIDEO_OMAP34XX_ISP_RESIZER) Int i; struct v4l2_buffer qbuf[2]; assert(hFc); assert(hSrcBuf); assert(hDstBuf); /* Pointers must be a multiple of 32 bytes */ assert((Buffer_getPhysicalPtr(hDstBuf) & 0x1F) == 0); assert((Buffer_getPhysicalPtr(hSrcBuf) & 0x1F) == 0); /* Queue the resizer buffers */ for (i=0; i < 2; i++) { qbuf[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; qbuf[i].memory = V4L2_MEMORY_USERPTR; qbuf[i].index = i; if (ioctl (hFc->fd, RSZ_QUERYBUF, &qbuf[i]) == -1) { Dmai_err1("Failed to query buffer index %d\n", i); return Dmai_EFAIL; } if (i == 0) { qbuf[i].m.userptr = (unsigned long) Buffer_getUserPtr(hSrcBuf); } else { qbuf[i].m.userptr = (unsigned long) Buffer_getUserPtr(hDstBuf); } if (ioctl (hFc->fd, RSZ_QUEUEBUF, &qbuf[i]) == -1) { Dmai_err1("Failed to queue buffer index %d\n",i); return Dmai_EFAIL; } } if (ioctl(hFc->fd, RSZ_RESIZE, NULL) == -1) { Dmai_err0("Failed to execute resize job\n"); return Dmai_EFAIL; } Buffer_setNumBytesUsed(hDstBuf, Buffer_getNumBytesUsed(hSrcBuf)); return Dmai_EOK; #else Dmai_err0("not implemented\n"); return Dmai_ENOTIMPL; #endif /* end CONFIG_VIDEO_OMAP34XX_ISP_RESIZER */ }
/****************************************************************************** * Resize_create ******************************************************************************/ Resize_Handle Resize_create(Resize_Attrs *attrs) { #ifdef CONFIG_DM365_IPIPE Resize_Handle hResize; unsigned long oper_mode; assert(attrs); hResize = (Resize_Handle)calloc(1, sizeof(Resize_Object)); if (hResize == NULL) { Dmai_err0("Failed to allocate space for Framecopy Object\n"); return NULL; } /* Open resizer device */ hResize->fd = open(RESIZER_DEVICE, O_RDWR); if (hResize->fd == -1) { Dmai_err1("Failed to open %s\n", RESIZER_DEVICE); return NULL; } oper_mode = IMP_MODE_SINGLE_SHOT; if (ioctl(hResize->fd,RSZ_S_OPER_MODE, &oper_mode) < 0) { Dmai_err0("Resizer can't set operation mode\n"); goto cleanup; } if (ioctl(hResize->fd,RSZ_G_OPER_MODE, &oper_mode) < 0) { Dmai_err0("Resizer can't get operation mode\n"); goto cleanup; } if (oper_mode != IMP_MODE_SINGLE_SHOT) { Dmai_err1("Resizer can't set operation mode single shot, the mode is %d\n", oper_mode); goto cleanup; } return hResize; cleanup: close(hResize->fd); hResize->fd = 0; return NULL; #else Dmai_err0("not implemented\n"); return NULL; #endif }
/****************************************************************************** * cleanup ******************************************************************************/ static Int cleanup(Display_Handle hDisplay) { Int ret = Dmai_EOK; BufTab_Handle hBufTab = hDisplay->hBufTab; enum v4l2_buf_type type; Int bufIdx; Buffer_Handle hDispBuf; if (hDisplay->fd != -1) { if (hDisplay->started) { /* Shut off the video display */ type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(hDisplay->fd, VIDIOC_STREAMOFF, &type) == -1) { Dmai_err1("VIDIOC_STREAMOFF failed (%s)\n", strerror(errno)); ret = Dmai_EFAIL; } } if (close(hDisplay->fd) == -1) { Dmai_err1("Failed to close capture device (%s)\n", strerror(errno)); ret = Dmai_EIO; } if (hDisplay->userAlloc == FALSE) { if (hBufTab) { for (bufIdx = 0; bufIdx < BufTab_getNumBufs(hBufTab); bufIdx++) { hDispBuf = BufTab_getBuf(hBufTab, bufIdx); if (munmap(Buffer_getUserPtr(hDispBuf), Buffer_getSize(hDispBuf)) == -1) { Dmai_err1("Failed to unmap capture buffer%d\n", bufIdx); ret = Dmai_EFAIL; } } } } } if (hDisplay->bufDescs) { free(hDisplay->bufDescs); } free(hDisplay); return ret; }
/****************************************************************************** * cleanup ******************************************************************************/ static Int cleanup(Capture_Handle hCapture) { BufTab_Handle hBufTab = hCapture->hBufTab; Int ret = Dmai_EOK; Int8 *capBufPtr; enum v4l2_buf_type type; Uns bufIdx; Buffer_Handle hCapBuf; if (hCapture->fd != -1) { if (hCapture->started) { /* Shut off the video capture */ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(hCapture->fd, VIDIOC_STREAMOFF, &type) == -1) { Dmai_err1("VIDIOC_STREAMOFF failed (%s)\n", strerror(errno)); ret = Dmai_EFAIL; } } if (close(hCapture->fd) == -1) { Dmai_err1("Failed to close capture device (%s)\n", strerror(errno)); ret = Dmai_EIO; } if (hCapture->userAlloc == FALSE && hBufTab) { for (bufIdx = 0; bufIdx < BufTab_getNumBufs(hBufTab); bufIdx++) { hCapBuf = BufTab_getBuf(hBufTab, bufIdx); capBufPtr = Buffer_getUserPtr(hCapBuf); if (munmap(capBufPtr - hCapture->topOffset, Buffer_getSize(hCapBuf)) == -1) { Dmai_err1("Failed to unmap capture buffer%d\n", bufIdx); ret = Dmai_EFAIL; } } } if (hCapture->bufDescs) { free(hCapture->bufDescs); } } free(hCapture); return ret; }
/****************************************************************************** * Display_v4l2_put ******************************************************************************/ Int Display_v4l2_put(Display_Handle hDisplay, Buffer_Handle hBuf) { Int idx; assert(hDisplay); assert(hBuf); idx = getUsedIdx(hDisplay->bufDescs, BufTab_getNumBufs(hDisplay->hBufTab)); if (idx < 0) { Dmai_err0("No v4l2 buffers available\n"); return Dmai_ENOMEM; } hDisplay->bufDescs[idx].v4l2buf.m.userptr = (Int)Buffer_getUserPtr(hBuf); hDisplay->bufDescs[idx].v4l2buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; /* Issue captured frame buffer back to device driver */ if (ioctl(hDisplay->fd, VIDIOC_QBUF, &hDisplay->bufDescs[idx].v4l2buf) == -1) { Dmai_err1("VIDIOC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } hDisplay->bufDescs[idx].hBuf = hBuf; hDisplay->bufDescs[idx].used = FALSE; return Dmai_EOK; }
/****************************************************************************** * Display_v4l2_get ******************************************************************************/ Int Display_v4l2_get(Display_Handle hDisplay, Buffer_Handle *hBufPtr) { struct v4l2_buffer v4l2buf; assert(hDisplay); assert(hBufPtr); Dmai_clear(v4l2buf); v4l2buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; v4l2buf.memory = hDisplay->userAlloc ? V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP; Dmai_clear(v4l2buf); v4l2buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; v4l2buf.memory = hDisplay->userAlloc ? V4L2_MEMORY_USERPTR : V4L2_MEMORY_MMAP; /* Get a frame buffer with captured data */ if(ioctl(hDisplay->fd, VIDIOC_DQBUF, &v4l2buf) < 0) { Dmai_err1("VIDIOC_DQBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } *hBufPtr = hDisplay->bufDescs[v4l2buf.index].hBuf; hDisplay->bufDescs[v4l2buf.index].used = TRUE; return Dmai_EOK; }
/****************************************************************************** * Framecopy_accel_create ******************************************************************************/ Framecopy_Handle Framecopy_accel_create(Framecopy_Attrs *attrs) { #ifdef CONFIG_VDCE Framecopy_Handle hFc; hFc = calloc(1, sizeof(Framecopy_Object)); if (hFc == NULL) { Dmai_err0("Failed to allocate space for Framecopy Object\n"); return NULL; } hFc->fd = open(VDCE_DEVICE_NAME, O_RDWR); if (hFc->fd == -1) { Dmai_err1("Unable to open VDCE device: %s\n", VDCE_DEVICE_NAME); free(hFc); return NULL; } return hFc; #else Dmai_err0("not implemented\n"); return NULL; #endif }
/****************************************************************************** * Buffer_copy ******************************************************************************/ Int Buffer_copy(Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { assert(hSrcBuf); assert(hDstBuf); assert(hSrcBuf->type == Buffer_Type_BASIC || hSrcBuf->type == Buffer_Type_GRAPHICS); if(hSrcBuf->type != hDstBuf->type) { Dmai_err1("Cannot copy to Buffer type (%d)\n", hDstBuf->type); return Dmai_EFAIL; } if (!hDstBuf->reference && hDstBuf->userPtr) { Dmai_dbg3("Free Buffer of size %u at 0x%x (0x%x phys)\n", (Uns) hDstBuf->origState.numBytes, (Uns) hDstBuf->userPtr, (Uns) hDstBuf->physPtr); if (!Memory_free(hDstBuf->userPtr, hDstBuf->origState.numBytes, &hDstBuf->memParams)) { return Dmai_EFAIL; } } if(hSrcBuf->type == Buffer_Type_GRAPHICS) { *(_BufferGfx_Object *) hDstBuf = *(_BufferGfx_Object *) hSrcBuf; } else { *(_Buffer_Object *) hDstBuf = *(_Buffer_Object *) hSrcBuf; } hDstBuf->reference = TRUE; return Dmai_EOK; }
/****************************************************************************** * Framecopy_resizer_accel_create ******************************************************************************/ Framecopy_Handle Framecopy_resizer_accel_create(Framecopy_Attrs *attrs) { #if defined(CONFIG_VIDEO_OMAP34XX_ISP_RESIZER) Framecopy_Handle hFc; Dmai_dbg0("Creating resizer accelerated framecopy\n"); hFc = (Framecopy_Handle)calloc(1, sizeof(Framecopy_Object)); if (hFc == NULL) { Dmai_err0("Failed to allocate space for Framecopy Object\n"); return NULL; } /* Open resizer device */ hFc->fd = open(RESIZER_DEVICE, O_RDWR); if (hFc->fd == -1) { Dmai_err1("Failed to open %s\n", RESIZER_DEVICE); return NULL; } return hFc; #else Dmai_err0("not implemented\n"); return NULL; #endif /* end CONFIG_VIDEO_OMAP34XX_ISP_RESIZER */ }
/****************************************************************************** * Capture_put ******************************************************************************/ Int Capture_put(Capture_Handle hCapture, Buffer_Handle hBuf) { Int idx; assert(hCapture); assert(hBuf); idx = getUsedIdx(hCapture->bufDescs, BufTab_getNumBufs(hCapture->hBufTab)); if (idx < 0) { Dmai_err0("You must get a captured buffer before putting one\n"); return Dmai_ENOMEM; } hCapture->bufDescs[idx].v4l2buf.m.userptr = (Int) Buffer_getUserPtr(hBuf); hCapture->bufDescs[idx].v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* Issue captured frame buffer back to device driver */ if (ioctl(hCapture->fd, VIDIOC_QBUF, &hCapture->bufDescs[idx].v4l2buf) == -1) { Dmai_err1("VIDIOC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } hCapture->bufDescs[idx].hBuf = hBuf; hCapture->bufDescs[idx].used = FALSE; return Dmai_EOK; }
/****************************************************************************** * Ir_create ******************************************************************************/ Ir_Handle Ir_create(Ir_Attrs *attrs) { #ifdef CONFIG_CIR Ir_Handle hIr; hIr = calloc(1, sizeof(Ir_Object)); if (hIr == NULL) { Dmai_err0("Failed to allocate space for Ir Object\n"); return NULL; } hIr->fd = open (CIR_DEVICE, O_RDONLY | O_NONBLOCK, 0); if (hIr->fd < 0) { Dmai_err1("Unable to open the CIR device %s\n", CIR_DEVICE); free(hIr); return NULL; } return hIr; #else Dmai_err0("not implemented\n"); return NULL; #endif }
/****************************************************************************** * setDisplayBuffer ******************************************************************************/ static Int setDisplayBuffer(Display_Handle hDisplay, Int displayIdx) { struct fb_var_screeninfo varInfo; if (ioctl(hDisplay->fd, FBIOGET_VSCREENINFO, &varInfo) == -1) { Dmai_err1("Failed FBIOGET_VSCREENINFO (%s)\n", strerror(errno)); return Dmai_EFAIL; } varInfo.yoffset = varInfo.yres * displayIdx; if (ioctl(hDisplay->fd, FBIOPAN_DISPLAY, &varInfo) == -1) { Dmai_err1("Failed FBIOPAN_DISPLAY (%s)\n", strerror(errno)); return Dmai_EFAIL; } return Dmai_EOK; }
/****************************************************************************** * Previewer_continous_delete ******************************************************************************/ Int Previewer_continous_delete(Int fd) { if (fd) { if (close(fd) == -1) { Dmai_err1("Failed to close previewer device (%s)\n", strerror(errno)); return Dmai_EIO; } } return Dmai_EOK; }
/****************************************************************************** * cleanup ******************************************************************************/ static Int cleanup(Display_Handle hDisplay) { Int ret = Dmai_EOK; BufTab_Handle hBufTab = hDisplay->hBufTab; struct fb_var_screeninfo varInfo; struct fb_fix_screeninfo fixInfo; if (hDisplay->fd != -1) { if (ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo) == -1) { Dmai_err1("Failed FBIOGET_FSCREENINFO (%s)\n", strerror(errno)); ret = Dmai_EFAIL; } if (ioctl(hDisplay->fd, FBIOGET_VSCREENINFO, &varInfo) == -1) { Dmai_err1("Failed ioctl FBIOGET_VSCREENINFO (%s)\n", strerror(errno)); ret = Dmai_EFAIL; } if (ioctl(hDisplay->fd, FBIOPUT_VSCREENINFO, &hDisplay->origVarInfo) == -1) { Dmai_err1("Failed FBIOGET_FSCREENINFO (%s)\n", strerror(errno)); ret = Dmai_EFAIL; } if (hBufTab) { munmap(Buffer_getUserPtr(BufTab_getBuf(hBufTab, 0)), fixInfo.line_length * varInfo.yres_virtual); free(hBufTab); } setDisplayBuffer(hDisplay, 0); close(hDisplay->fd); } free(hDisplay); return ret; }
/****************************************************************************** * Initialize & configure resizer B in on-the-fly (continous) mode ******************************************************************************/ int Resizer_B_config(int rsz_fd, unsigned int width, unsigned int height) { unsigned int user_mode; struct rsz_channel_config rsz_chan_config; struct rsz_continuous_config rsz_cont_config; user_mode = IMP_MODE_CONTINUOUS; if(rsz_fd <= 0) { Dmai_err0("Cannot use resize device \n"); return NULL; } bzero(&rsz_cont_config, sizeof(struct rsz_continuous_config)); rsz_chan_config.oper_mode = user_mode; rsz_chan_config.chain = 1; rsz_chan_config.len = sizeof(struct rsz_continuous_config); rsz_chan_config.config = &rsz_cont_config; if (ioctl(rsz_fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { Dmai_err1("Error in getting channel configuration from resizer (%s)\n", strerror(errno)); return Dmai_EFAIL; } /* we can ignore the input spec since we are chaining. So only set output specs */ rsz_cont_config.output2.width = width; rsz_cont_config.output2.height= height; rsz_cont_config.output2.pix_fmt = IPIPE_YUV420SP; rsz_cont_config.output2.enable = 1; rsz_chan_config.len = sizeof(struct rsz_continuous_config); rsz_chan_config.config = &rsz_cont_config; if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err1("Error in setting resizer configuration (%s)\n", strerror(errno)); return Dmai_EFAIL; } Dmai_dbg0("Resizer B initialized\n"); return Dmai_EOK; }
/****************************************************************************** * Buffer_create ******************************************************************************/ Buffer_Handle Buffer_create(Int32 size, Buffer_Attrs *attrs) { Buffer_Handle hBuf; UInt32 objSize; if (attrs == NULL) { Dmai_err0("Must provide attrs\n"); return NULL; } if (attrs->type != Buffer_Type_BASIC && attrs->type != Buffer_Type_GRAPHICS) { Dmai_err1("Unknown Buffer type (%d)\n", attrs->type); return NULL; } objSize = attrs->type == Buffer_Type_GRAPHICS ? sizeof(_BufferGfx_Object) : sizeof(_Buffer_Object); hBuf = (Buffer_Handle) calloc(1, objSize); if (hBuf == NULL) { Dmai_err0("Failed to allocate space for Buffer Object\n"); return NULL; } _Buffer_init(hBuf, size, attrs); if (!attrs->reference) { hBuf->userPtr = (Int8*)Memory_alloc(size, &attrs->memParams); if (hBuf->userPtr == NULL) { printf("Failed to allocate memory.\n"); free(hBuf); return NULL; } hBuf->physPtr = Memory_getBufferPhysicalAddress(hBuf->userPtr, size, NULL); Dmai_dbg3("Alloc Buffer of size %u at 0x%x (0x%x phys)\n", (Uns) size, (Uns) hBuf->userPtr, (Uns) hBuf->physPtr); } hBuf->reference = attrs->reference; return hBuf; }
/****************************************************************************** * Display_fbdev_get ******************************************************************************/ Int Display_fbdev_get(Display_Handle hDisplay, Buffer_Handle *hBufPtr) { Int dummy; BufTab_Handle hBufTab = hDisplay->hBufTab; assert(hDisplay); assert(hBufPtr); /* Wait for vertical sync */ if (ioctl(hDisplay->fd, FBIO_WAITFORVSYNC, &dummy) == -1) { Dmai_err1("Failed FBIO_WAITFORVSYNC (%s)\n", strerror(errno)); return Dmai_EFAIL; } dummy = 1; *hBufPtr = BufTab_getBuf(hBufTab, hDisplay->workingIdx); return Dmai_EOK; }
/****************************************************************************** * setMixerInput *****************************************************************************/ static Int setMixerControl (const Char *name, Int value) { Int status; snd_hctl_t *hctl; snd_ctl_elem_id_t *id; snd_hctl_elem_t *elem; snd_ctl_elem_value_t *control; if ((status = snd_hctl_open(&hctl, AUDIO_MIXER, 0)) < 0) { Dmai_err2("setMixerControl %s open error: %s\n", AUDIO_MIXER, snd_strerror(status)); return Dmai_EFAIL;; } if ((status = snd_hctl_load(hctl)) < 0) { Dmai_err2("setMixerControl %s load error: %s\n", AUDIO_MIXER, snd_strerror(status)); return Dmai_EFAIL;; } snd_ctl_elem_id_alloca(&id); snd_ctl_elem_id_set_interface(id, SND_CTL_ELEM_IFACE_MIXER); snd_ctl_elem_id_set_name(id, name); elem = snd_hctl_find_elem(hctl, id); if (!elem) { Dmai_err1("setMixerControl %s find element error\n", AUDIO_MIXER); snd_hctl_close(hctl); return Dmai_EFAIL; } snd_ctl_elem_value_alloca(&control); snd_ctl_elem_value_set_id(control, id); snd_ctl_elem_value_set_integer(control, 0, value); snd_hctl_elem_write(elem, control); snd_hctl_close(hctl); return Dmai_EOK; }
/****************************************************************************** * Capture_put ******************************************************************************/ Int Capture_put(Capture_Handle hCapture, Buffer_Handle hBuf) { Int idx; assert(hCapture); assert(hBuf); /* * The used Flag as part of bufdesc is with respect to the use of buffer * by the application. If Used = TRUE then the index is available for * storing new buffer information. This is set to FALSE once it contains * valid information about the buffer. */ idx = getUsedIdx(hCapture->bufDescs, BufTab_getNumBufs(hCapture->hBufTab)); if (idx < 0) { Dmai_err0("You must get a captured buffer before putting one\n"); return Dmai_ENOMEM; } hCapture->bufDescs[idx].v4l2buf.m.userptr = (Int) Buffer_getUserPtr(hBuf); hCapture->bufDescs[idx].v4l2buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; /* Issue captured frame buffer back to device driver */ if (ioctl(hCapture->fd, VIDIOC_QBUF, &hCapture->bufDescs[idx].v4l2buf) == -1) { Dmai_err1("VIDIOC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } hCapture->bufDescs[idx].hBuf = hBuf; hCapture->bufDescs[idx].used = FALSE; return Dmai_EOK; }
/****************************************************************************** * Capture_create ******************************************************************************/ Capture_Handle Capture_create(BufTab_Handle hBufTab, Capture_Attrs *attrs) { struct v4l2_capability cap; struct v4l2_crop crop; struct v4l2_format fmt; enum v4l2_buf_type type; Capture_Handle hCapture; VideoStd_Type videoStd; Int32 width, height; assert(attrs); Dmai_clear(fmt); /* Allocate space for state object */ hCapture = calloc(1, sizeof(Capture_Object)); if (hCapture == NULL) { Dmai_err0("Failed to allocate space for Capture Object\n"); return NULL; } /* User allocated buffers by default */ hCapture->userAlloc = TRUE; /* Open video capture device */ hCapture->fd = open(attrs->captureDevice, O_RDWR, 0); if (hCapture->fd == -1) { Dmai_err2("Cannot open %s (%s)\n", attrs->captureDevice, strerror(errno)); cleanup(hCapture); return NULL; } /* See if an input is connected, and if so which standard */ if (Capture_detectVideoStd(hCapture, &videoStd, attrs) < 0) { cleanup(hCapture); return NULL; } hCapture->videoStd = videoStd; if (VideoStd_getResolution(videoStd, &width, &height) < 0) { cleanup(hCapture); Dmai_err0("Failed to get resolution of capture video standard\n"); return NULL; } /* Query for capture device capabilities */ if (ioctl(hCapture->fd, VIDIOC_QUERYCAP, &cap) == -1) { cleanup(hCapture); if (errno == EINVAL) { Dmai_err1("%s is no V4L2 device\n", attrs->captureDevice); cleanup(hCapture); return NULL; } Dmai_err2("Failed VIDIOC_QUERYCAP on %s (%s)\n", attrs->captureDevice, strerror(errno)); cleanup(hCapture); return NULL; } if (!(cap.capabilities & V4L2_CAP_VIDEO_CAPTURE)) { Dmai_err1("%s is not a video capture device\n", attrs->captureDevice); cleanup(hCapture); return NULL; } if (!(cap.capabilities & V4L2_CAP_STREAMING)) { Dmai_err1("%s does not support streaming i/o\n", attrs->captureDevice); cleanup(hCapture); return NULL; } fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(hCapture->fd, VIDIOC_G_FMT, &fmt) == -1) { Dmai_err2("Failed VIDIOC_G_FMT on %s (%s)\n", attrs->captureDevice, strerror(errno)); cleanup(hCapture); return NULL; } fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; fmt.fmt.pix.bytesperline = width * 2; fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; if (ioctl(hCapture->fd, VIDIOC_S_FMT, &fmt) == -1) { Dmai_err2("Failed VIDIOC_S_FMT on %s (%s)\n", attrs->captureDevice, strerror(errno)); cleanup(hCapture); return NULL; } Dmai_dbg3("Video input connected size %dx%d pitch %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline); if (attrs->cropWidth > 0 && attrs->cropHeight > 0) { if (attrs->cropX & 0x1) { Dmai_err1("Crop width (%ld) needs to be even\n", attrs->cropX); cleanup(hCapture); return NULL; } crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; crop.c.left = attrs->cropX; crop.c.top = attrs->cropY; crop.c.width = attrs->cropWidth; crop.c.height = hCapture->topOffset ? attrs->cropHeight + 4 + 2 : attrs->cropHeight; Dmai_dbg4("Setting capture cropping at %dx%d size %dx%d\n", crop.c.left, crop.c.top, crop.c.width, crop.c.height); /* Crop the image depending on requested image size */ if (ioctl(hCapture->fd, VIDIOC_S_CROP, &crop) == -1) { Dmai_err2("VIDIOC_S_CROP failed on %s (%s)\n", attrs->captureDevice, strerror(errno)); cleanup(hCapture); return NULL; } } if (hBufTab == NULL) { hCapture->userAlloc = FALSE; /* The driver allocates the buffers */ if (_Dmai_v4l2DriverAlloc(hCapture->fd, attrs->numBufs, V4L2_BUF_TYPE_VIDEO_CAPTURE, &hCapture->bufDescs, &hBufTab, hCapture->topOffset, attrs->colorSpace) < 0) { Dmai_err1("Failed to allocate capture driver buffers on %s\n", attrs->captureDevice); cleanup(hCapture); return NULL; } } else { /* Make the driver use the user supplied buffers */ if (_Dmai_v4l2UserAlloc(hCapture->fd, attrs->numBufs, V4L2_BUF_TYPE_VIDEO_CAPTURE, &hCapture->bufDescs, hBufTab, 0, attrs->colorSpace, TRUE) < 0) { Dmai_err1("Failed to intialize capture driver buffers on %s\n", attrs->captureDevice); cleanup(hCapture); return NULL; } } hCapture->hBufTab = hBufTab; /* Start the video streaming */ type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (ioctl(hCapture->fd, VIDIOC_STREAMON, &type) == -1) { Dmai_err2("VIDIOC_STREAMON failed on %s (%s)\n", attrs->captureDevice, strerror(errno)); cleanup(hCapture); return NULL; } hCapture->started = TRUE; return hCapture; }
/****************************************************************************** * _Dmai_v4l2DriverAlloc ******************************************************************************/ Int _Dmai_v4l2DriverAlloc(Int fd, Int numBufs, enum v4l2_buf_type type, struct _VideoBufDesc **bufDescsPtr, BufTab_Handle *hBufTabPtr, Int topOffset, ColorSpace_Type colorSpace) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; struct v4l2_requestbuffers req; struct v4l2_format fmt; _VideoBufDesc *bufDesc; Buffer_Handle hBuf; Int bufIdx; Int8 *virtPtr; Dmai_clear(fmt); fmt.type = type; if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) { Dmai_err1("VIDIOC_G_FMT failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } Dmai_clear(req); req.count = numBufs; req.type = type; req.memory = V4L2_MEMORY_MMAP; /* Allocate buffers in the capture device driver */ if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { Dmai_err1("VIDIOC_REQBUFS failed (%s)\n", strerror(errno)); return Dmai_ENOMEM; } if (req.count < numBufs || !req.count) { Dmai_err0("Insufficient device driver buffer memory\n"); return Dmai_ENOMEM; } /* Allocate space for buffer descriptors */ *bufDescsPtr = calloc(numBufs, sizeof(_VideoBufDesc)); if (*bufDescsPtr == NULL) { Dmai_err0("Failed to allocate space for buffer descriptors\n"); return Dmai_ENOMEM; } gfxAttrs.dim.width = fmt.fmt.pix.width; gfxAttrs.dim.height = fmt.fmt.pix.height; gfxAttrs.dim.lineLength = fmt.fmt.pix.bytesperline; gfxAttrs.colorSpace = colorSpace; gfxAttrs.bAttrs.reference = TRUE; *hBufTabPtr = BufTab_create(numBufs, fmt.fmt.pix.sizeimage, BufferGfx_getBufferAttrs(&gfxAttrs)); if (*hBufTabPtr == NULL) { return Dmai_ENOMEM; } for (bufIdx = 0; bufIdx < numBufs; bufIdx++) { bufDesc = &(*bufDescsPtr)[bufIdx]; /* Ask for information about the driver buffer */ Dmai_clear(bufDesc->v4l2buf); bufDesc->v4l2buf.type = type; bufDesc->v4l2buf.memory = V4L2_MEMORY_MMAP; bufDesc->v4l2buf.index = bufIdx; if (ioctl(fd, VIDIOC_QUERYBUF, &bufDesc->v4l2buf) == -1) { Dmai_err1("Failed VIDIOC_QUERYBUF (%s)\n", strerror(errno)); return Dmai_EFAIL; } /* Map the driver buffer to user space */ virtPtr = mmap(NULL, bufDesc->v4l2buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, bufDesc->v4l2buf.m.offset) + topOffset; if (virtPtr == MAP_FAILED) { Dmai_err1("Failed to mmap buffer (%s)\n", strerror(errno)); return Dmai_EFAIL; } /* Initialize the Buffer with driver buffer information */ hBuf = BufTab_getBuf(*hBufTabPtr, bufIdx); Buffer_setNumBytesUsed(hBuf, fmt.fmt.pix.bytesperline * fmt.fmt.pix.height); Buffer_setUseMask(hBuf, gfxAttrs.bAttrs.useMask); Buffer_setUserPtr(hBuf, virtPtr); /* Initialize buffer to black */ _Dmai_blackFill(hBuf); Dmai_dbg3("Driver buffer %d mapped to %#x has physical address " "%#lx\n", bufIdx, (Int) virtPtr, Buffer_getPhysicalPtr(hBuf)); bufDesc->hBuf = hBuf; /* Queue buffer in device driver */ if (ioctl(fd, VIDIOC_QBUF, &bufDesc->v4l2buf) == -1) { Dmai_err1("VIODIOC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } } return Dmai_EOK; }
/****************************************************************************** * _Dmai_v4l2UserAlloc ******************************************************************************/ Int _Dmai_v4l2UserAlloc(Int fd, Int numBufs, enum v4l2_buf_type type, struct _VideoBufDesc **bufDescsPtr, BufTab_Handle hBufTab, Int topOffset, ColorSpace_Type colorSpace, Int queueBuffers) { struct v4l2_requestbuffers req; struct v4l2_format fmt; _VideoBufDesc *bufDesc; Buffer_Handle hBuf; Int bufIdx; Dmai_clear(fmt); fmt.type = type; if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) { Dmai_err1("VIDIOC_G_FMT failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } if (Buffer_getSize(BufTab_getBuf(hBufTab, 0)) < fmt.fmt.pix.width * fmt.fmt.pix.height * 2) { Dmai_err0("Supplied buffers not large enough for video standard\n"); return Dmai_EINVAL; } /* Set the actual size of the buffers allocated */ fmt.type = type; fmt.fmt.pix.sizeimage = Buffer_getSize(BufTab_getBuf(hBufTab, 0)); fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; fmt.fmt.pix.bytesperline = fmt.fmt.pix.width; if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) { Dmai_err1("VIDIOC_S_FMT failed (%s)\n", strerror(errno)); return Dmai_EIO; } /* * Tell the driver that we will use user allocated buffers, but don't * allocate any buffers in the driver (just the internal descriptors). */ Dmai_clear(req); req.type = type; req.count = numBufs; req.memory = V4L2_MEMORY_USERPTR; if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { Dmai_err0("Could not allocate video display buffers\n"); return Dmai_ENOMEM; } /* The driver may return less buffers than requested */ if (req.count < numBufs || !req.count) { Dmai_err0("Insufficient device driver buffer memory\n"); return Dmai_ENOMEM; } /* Allocate space for buffer descriptors */ *bufDescsPtr = calloc(numBufs, sizeof(_VideoBufDesc)); if (*bufDescsPtr == NULL) { Dmai_err0("Failed to allocate space for buffer descriptors\n"); return Dmai_ENOMEM; } for (bufIdx = 0; bufIdx < numBufs; bufIdx++) { bufDesc = &(*bufDescsPtr)[bufIdx]; hBuf = BufTab_getBuf(hBufTab, bufIdx); if (hBuf == NULL) { Dmai_err0("Failed to get buffer from BufTab for display\n"); return Dmai_ENOMEM; } if (Buffer_getType(hBuf) != Buffer_Type_GRAPHICS) { Dmai_err0("Buffer supplied to Display not a Graphics buffer\n"); return Dmai_EINVAL; } Dmai_clear(bufDesc->v4l2buf); bufDesc->v4l2buf.index = bufIdx; bufDesc->v4l2buf.type = type; bufDesc->v4l2buf.memory = V4L2_MEMORY_USERPTR; bufDesc->v4l2buf.m.userptr = (UInt32) Buffer_getUserPtr(hBuf); bufDesc->v4l2buf.length = (fmt.fmt.pix.sizeimage + 4096) & (~0xFFF); bufDesc->hBuf = hBuf; bufDesc->used = (queueBuffers == FALSE) ? TRUE : FALSE; /* If queueBuffers is TRUE, initialize the buffers to black and queue * them into the driver. */ if (queueBuffers == TRUE) { Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf)); _Dmai_blackFill(hBuf); /* Queue buffer in device driver */ if (ioctl(fd, VIDIOC_QBUF, &bufDesc->v4l2buf) == -1) { Dmai_err1("VIODIC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } } } return Dmai_EOK; }
/****************************************************************************** * _Dmai_blackFill * Note: This function uses x, y parameters to calculate the offset for the * buffers. ******************************************************************************/ Void _Dmai_blackFill(Buffer_Handle hBuf) { switch (BufferGfx_getColorSpace(hBuf)) { case ColorSpace_YUV422PSEMI: { Int8 *yPtr = Buffer_getUserPtr(hBuf); Int32 ySize = Buffer_getSize(hBuf) / 2; Int8 *cbcrPtr = yPtr + ySize; Int bpp = ColorSpace_getBpp(ColorSpace_YUV422PSEMI); Int y; BufferGfx_Dimensions dim; UInt32 offset; BufferGfx_getDimensions(hBuf, &dim); offset = dim.y * dim.lineLength + dim.x * bpp / 8; for (y = 0; y < dim.height; y++) { memset(yPtr + offset, 0x0, dim.width * bpp / 8); yPtr += dim.lineLength; } for (y = 0; y < dim.height; y++) { memset(cbcrPtr + offset, 0x80, dim.width * bpp / 8); cbcrPtr += dim.lineLength; } break; } case ColorSpace_YUV420PSEMI: { Int8 *yPtr = Buffer_getUserPtr(hBuf); Int32 ySize = Buffer_getSize(hBuf) * 2 / 3; Int8 *cbcrPtr = yPtr + ySize; Int bpp = ColorSpace_getBpp(ColorSpace_YUV420PSEMI); Int y; BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); yPtr += dim.y * dim.lineLength + dim.x * bpp / 8; for (y = 0; y < dim.height; y++) { memset(yPtr, 0x0, dim.width * bpp / 8); yPtr += dim.lineLength; } cbcrPtr += dim.y * dim.lineLength / 2 + dim.x * bpp / 8; for (y = 0; y < dim.height / 2; y++) { memset(cbcrPtr, 0x80, dim.width * bpp / 8); cbcrPtr += dim.lineLength; } break; } case ColorSpace_UYVY: { Int32 *bufPtr = (Int32*)Buffer_getUserPtr(hBuf); Int bpp = ColorSpace_getBpp(ColorSpace_UYVY); Int i, j; BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); bufPtr += (dim.y * dim.lineLength + dim.x * bpp / 8) / sizeof(Int32); /* Make sure display buffer is 4-byte aligned */ assert((((UInt32) bufPtr) & 0x3) == 0); for (i = 0; i < dim.height; i++) { for (j = 0; j < dim.width / 2; j++) { bufPtr[j] = UYVY_BLACK; } bufPtr += dim.lineLength / sizeof(Int32); } break; } case ColorSpace_RGB565: { memset(Buffer_getUserPtr(hBuf), 0, Buffer_getSize(hBuf)); break; } default: { Dmai_err1("Unsupported color space (%d) for _Dmai_blackFill\n", BufferGfx_getColorSpace(hBuf)); break; } } }
/****************************************************************************** * Display_v4l2_create ******************************************************************************/ Display_Handle Display_v4l2_create(BufTab_Handle hBufTab, Display_Attrs *attrs) { struct v4l2_format fmt; enum v4l2_buf_type type; Display_Handle hDisplay; Int32 width, height, bytesperline; assert(attrs); /* delayStreamon not supported for this platform */ if (attrs->delayStreamon == TRUE) { Dmai_err0("Support for delayed VIDIOC_STREAMON not implemented\n"); return NULL; } /* Allocate space for state object */ hDisplay = calloc(1, sizeof(Display_Object)); if (hDisplay == NULL) { Dmai_err0("Failed to allocate space for Display Object\n"); return NULL; } hDisplay->userAlloc = TRUE; /* Open video capture device */ hDisplay->fd = open(attrs->displayDevice, O_RDWR, 0); if (hDisplay->fd == -1) { Dmai_err2("Cannot open %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } /* Determine the video image dimensions */ fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(hDisplay->fd, VIDIOC_G_FMT, &fmt) == -1) { Dmai_err0("Failed to determine video display format\n"); cleanup(hDisplay); return NULL; } Dmai_dbg3("Found video output size %dx%d pitch %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline); /* If video standard is set to auto then use current height and width */ if (attrs->videoStd == VideoStd_AUTO) { width = fmt.fmt.pix.width; height = fmt.fmt.pix.height; bytesperline = fmt.fmt.pix.bytesperline; } else if (attrs->videoStd == -1) { width = attrs->width; height = attrs->height; bytesperline = width; } else { VideoStd_getResolution(attrs->videoStd, &width, &height); bytesperline = width; } fmt.fmt.pix.width = width; fmt.fmt.pix.height = height; fmt.fmt.pix.bytesperline = bytesperline; fmt.fmt.pix.sizeimage = bytesperline * height * 2; /* If colorspace is passed then use this colorspace */ switch (attrs->colorSpace) { case ColorSpace_YUV422PSEMI: fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_NV16; break; default: Dmai_err0("Output colorspace is not supported\n"); cleanup(hDisplay); return NULL; break; } Dmai_dbg3("Setting video output size %dx%d pitch %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline); if (ioctl(hDisplay->fd, VIDIOC_S_FMT, &fmt) == -1) { Dmai_err0("Failed to set video display format\n"); cleanup(hDisplay); return NULL; } Dmai_dbg3("Current video output size %dx%d pitch %d\n", fmt.fmt.pix.width, fmt.fmt.pix.height, fmt.fmt.pix.bytesperline); /* Should the device driver allocate the display buffers? */ if (hBufTab == NULL) { hDisplay->userAlloc = FALSE; if (_Dmai_v4l2DriverAlloc(hDisplay->fd, attrs->numBufs, V4L2_BUF_TYPE_VIDEO_OUTPUT, &hDisplay->bufDescs, &hBufTab, 0, attrs->colorSpace) < 0) { Dmai_err1("Failed to allocate display driver buffers on %s\n", attrs->displayDevice); cleanup(hDisplay); return NULL; } } else { Dmai_err0("User supplied buffers not supported\n"); cleanup(hDisplay); return NULL; } /* Start the video streaming */ type = V4L2_BUF_TYPE_VIDEO_OUTPUT; if (ioctl(hDisplay->fd, VIDIOC_STREAMON, &type) == -1) { Dmai_err2("VIDIOC_STREAMON failed on %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } hDisplay->started = TRUE; hDisplay->hBufTab = hBufTab; hDisplay->displayStd = Display_Std_V4L2; return hDisplay; }
/****************************************************************************** * Initialize & configure previewer in on-the-fly (continous) mode ******************************************************************************/ Int Previewer_continuous_config(Bool setRgbColorPallet) { #ifdef CONFIG_DM365_IPIPE Int preview_fd; unsigned int oper_mode, user_mode; struct prev_channel_config prev_chan_config; struct prev_continuous_config prev_cont_config; struct prev_cap cap; struct prev_module_param mod_param; user_mode = IMP_MODE_CONTINUOUS; preview_fd = open((const char *)PREVIEWER_DEVICE, O_RDWR); if(preview_fd <= 0) { Dmai_err0("Cannot open previewer device \n"); return NULL; } if (ioctl(preview_fd,PREV_S_OPER_MODE, &user_mode) < 0) { Dmai_err1("Can't set operation mode in previewer (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } if (ioctl(preview_fd,PREV_G_OPER_MODE, &oper_mode) < 0) { Dmai_err1("Can't get operation mode from previewer (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } if (oper_mode == user_mode) { Dmai_dbg0("Operating mode changed successfully to continuous in previewer\n"); } else { Dmai_err0("failed to set mode to continuous in previewer\n"); close(preview_fd); return Dmai_EFAIL; } prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = 0; prev_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) { Dmai_err1("Error in setting default previewer configuration (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } if (setRgbColorPallet) { Dmai_dbg0("Setting RGB color pallet\n"); prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = sizeof(struct prev_continuous_config); prev_chan_config.config = &prev_cont_config; /* to set defaults in driver */ if (ioctl(preview_fd, PREV_G_CONFIG, &prev_chan_config) < 0) { Dmai_err1("Error in setting default previewer configuration (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = sizeof(struct prev_continuous_config); prev_chan_config.config = &prev_cont_config; /* to set defaults in driver */ prev_cont_config.input.colp_elep= IPIPE_BLUE; prev_cont_config.input.colp_elop= IPIPE_GREEN_BLUE; prev_cont_config.input.colp_olep= IPIPE_GREEN_RED; prev_cont_config.input.colp_olop= IPIPE_RED; if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) { Dmai_err1("Error in setting default previewer configuration (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } cap.index=0; while (1) { if (ioctl(preview_fd , PREV_ENUM_CAP, &cap) < 0) { break; } strcpy(mod_param.version,cap.version); mod_param.module_id = cap.module_id; // using defaults Dmai_dbg1("Setting default for %s\n", cap.module_name); mod_param.param = NULL; if (ioctl(preview_fd, PREV_S_PARAM, &mod_param) < 0) { Dmai_err1("Error in Setting %s params from driver\n", cap.module_name); close(preview_fd); return Dmai_EFAIL; } cap.index++; } } Dmai_dbg0("Previewer initialized\n"); return preview_fd; #else Dmai_err0("not implemented\n"); return Dmai_ENOTIMPL; #endif }
/****************************************************************************** * Initialize & configure previewer in on-the-fly (continous) mode ******************************************************************************/ Int Previewer_continous_config(void) { Int preview_fd; unsigned int oper_mode, user_mode; struct prev_channel_config prev_chan_config; struct prev_continuous_config prev_cont_config; user_mode = IMP_MODE_CONTINUOUS; preview_fd = open((const char *)PREVIEWER_DEVICE, O_RDWR); if(preview_fd <= 0) { Dmai_err0("Cannot open previewer device \n"); return NULL; } if (ioctl(preview_fd,PREV_S_OPER_MODE, &user_mode) < 0) { Dmai_err1("Can't set operation mode in previewer (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } if (ioctl(preview_fd,PREV_G_OPER_MODE, &oper_mode) < 0) { Dmai_err1("Can't get operation mode from previewer (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } if (oper_mode == user_mode) { Dmai_dbg0("Operating mode changed successfully to continuous in previewer\n"); } else { Dmai_err0("failed to set mode to continuous in previewer\n"); close(preview_fd); return Dmai_EFAIL; } prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = 0; prev_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) { Dmai_err1("Error in setting default previewer configuration (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = sizeof(struct prev_continuous_config); prev_chan_config.config = &prev_cont_config; if (ioctl(preview_fd, PREV_G_CONFIG, &prev_chan_config) < 0) { Dmai_err1("Error in getting configuration from previewer (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } prev_chan_config.oper_mode = oper_mode; prev_chan_config.len = sizeof(struct prev_continuous_config); prev_chan_config.config = &prev_cont_config; if (ioctl(preview_fd, PREV_S_CONFIG, &prev_chan_config) < 0) { Dmai_err1("Error in setting previewer configuration (%s)\n", strerror(errno)); close(preview_fd); return Dmai_EFAIL; } Dmai_dbg0("Previewer initialized\n"); return preview_fd; }
/****************************************************************************** * Initialize & configure resizer in on-the-fly (continous) mode ******************************************************************************/ Int Resizer_continous_config(void) { Int rsz_fd; unsigned int oper_mode, user_mode; struct rsz_channel_config rsz_chan_config; struct rsz_continuous_config rsz_cont_config; user_mode = IMP_MODE_CONTINUOUS; rsz_fd = open((const char *)RESIZER_DEVICE, O_RDWR); if(rsz_fd <= 0) { Dmai_err0("Cannot open resize device \n"); return NULL; } if (ioctl(rsz_fd, RSZ_S_OPER_MODE, &user_mode) < 0) { Dmai_err1("Can't set operation mode (%s)\n", strerror(errno)); close(rsz_fd); return Dmai_EFAIL; } if (ioctl(rsz_fd, RSZ_G_OPER_MODE, &oper_mode) < 0) { Dmai_err1("Can't get operation mode (%s)\n", strerror(errno)); close(rsz_fd); return Dmai_EFAIL; } if (oper_mode == user_mode) { Dmai_dbg0("Successfully set mode to continuous in resizer\n"); } else { Dmai_err0("Failed to set mode to continuous in resizer\n"); close(rsz_fd); return Dmai_EFAIL; } /* set configuration to chain resizer with preview */ rsz_chan_config.oper_mode = user_mode; rsz_chan_config.chain = 1; rsz_chan_config.len = 0; rsz_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err1("Error in setting default configuration in resizer (%s)\n", strerror(errno)); close(rsz_fd); return Dmai_EFAIL; } bzero(&rsz_cont_config, sizeof(struct rsz_continuous_config)); rsz_chan_config.oper_mode = user_mode; rsz_chan_config.chain = 1; rsz_chan_config.len = sizeof(struct rsz_continuous_config); rsz_chan_config.config = &rsz_cont_config; if (ioctl(rsz_fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { Dmai_err1("Error in getting channel configuration from resizer (%s)\n", strerror(errno)); close(rsz_fd); return Dmai_EFAIL; } /* we can ignore the input spec since we are chaining. So only set output specs */ rsz_cont_config.output1.enable = 1; rsz_cont_config.output2.enable = 0; rsz_chan_config.len = sizeof(struct rsz_continuous_config); rsz_chan_config.config = &rsz_cont_config; if (ioctl(rsz_fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err1("Error in setting resizer configuration (%s)\n", strerror(errno)); close(rsz_fd); return Dmai_EFAIL; } Dmai_dbg0("Resizer A initialized\n"); return rsz_fd; }
/****************************************************************************** * Idec1_process ******************************************************************************/ Int Idec1_process(Idec1_Handle hId, Buffer_Handle hInBuf, Buffer_Handle hOutBuf) { BufferGfx_Dimensions dim; IMGDEC1_DynamicParams dynParams; IMGDEC1_InArgs inArgs; IMGDEC1_OutArgs outArgs; IMGDEC1_Status decStatus; XDM1_BufDesc inBufDesc; XDM1_BufDesc outBufDesc; XDAS_Int32 status; XDAS_Int8 * inPtr; XDAS_Int8 * outPtr; UInt32 offset = 0; UInt32 i; assert(hId); assert(hInBuf); assert(hOutBuf); assert(Buffer_getSize(hInBuf)); assert(Buffer_getUserPtr(hInBuf)); assert(Buffer_getUserPtr(hOutBuf)); assert(Buffer_getNumBytesUsed(hInBuf)); assert(Buffer_getSize(hOutBuf)); assert(Buffer_getType(hOutBuf) == Buffer_Type_GRAPHICS); BufferGfx_getDimensions(hOutBuf, &dim); inPtr = Buffer_getUserPtr(hInBuf); outPtr = Buffer_getUserPtr(hOutBuf); inArgs.size = sizeof(IMGDEC1_InArgs); inArgs.numBytes = Buffer_getNumBytesUsed(hInBuf); outArgs.size = sizeof(IMGDEC1_OutArgs); inBufDesc.numBufs = 1; outBufDesc.numBufs = hId->minNumOutBufs; inBufDesc.descs[0].buf = inPtr; inBufDesc.descs[0].bufSize = Buffer_getSize(hInBuf); for(i = 0; i < hId->minNumOutBufs; i++) { outBufDesc.descs[i].buf = (XDAS_Int8 *)((unsigned int)outPtr + offset); offset += hId->minOutBufSize[i]; outBufDesc.descs[i].bufSize = hId->minOutBufSize[i]; } /* Decode image buffer */ status = IMGDEC1_process(hId->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs); Buffer_setNumBytesUsed(hInBuf, outArgs.bytesConsumed); if (status != IMGDEC1_EOK) { if (XDM_ISFATALERROR(outArgs.extendedError)) { Dmai_err2("IMGDEC1_process() failed with error (%d ext: 0x%x)\n", (Int)status, (Uns) outArgs.extendedError); return Dmai_EFAIL; } else { Dmai_dbg1("IMGDEC1_process() non-fatal error 0x%x\n", (Uns) outArgs.extendedError); return Dmai_EBITERROR; } } /* Get the dynamic codec status */ decStatus.data.buf = NULL; decStatus.size = sizeof(IMGDEC1_Status); dynParams.size = sizeof(IMGDEC1_DynamicParams); status = IMGDEC1_control(hId->hDecode, XDM_GETSTATUS, &dynParams, &decStatus); if (status != IMGDEC1_EOK) { Dmai_err1("XDM_GETSTATUS failed, status=%d\n", status); return Dmai_EFAIL; } /* Set output Color Format */ switch (decStatus.outputChromaFormat) { case XDM_YUV_422ILE: BufferGfx_setColorSpace (hOutBuf, ColorSpace_UYVY); break; case XDM_YUV_420P: BufferGfx_setColorSpace (hOutBuf, ColorSpace_YUV420P); break; case XDM_YUV_422P: BufferGfx_setColorSpace (hOutBuf, ColorSpace_YUV422P); break; case XDM_YUV_444P: BufferGfx_setColorSpace (hOutBuf, ColorSpace_YUV444P); break; case XDM_GRAY: BufferGfx_setColorSpace (hOutBuf, ColorSpace_GRAY); break; default: printf("Unsupported output color space.\n"); return Dmai_EFAIL; } dim.x = dim.y = 0; dim.width = decStatus.outputWidth; dim.height = decStatus.outputHeight; dim.lineLength = decStatus.outputWidth * ColorSpace_getBpp(BufferGfx_getColorSpace(hOutBuf)) / 8; if (BufferGfx_setDimensions(hOutBuf, &dim) < 0) { Dmai_err0("Frame does not fit in allocated buffer\n"); return Dmai_EFAIL; } return Dmai_EOK; }
/****************************************************************************** * Capture_detectVideoStd ******************************************************************************/ Int Capture_detectVideoStd(Capture_Handle hCapture, VideoStd_Type *videoStdPtr, Capture_Attrs *attrs) { v4l2_std_id id; struct v4l2_input input; Int index; Int fd; struct v4l2_standard std; assert(videoStdPtr); assert(attrs); if (attrs->videoStd < 0 || attrs->videoStd > VideoStd_COUNT) { Dmai_err1("Invalid capture standard given (%d)\n", attrs->videoStd); return Dmai_EINVAL; } if (hCapture) { fd = hCapture->fd; } else { fd = open(attrs->captureDevice, O_RDWR, 0); if (fd == -1) { Dmai_err2("Cannot open %s (%s)\n", attrs->captureDevice, strerror(errno)); return Dmai_EFAIL; } } /* Get any active input */ if (ioctl(fd, VIDIOC_G_INPUT, &index) < 0) { Dmai_err0("VIDIOC_G_INPUT"); return Dmai_EFAIL; } /* Display available video input */ Dmai_dbg0("Available video input:\n"); for (index=0;; index++) { input.index = index; if (ioctl(fd, VIDIOC_ENUMINPUT, &input) < 0) { if (errno == EINVAL || errno == ENOTTY) break; } Dmai_dbg1(" name=%s\n", input.name); } /* Set video input */ switch (attrs->videoInput) { case Capture_Input_SVIDEO: Dmai_dbg0("Setting video input to SVIDEO\n"); index = 1; break; case Capture_Input_COMPOSITE: Dmai_dbg0("Setting video input to COMPOSITE\n"); index = 0; break; default: Dmai_err0("Unknown video input\n"); return Dmai_EFAIL; break; } if (ioctl(fd, VIDIOC_S_INPUT, &index) < 0) { Dmai_err2("Failed VIDIOC_S_INPUT to index %d (%s)\n", index, strerror(errno)); return Dmai_EFAIL; } /* Display available video standards */ Dmai_dbg0("Available video standard:\n"); for (index=0;; index++) { std.frameperiod.numerator = 1; std.frameperiod.denominator = 0; std.index = index; if (ioctl(fd, VIDIOC_ENUMSTD, &std) < 0) { if (errno == EINVAL || errno == ENOTTY) break; } Dmai_dbg3(" name=%s, fps=%d/%d\n", std.name, std.frameperiod.denominator, std.frameperiod.numerator); } /* Detect the standard in the input detected */ if (ioctl(fd, VIDIOC_QUERYSTD, &id) < 0) { Dmai_err0("VIDIOC_QUERYSTD"); return Dmai_EFAIL; } /* Get current video standard */ if (ioctl(fd, VIDIOC_G_STD, &id) < 0) { Dmai_err0("Failed VIDIOC_G_STD\n"); return Dmai_EFAIL; } if (!hCapture) { close(fd); } if (id & V4L2_STD_NTSC) { *videoStdPtr = VideoStd_D1_NTSC; Dmai_dbg0("Found NTSC std input\n"); } else if (id & V4L2_STD_PAL) { *videoStdPtr = VideoStd_D1_PAL; Dmai_dbg0("Found PAL std input\n"); } else if (id & V4L2_STD_525_60) { *videoStdPtr = VideoStd_480P; Dmai_dbg0("Found 525_60 std input\n"); } else if (id & V4L2_STD_625_50) { *videoStdPtr = VideoStd_576P; Dmai_dbg0("Found 625_50 std input\n"); } else { Dmai_err1("Unknown video standard on capture device %s\n", attrs->captureDevice); return Dmai_EFAIL; } attrs->videoStd = *videoStdPtr; Dmai_dbg2("Capture input set to %s. Standard: %d\n", captureInputString[attrs->videoInput], *videoStdPtr); return Dmai_EOK; }