/****************************************************************************** * Sound_alsa_read ******************************************************************************/ Int Sound_alsa_read(Sound_Handle hSound, Buffer_Handle hBuf) { Int32 numSamples, readSamples; Int8 *bufPtr; assert(hSound); assert(hBuf); readSamples = Buffer_getNumBytesUsed(hBuf) / (2 * hSound->channels); bufPtr = Buffer_getUserPtr(hBuf); while (readSamples > 0) { numSamples = snd_pcm_readi(hSound->rcIn, bufPtr, readSamples); if (numSamples == -EAGAIN) continue; if (numSamples < 0) { if (xrunRecovery(hSound->rcIn,numSamples) < 0) { Dmai_err2 ("Failed to read from %s (%s)\n", AUDIO_DEVICE, strerror(numSamples)); return Dmai_EFAIL; } } else { bufPtr += numSamples * 2 * hSound->channels; readSamples -= numSamples; } } Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf)); 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; }
/****************************************************************************** * Sound_alsa_write ******************************************************************************/ Int Sound_alsa_write(Sound_Handle hSound, Buffer_Handle hBuf) { Int32 numSamples, writeSamples; Int8 *bufPtr; assert(hSound); assert(hBuf); writeSamples = Buffer_getNumBytesUsed(hBuf) / (2 * hSound->channels); bufPtr = Buffer_getUserPtr(hBuf); while (writeSamples > 0) { /* start by doing a blocking wait for free space. */ snd_pcm_wait (hSound->rcOut, PCM_TIMEOUT); numSamples = snd_pcm_writei(hSound->rcOut, bufPtr, writeSamples); if (numSamples == -EAGAIN) continue; if (numSamples < 0) { if (xrunRecovery(hSound->rcOut,numSamples) < 0) { Dmai_err2 ("Failed to write to %s (%s)\n", AUDIO_DEVICE, strerror(-numSamples)); return Dmai_EFAIL; } } else { bufPtr += numSamples * 2 * hSound->channels; writeSamples -= numSamples; } } Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf)); return Dmai_EOK; }
/****************************************************************************** * 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; }
/****************************************************************************** * Framecopy_accel_execute ******************************************************************************/ Int Framecopy_accel_config(Framecopy_Handle hFc, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { vdce_params_t params; BufferGfx_Dimensions srcDim; BufferGfx_Dimensions dstDim; Int width, height; /* Buffer needs to be graphics buffers */ if (Buffer_getType(hSrcBuf) != Buffer_Type_GRAPHICS || Buffer_getType(hDstBuf) != Buffer_Type_GRAPHICS) { Dmai_err0("Src and dst buffers need to be graphics buffers\n"); return Dmai_EINVAL; } /* Sanity check buffer color space */ if (BufferGfx_getColorSpace(hSrcBuf) != BufferGfx_getColorSpace(hDstBuf)) { Dmai_err0("Src and dst buffers need to have same colorspace\n"); return Dmai_EINVAL; } BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); /* Source and destination width must be even */ if (dstDim.width % 2 || srcDim.width % 2) { Dmai_err2("Output (%d) and input width (%d) must be even\n", dstDim.width, srcDim.width); return Dmai_EINVAL; } /* Pitches must be a multiple of 8 */ if (dstDim.lineLength % 8 || srcDim.lineLength % 8) { Dmai_err2("Dst (%ld) and src (%ld) pitch must be a multiple of 8\n", dstDim.lineLength, srcDim.lineLength); return Dmai_EINVAL; } /* Select the smallest resolution */ width = srcDim.width < dstDim.width ? srcDim.width : dstDim.width; height = srcDim.height < dstDim.height ? srcDim.height : dstDim.height; Dmai_dbg2("Configuring resizer to copy image resolution %dx%d\n", width, height); params.vdce_mode = VDCE_OPERATION_RESIZING; if (ioctl(hFc->fd, VDCE_GET_DEFAULT, ¶ms) < 0) { Dmai_err0("default params failed error.\n"); return Dmai_EFAIL; } switch (BufferGfx_getColorSpace(hSrcBuf)) { case ColorSpace_YUV422PSEMI: params.vdce_mode_params.rsz_params.rsz_mode = VDCE_MODE_422; /* Speed up the conversion, note that this value hangs the resizer * for 420P color format */ params.common_params.prcs_unit_value = 256; break; case ColorSpace_YUV420PSEMI: params.vdce_mode_params.rsz_params.rsz_mode = VDCE_MODE_420; break; default: Dmai_err0("Colorspace format not supported\n"); return Dmai_ENOTIMPL; } params.common_params.src_hsz_luminance = width; params.common_params.src_vsz_luminance = height; params.common_params.dst_hsz_luminance = width; params.common_params.dst_vsz_luminance = height; params.common_params.src_processing_mode = VDCE_PROGRESSIVE; params.common_params.src_mode = VDCE_FRAME_MODE; params.common_params.res_mode = VDCE_FRAME_MODE; /* call ioctl to set parameters */ if (ioctl(hFc->fd, VDCE_SET_PARAMS, ¶ms) < 0) { Dmai_err0("VDCE_SET_PARAMS failed \n"); return Dmai_EFAIL; } return Dmai_EOK; }
/****************************************************************************** * Display_fbdev_create ******************************************************************************/ Display_Handle Display_fbdev_create(BufTab_Handle hBufTab, Display_Attrs *attrs) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; struct fb_var_screeninfo varInfo; struct fb_fix_screeninfo fixInfo; Int displaySize; Int bufIdx; Int8 *virtPtr; Int32 physPtr; Int32 height, width; Display_Handle hDisplay; Buffer_Handle hBuf; if (attrs == NULL) { Dmai_err0("Must supply valid attrs\n"); return NULL; } if (hBufTab != NULL) { Dmai_err0("FBdev display does not accept user allocated buffers\n"); return NULL; } hDisplay = calloc(1, sizeof(Display_Object)); if (hDisplay == NULL) { Dmai_err0("Failed to allocate space for Display Object\n"); return NULL; } /* Open video display device */ hDisplay->fd = open(attrs->displayDevice, O_RDWR); if (hDisplay->fd == -1) { Dmai_err2("Failed to open fb device %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } /* Get fixed screen info */ if (ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo) == -1) { Dmai_err2("Failed FBIOGET_FSCREENINFO on %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } /* Get virtual screen info */ if (ioctl(hDisplay->fd, FBIOGET_VSCREENINFO, &varInfo) == -1) { Dmai_err2("Failed FBIOGET_VSCREENINFO on %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } Dmai_dbg5("Found width=%d height=%d, yres_virtual=%d,xres_virtual=%d," " line_length=%d\n", varInfo.xres, varInfo.yres, varInfo.yres_virtual,varInfo.xres_virtual, fixInfo.line_length); /* Save current virtual screen info. */ memcpy(&hDisplay->origVarInfo, &varInfo, sizeof(struct fb_var_screeninfo)); /* If video standard is set to auto then use current height and width */ if (attrs->videoStd == VideoStd_AUTO) { width = varInfo.xres; height = varInfo.yres; } /* If video standard is not set then use the height/width passed from * attribute. */ else if (attrs->videoStd == -1) { width = attrs->width; height = attrs->height; } /* calulcate height/width from video standard */ else { VideoStd_getResolution(attrs->videoStd, &width, &height); } if (attrs->width > 0) { width = attrs->width; } if (attrs->height > 0) { height = attrs->height; } if (width > varInfo.xres) { width = varInfo.xres; } if (height > varInfo.yres) { height = varInfo.yres; } varInfo.xoffset = 0; varInfo.yoffset = 0; varInfo.xres = width; varInfo.yres = height; varInfo.xres_virtual = width; varInfo.yres_virtual = varInfo.yres * attrs->numBufs; /* Set video display format */ Dmai_dbg4("Setting width=%d height=%d, yres_virtual=%d," " xres_virtual=%d\n", varInfo.xres, varInfo.yres, varInfo.yres_virtual, varInfo.xres_virtual); if (ioctl(hDisplay->fd, FBIOPUT_VSCREENINFO, &varInfo) == -1) { Dmai_err2("Failed FBIOPUT_VSCREENINFO on %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } if (ioctl(hDisplay->fd, FBIOGET_FSCREENINFO, &fixInfo) == -1) { Dmai_err2("Failed FBIOGET_FSCREENINFO on %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } Dmai_dbg5("New width=%d, height=%d, yres_virtual=%d,xres_virtual=%d, " "line_length=%d\n", varInfo.xres, varInfo.yres, varInfo.yres_virtual, varInfo.xres_virtual, fixInfo.line_length); gfxAttrs.dim.width = varInfo.xres; gfxAttrs.colorSpace = attrs->colorSpace; gfxAttrs.dim.height = varInfo.yres; gfxAttrs.dim.lineLength = fixInfo.line_length; gfxAttrs.bAttrs.reference = TRUE; displaySize = fixInfo.line_length * varInfo.yres; hBufTab = BufTab_create(attrs->numBufs, displaySize, BufferGfx_getBufferAttrs(&gfxAttrs)); if (hBufTab == NULL) { Dmai_err0("Failed to allocate BufTab for display buffers\n"); cleanup(hDisplay); return NULL; } hBuf = BufTab_getBuf(hBufTab, 0); Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres * varInfo.bits_per_pixel / 8); virtPtr = (Int8 *) mmap (NULL, displaySize * attrs->numBufs, PROT_READ | PROT_WRITE, MAP_SHARED, hDisplay->fd, 0); if (virtPtr == MAP_FAILED) { Dmai_err2("Failed mmap on %s (%s)\n", attrs->displayDevice, strerror(errno)); cleanup(hDisplay); return NULL; } if (Buffer_setUserPtr(hBuf, virtPtr) < 0) { cleanup(hDisplay); return NULL; } _Dmai_blackFill(hBuf); Dmai_dbg3("Display buffer %d mapped to %#lx has physical address %#lx\n", 0, (Int32) virtPtr, physPtr); for (bufIdx=1; bufIdx < attrs->numBufs; bufIdx++) { hBuf = BufTab_getBuf(hBufTab, bufIdx); Buffer_setNumBytesUsed(hBuf, varInfo.xres * varInfo.yres * varInfo.bits_per_pixel / 8); virtPtr = virtPtr + displaySize; Buffer_setUserPtr(hBuf, virtPtr); _Dmai_blackFill(hBuf); Dmai_dbg3("Display buffer %d mapped to %#lx, physical address %#lx\n", bufIdx, (unsigned long) virtPtr, physPtr); } hDisplay->hBufTab = hBufTab; hDisplay->displayIdx = 0; hDisplay->workingIdx = attrs->numBufs > 1 ? 1 : 0; hDisplay->displayStd = Display_Std_FBDEV; if (setDisplayBuffer(hDisplay, hDisplay->displayIdx) < 0) { cleanup(hDisplay); return NULL; } return hDisplay; }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
/****************************************************************************** * Sdec_process ******************************************************************************/ Int Sdec_process(Sdec_Handle hSd, Buffer_Handle hInBuf, Buffer_Handle hOutBuf) { SPHDEC_DynamicParams dynamicParams; SPHDEC_Status decStatus; XDM_BufDesc inBufDesc; XDM_BufDesc outBufDesc; XDAS_Int32 inBufSizeArray[1]; XDAS_Int32 outBufSizeArray[1]; XDAS_Int32 status; SPHDEC_InArgs inArgs; SPHDEC_OutArgs outArgs; XDAS_Int8 *inPtr; XDAS_Int8 *outPtr; assert(hSd); assert(hInBuf); assert(hOutBuf); assert(Buffer_getUserPtr(hInBuf)); assert(Buffer_getUserPtr(hOutBuf)); assert(Buffer_getNumBytesUsed(hInBuf)); assert(Buffer_getSize(hOutBuf)); inPtr = Buffer_getUserPtr(hInBuf); outPtr = Buffer_getUserPtr(hOutBuf); inBufSizeArray[0] = Buffer_getNumBytesUsed(hInBuf); outBufSizeArray[0] = Buffer_getSize(hOutBuf); inBufDesc.bufSizes = inBufSizeArray; inBufDesc.bufs = &inPtr; inBufDesc.numBufs = 1; outBufDesc.bufSizes = outBufSizeArray; outBufDesc.bufs = &outPtr; outBufDesc.numBufs = 1; inArgs.size = sizeof(SPHDEC_InArgs); inArgs.inBufferSize = Buffer_getNumBytesUsed(hInBuf); outArgs.size = sizeof(SPHDEC_OutArgs); /* Decode the speech buffer */ status = SPHDEC_process(hSd->hDecode, &inBufDesc, &outBufDesc, &inArgs, &outArgs); if (status != SPHDEC_EOK) { decStatus.size = sizeof(SPHDEC_Status); dynamicParams.size = sizeof(SPHDEC_DynamicParams); status = SPHDEC_control(hSd->hDecode, XDM_GETSTATUS, &dynamicParams, &decStatus); if (status != SPHDEC_EOK) { Dmai_err1("XDM_GETSTATUS failed, status=%d\n", status); return Dmai_EFAIL; } if (status == SPHDEC_ERUNTIME || XDM_ISFATALERROR(decStatus.extendedError)) { Dmai_err2("SPHDEC_process() failed with error (%d ext: 0x%x)\n", (Int)status, (Uns) decStatus.extendedError); return Dmai_EFAIL; } else { Dmai_dbg1("SPHDEC_process() non-fatal error 0x%x\n", (Uns) decStatus.extendedError); return Dmai_EBITERROR; } } /* A fixed x2 decompression ratio, only works for g711 */ Buffer_setNumBytesUsed(hOutBuf, Buffer_getNumBytesUsed(hInBuf) * 2); return Dmai_EOK; }
/****************************************************************************** * Sound_alsa_create ******************************************************************************/ Sound_Handle Sound_alsa_create(Sound_Attrs *attrs) { Sound_Handle hSound; Int status; snd_output_t *log; assert(attrs); hSound = calloc(1, sizeof(Sound_Object)); if (hSound == NULL) { Dmai_err0("Failed to allocate space for Sound Object\n"); return NULL; } hSound->soundStd = attrs->soundStd; hSound->sampleRate = attrs->sampleRate; hSound->channels = attrs->channels; hSound->bufSize = attrs->bufSize; if (attrs->mode == Sound_Mode_INPUT || attrs->mode == Sound_Mode_FULLDUPLEX) { status = snd_pcm_open(&hSound->rcIn, AUDIO_DEVICE, SND_PCM_STREAM_CAPTURE, 0); if (status < 0) { Dmai_err2("Failed to open ALSA sound device for input %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); Sound_alsa_delete(hSound); return NULL; } /* Allocate a PCM SW and HW Param structure */ status = snd_pcm_hw_params_malloc(&hSound->hwParamsIn); if (status < 0) { Dmai_err2("Failed to alloc hardware param structure on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); Sound_alsa_delete(hSound); return NULL; } status = snd_pcm_sw_params_malloc(&hSound->swParamsIn); if (status < 0) { Dmai_err2("Failed to alloc software param structure on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); Sound_alsa_delete(hSound); return NULL; } if (initHwParams(hSound->rcIn,hSound->hwParamsIn,attrs,hSound) < 0) { Sound_alsa_delete(hSound); return NULL; } if (initSwParams(hSound->rcIn,hSound->swParamsIn,hSound,1) < 0) { Sound_alsa_delete(hSound); return NULL; } } if (attrs->mode == Sound_Mode_OUTPUT || attrs->mode == Sound_Mode_FULLDUPLEX) { status = snd_pcm_open(&hSound->rcOut, AUDIO_DEVICE, SND_PCM_STREAM_PLAYBACK, 0); if (status < 0) { Dmai_err2("Failed to open ALSA sound device for output %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); Sound_alsa_delete(hSound); return NULL; } /* Allocate a PCM SW and HW Param structure */ status = snd_pcm_hw_params_malloc(&hSound->hwParamsOut); if (status < 0) { Dmai_err2("Failed to alloc hardware param structure on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); Sound_alsa_delete(hSound); return NULL; } status = snd_pcm_sw_params_malloc(&hSound->swParamsOut); if (status < 0) { Dmai_err2("Failed to alloc hardware param structure on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); Sound_alsa_delete(hSound); return NULL; } if (initHwParams(hSound->rcOut,hSound->hwParamsOut,attrs,hSound) < 0) { Sound_alsa_delete(hSound); return NULL; } if (initSwParams(hSound->rcOut,hSound->swParamsOut,hSound,0) < 0) { Sound_alsa_delete(hSound); return NULL; } if (setMixerVolume (attrs) <0) { Sound_alsa_delete (hSound); return NULL; } } #if 0 if (attrs->mode != Sound_Mode_OUTPUT) { if (attrs->soundInput == Sound_Input_MIC) { if(setMixerControl(RIGHT_LINE_CTRL_ELEM, 0) != Dmai_EOK) { Dmai_err0("Failed to configure Right_PGA_Mixer_Line1R_Switch\n"); Sound_alsa_delete(hSound); return NULL; } if(setMixerControl(LEFT_LINE_CTRL_ELEM, 0) != Dmai_EOK) { Dmai_err0("Failed to configure Left_PGA_Mixer_Line1L_Switch\n"); Sound_alsa_delete(hSound); return NULL; } if(setMixerControl(RIGHT_MIC_CTRL_ELEM, 1) != Dmai_EOK) { Dmai_err0("Failed to configure Right_PGA_Mixer_Mic3R_Switch\n"); Sound_alsa_delete(hSound); return NULL; } if(setMixerControl(LEFT_MIC_CTRL_ELEM, 1) != Dmai_EOK) { Dmai_err0("Failed to configure Left_PGA_Mixer_Mic3L_Switch\n"); Sound_alsa_delete(hSound); return NULL; } } else if (attrs->soundInput == Sound_Input_LINE) { if(setMixerControl(RIGHT_LINE_CTRL_ELEM, 1) != Dmai_EOK) { Dmai_err0("Failed to configure Right_PGA_Mixer_Line1R_Switch\n"); Sound_alsa_delete(hSound); return NULL; } if(setMixerControl(LEFT_LINE_CTRL_ELEM, 1) != Dmai_EOK) { Dmai_err0("Failed to configure Left_PGA_Mixer_Line1L_Switch\n"); Sound_alsa_delete(hSound); return NULL; } if(setMixerControl(RIGHT_MIC_CTRL_ELEM, 0) != Dmai_EOK) { Dmai_err0("Failed to configure Right_PGA_Mixer_Mic3R_Switch\n"); Sound_alsa_delete(hSound); return NULL; } if(setMixerControl(LEFT_MIC_CTRL_ELEM, 0) != Dmai_EOK) { Dmai_err0("Failed to configure Left_PGA_Mixer_Mic3L_Switch\n"); Sound_alsa_delete(hSound); return NULL; } } } snd_output_close(log); #endif return hSound; }
/****************************************************************************** * initSwParams * ***************************************************************************/ static Int initSwParams(snd_pcm_t *rc, snd_pcm_sw_params_t *swParams, Sound_Handle hSound, Int delay) { Int status; snd_pcm_uframes_t stop_threshold; snd_pcm_uframes_t startThreashold; /* Get the current sw params */ status = snd_pcm_sw_params_current (rc, swParams); if (status < 0) { Dmai_err2 ("Failed to read the current swparams on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the available min */ status = snd_pcm_sw_params_set_avail_min(rc, swParams, hSound->periodSize); if (status < 0) { Dmai_err3 ("Failed to set avail min to (%d) on %s (%s)\n", hSound->periodSize, AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the start threshold */ if (delay) { startThreashold = 1; } else { startThreashold = hSound->bufSize; } status = snd_pcm_sw_params_set_start_threshold(rc, swParams, startThreashold); if (status < 0) { Dmai_err3 ("Failed to set start threashold to %d on %s (%s)\n", startThreashold, AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the stop threshold */ stop_threshold = hSound->bufSize; status = snd_pcm_sw_params_set_stop_threshold(rc, swParams, stop_threshold); if (status < 0) { Dmai_err3 ("Failed to set start threashold to (%d) on %s (%s)\n", stop_threshold, AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Write the swparams */ status = snd_pcm_sw_params(rc, swParams); if (status < 0) { Dmai_err2 ("Failed to set swparams on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } return Dmai_EOK; }
/****************************************************************************** * initHwParams ******************************************************************************/ static Int initHwParams(snd_pcm_t *rc, snd_pcm_hw_params_t *hwParams, Sound_Attrs *attrs, Sound_Handle hSound) { Int status; snd_pcm_uframes_t periodSize,bufSize; Uns buffer_time = 0; Uns sampleRate = attrs->sampleRate; /* Fill the params with the defaults */ status = snd_pcm_hw_params_any(rc, hwParams); if (status < 0) { Dmai_err2("Failed to init ALSA hardware param structure on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the access type to interleaved */ status = snd_pcm_hw_params_set_access(rc, hwParams, SND_PCM_ACCESS_RW_INTERLEAVED); if (status < 0) { Dmai_err2("Failed to set ALSA access type on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the format to 16 bit little endian */ status = snd_pcm_hw_params_set_format(rc, hwParams, SND_PCM_FORMAT_S16_LE); if (status < 0) { Dmai_err2("Failed to set sample format on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the sample rate */ status = snd_pcm_hw_params_set_rate_near(rc, hwParams, (Uns *) &sampleRate, 0); if (status < 0) { Dmai_err3("Failed to set sample rate to %d on %s (%s)\n", attrs->sampleRate, AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set the number of channels to 2 */ status = snd_pcm_hw_params_set_channels(rc, hwParams, attrs->channels); if (status < 0) { Dmai_err3("Failed to set channel count to %d on %s (%s)\n", attrs->channels, AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Set period size */ periodSize = hSound->periodSize=16; status = snd_pcm_hw_params_set_period_size_near (rc, hwParams, &periodSize, 0); if (status < 0) { Dmai_err3("Failed to set the period size to %d on %s (%s)\n", periodSize, AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } if (periodSize != hSound->periodSize) { Dmai_dbg4("Failed to set buffer size (%d) , got (%d) on %s (%s)\n", hSound->periodSize, periodSize, AUDIO_DEVICE, snd_strerror(status)); hSound->periodSize = periodSize; } /* Set the maximum buffer time */ status = snd_pcm_hw_params_get_buffer_time_max(hwParams, &buffer_time, 0); if (status < 0) { Dmai_err2("Failed to get maximum buffer time on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } if (buffer_time > 500000) { buffer_time = 500000; } status = snd_pcm_hw_params_set_buffer_time_near(rc, hwParams, &buffer_time, 0); if (status < 0) { Dmai_err2("Failed to set maximum buffer time on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Prepare the PCM interface with the parameters chosen */ status = snd_pcm_hw_params(rc, hwParams); if (status < 0) { Dmai_err2("Failed to set ALSA parameters on %s (%s)\n", AUDIO_DEVICE, snd_strerror(status)); return Dmai_EFAIL; } /* Do sanity check */ snd_pcm_hw_params_get_period_size(hwParams, &periodSize, 0); snd_pcm_hw_params_get_buffer_size(hwParams, &bufSize); if (periodSize == bufSize) { Dmai_err2("Can't use period size equal to buf size (%d == %d)\n", periodSize, bufSize); return Dmai_EFAIL; } hSound->periodSize = periodSize; hSound->bufSize = bufSize; return Dmai_EOK; }
/****************************************************************************** * setMixerVolume *****************************************************************************/ static Int setMixerVolume (Sound_Attrs *attrs) { Int status; snd_mixer_t *rcMixer; snd_mixer_elem_t *elem; snd_mixer_selem_id_t *sid; snd_mixer_selem_id_malloc (&sid); /* Open the mixer device */ status = snd_mixer_open (&rcMixer, 0); if ( status<0 ) { Dmai_err2 ("Failed to open mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } /* Attach mixer with sound card */ status = snd_mixer_attach (rcMixer,AUDIO_MIXER); if (status <0) { Dmai_err2 ("Failed to attach mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } /* Register mixer with selected elements */ status = snd_mixer_selem_register (rcMixer, NULL, NULL); if (status <0) { Dmai_err2 ("Failed to register mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } /* Load mixer */ status = snd_mixer_load (rcMixer); if (status <0) { Dmai_err2 ("Failed to load mixer on %s (%s)\n", AUDIO_MIXER, snd_strerror (status)); return Dmai_EFAIL; } for (elem = snd_mixer_first_elem (rcMixer); elem; elem=snd_mixer_elem_next(elem)) { snd_mixer_selem_get_id(elem,sid); if (!snd_mixer_selem_is_active(elem)) continue; if (attrs->mode == Sound_Mode_OUTPUT || attrs->mode == Sound_Mode_FULLDUPLEX) { if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) snd_mixer_selem_set_playback_volume (elem, SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain); if (snd_mixer_selem_has_playback_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) snd_mixer_selem_set_playback_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain); } if (attrs->mode == Sound_Mode_INPUT || attrs->mode == Sound_Mode_FULLDUPLEX) { if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_LEFT)) snd_mixer_selem_set_capture_volume (elem, SND_MIXER_SCHN_FRONT_LEFT,attrs->leftGain); if (snd_mixer_selem_has_capture_channel(elem, SND_MIXER_SCHN_FRONT_RIGHT)) snd_mixer_selem_set_capture_volume (elem, SND_MIXER_SCHN_FRONT_RIGHT,attrs->rightGain); } } snd_mixer_selem_id_free (sid); snd_mixer_close (rcMixer); return Dmai_EOK; }
/****************************************************************************** * Framecopy_resizer_accel_config ******************************************************************************/ Int Framecopy_resizer_accel_config(Framecopy_Handle hFc, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { #if defined(CONFIG_VIDEO_OMAP34XX_ISP_RESIZER) struct v4l2_requestbuffers reqbuf; Int rszRate; BufferGfx_Dimensions srcDim, dstDim; struct rsz_params params = { 0, /* in_hsize (set at run time) */ 0, /* in_vsize (set at run time) */ 0, /* in_pitch (set at run time) */ RSZ_INTYPE_YCBCR422_16BIT, /* inptyp */ 0, /* vert_starting_pixel */ 0, /* horz_starting_pixel */ 0, /* cbilin */ RSZ_PIX_FMT_UYVY, /* pix_fmt */ 0, /* out_hsize (set at run time) */ 0, /* out_vsize (set at run time) */ 0, /* out_pitch (set at run time) */ 0, /* hstph */ 0, /* vstph */ { /* hfilt_coeffs */ 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0 }, { /* vfilt_coeffs */ 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0, 256, 0, 0, 0 }, { /* yenh_params */ 0, /* type */ 0, /* gain */ 0, /* slop */ 0 /* core */ } }; /* Pointers must be a multiple of 4096 bytes */ assert((Buffer_getPhysicalPtr(hDstBuf) & 0xFFF) == 0); assert((Buffer_getPhysicalPtr(hSrcBuf) & 0xFFF) == 0); BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); Dmai_dbg2("Configuring resizer to copy image of resolution %dx%d\n", srcDim.width, srcDim.height); /* Source and destination pitch must be 32 bytes aligned */ if (srcDim.lineLength % 32 || dstDim.lineLength % 32) { Dmai_err2("Src (%ld) and dst (%ld) must be aligned on 32 bytes\n", srcDim.lineLength, dstDim.lineLength); return Dmai_EINVAL; } /* Set up the copy job */ params.in_hsize = srcDim.width; params.in_vsize = srcDim.height; params.in_pitch = srcDim.lineLength; params.out_hsize = dstDim.width; params.out_vsize = dstDim.height; params.out_pitch = dstDim.lineLength; params.cbilin = 0; params.pix_fmt = RSZ_PIX_FMT_UYVY; params.vert_starting_pixel = 0; params.horz_starting_pixel = 0; params.inptyp = RSZ_INTYPE_YCBCR422_16BIT; params.hstph = 0; params.vstph = 0; params.yenh_params.type = 0; params.yenh_params.gain = 0; params.yenh_params.slop = 0; params.yenh_params.core = 0; hFc->inSize = srcDim.lineLength * params.in_vsize; hFc->outSize = dstDim.lineLength * params.out_vsize; if (ioctl(hFc->fd, RSZ_S_PARAM, ¶ms) == -1) { Dmai_err0("Framecopy setting parameters failed.\n"); return Dmai_EFAIL; } rszRate = 0x0; if (ioctl(hFc->fd, RSZ_S_EXP, &rszRate) == -1) { Dmai_err0("Framecopy setting read cycle failed.\n"); return Dmai_EFAIL; } reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; reqbuf.memory = V4L2_MEMORY_USERPTR; reqbuf.count = 2; if (ioctl(hFc->fd, RSZ_REQBUF, &reqbuf) == -1) { Dmai_err0("Request buffer failed.\n"); return Dmai_EFAIL; } return Dmai_EOK; #else Dmai_err0("not implemented\n"); return Dmai_ENOTIMPL; #endif /* end CONFIG_VIDEO_OMAP34XX_ISP_RESIZER */ }