/****************************************************************************** * 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; }
/****************************************************************************** * Resize_config ******************************************************************************/ Int Resize_config(Resize_Handle hResize, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf, Buffer_Handle hsDstBuf) { BufferGfx_Dimensions srcDim, dstDim, sdstDim; UInt hDif; UInt vDif; UInt shDif; UInt svDif; struct rsz_channel_config rsz_chan_config; struct rsz_single_shot_config rsz_ss_config; /* Make sure our input parameters are valid */ if (!hResize) { Dmai_err0("Resize_Handle parameter must not be NULL\n"); return Dmai_EINVAL; } if (!hSrcBuf) { Dmai_err0("Source buffer parameter must not be NULL\n"); return Dmai_EINVAL; } if (!hDstBuf) { Dmai_err0("Destination buffer parameter must not be NULL\n"); return Dmai_EINVAL; } if (!hsDstBuf) { Dmai_err0("Second destination buffer parameter is NULL\n"); } /* Buffer needs to be graphics buffers */ if (Buffer_getType(hSrcBuf) != Buffer_Type_GRAPHICS || Buffer_getType(hDstBuf) != Buffer_Type_GRAPHICS || hsDstBuf?(Buffer_getType(hsDstBuf) != Buffer_Type_GRAPHICS):FALSE) { Dmai_err0("Src and dst buffers need to be graphics buffers\n"); return Dmai_EINVAL; } BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); hsDstBuf?BufferGfx_getDimensions(hsDstBuf, &sdstDim):NULL; if (dstDim.width <= 0) { Dmai_err0("Destination buffer width must be greater than zero\n"); return Dmai_EINVAL; } if (dstDim.height <= 0) { Dmai_err0("Destination buffer height must be greater than zero\n"); return Dmai_EINVAL; } if (hsDstBuf?(sdstDim.width <= 0):FALSE) { Dmai_err0("Second destination buffer width must be greater than zero\n"); return Dmai_EINVAL; } if (hsDstBuf?(sdstDim.height <= 0):FALSE) { Dmai_err0("Second destination buffer height must be greater than zero\n"); return Dmai_EINVAL; } if ((srcDim.lineLength & 0x1F) != 0) { Dmai_err0("Source buffer pitch must be a multiple of 32 bytes\n"); return Dmai_EINVAL; } if ((dstDim.lineLength & 0x1F) != 0) { Dmai_err0("Destination buffer pitch must be a multiple of 32 bytes\n"); return Dmai_EINVAL; } if (hsDstBuf?((sdstDim.lineLength & 0x1F) != 0):FALSE) { Dmai_err0("Second destination buffer pitch must be a multiple of 32 bytes\n"); return Dmai_EINVAL; } /* Check for valid buffer scaling */ hDif = srcDim.width * 256 / dstDim.width; vDif = srcDim.height * 256 / dstDim.height; if (hDif < 32) { Dmai_err0("Horizontal up-scaling must not exceed 8x\n"); return Dmai_EINVAL; } if (hDif > 4096) { Dmai_err0("Horizontal down-scaling must not exceed 1/16x\n"); return Dmai_EINVAL; } if (vDif < 32) { Dmai_err0("Vertical up-scaling must not exceed 8x\n"); return Dmai_EINVAL; } if (vDif > 4096) { Dmai_err0("Vertical down-scaling must not exceed 1/16x\n"); return Dmai_EINVAL; } shDif = hsDstBuf?(srcDim.width * 256 / sdstDim.width):0; svDif = hsDstBuf?(srcDim.height * 256 / sdstDim.height):0; if (shDif && shDif < 32) { Dmai_err0("Second horizontal up-scaling must not exceed 8x\n"); return Dmai_EINVAL; } if (shDif && shDif > 4096) { Dmai_err0("Second horizontal down-scaling must not exceed 1/16x\n"); return Dmai_EINVAL; } if (svDif && svDif < 32) { Dmai_err0("Second vertical up-scaling must not exceed 8x\n"); return Dmai_EINVAL; } if (svDif && svDif > 4096) { Dmai_err0("Second vertical down-scaling must not exceed 1/16x\n"); return Dmai_EINVAL; } /* Configure for ColorSpace_UYVY_*/ if (BufferGfx_getColorSpace(hSrcBuf) == ColorSpace_UYVY) { /* Setting default configuration in Resizer */ Dmai_clear(rsz_ss_config); rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = 0; rsz_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(hResize->fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in setting default configuration for single shot mode\n"); goto faco_error; } /* default configuration setting in Resizer successfull */ Dmai_clear(rsz_ss_config); rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = sizeof(struct rsz_single_shot_config); rsz_chan_config.config = &rsz_ss_config; if (ioctl(hResize->fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in getting resizer channel configuration from driver\n"); goto faco_error; } /* input params are set at the resizer */ rsz_ss_config.input.image_width = srcDim.width; rsz_ss_config.input.image_height = srcDim.height; rsz_ss_config.input.ppln = rsz_ss_config.input.image_width + 8; rsz_ss_config.input.lpfr = rsz_ss_config.input.image_height + 10; rsz_ss_config.input.pix_fmt = pixFormatConversion(BufferGfx_getColorSpace(hSrcBuf)); rsz_ss_config.output1.pix_fmt = pixFormatConversion(BufferGfx_getColorSpace(hDstBuf)); rsz_ss_config.output1.enable = 1; rsz_ss_config.output1.width = dstDim.width; rsz_ss_config.output1.height = dstDim.height; rsz_ss_config.output2.pix_fmt = hsDstBuf?pixFormatConversion(BufferGfx_getColorSpace(hsDstBuf)):0; rsz_ss_config.output2.enable = hsDstBuf?1:0; rsz_ss_config.output2.width = hsDstBuf?sdstDim.width:0; rsz_ss_config.output2.height = hsDstBuf?sdstDim.height:0; rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = sizeof(struct rsz_single_shot_config); if (ioctl(hResize->fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in setting default configuration for single shot mode\n"); goto faco_error; } rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = sizeof(struct rsz_single_shot_config); /* read again and verify */ if (ioctl(hResize->fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in getting configuration from driver\n"); goto faco_error; } } return Dmai_EOK; faco_error: close(hResize->fd); hResize->fd = 0; return Dmai_EFAIL; }
/****************************************************************************** * _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; }
/****************************************************************************** * Resize_config ******************************************************************************/ Int Resize_config(Resize_Handle hResize, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { #ifdef CONFIG_DM365_IPIPE BufferGfx_Dimensions srcDim, dstDim; UInt hDif; UInt vDif; struct rsz_channel_config rsz_chan_config; struct rsz_single_shot_config rsz_ss_config; /* Make sure our input parameters are valid */ if (!hResize) { Dmai_err0("Resize_Handle parameter must not be NULL\n"); return Dmai_EINVAL; } if (!hSrcBuf) { Dmai_err0("Source buffer parameter must not be NULL\n"); return Dmai_EINVAL; } if (!hDstBuf) { Dmai_err0("Destination buffer parameter must not be NULL\n"); return Dmai_EINVAL; } /* 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; } BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); if (dstDim.width <= 0) { Dmai_err0("Destination buffer width must be greater than zero\n"); return Dmai_EINVAL; } if (dstDim.height <= 0) { Dmai_err0("Destination buffer height must be greater than zero\n"); return Dmai_EINVAL; } if ((srcDim.lineLength & 0x1F) != 0) { Dmai_err0("Source buffer pitch must be a multiple of 32 bytes\n"); return Dmai_EINVAL; } if ((dstDim.lineLength & 0x1F) != 0) { Dmai_err0("Destination buffer pitch must be a multiple of 32 bytes\n"); return Dmai_EINVAL; } /* Check for valid buffer scaling */ hDif = srcDim.width * 256 / dstDim.width; vDif = srcDim.height * 256 / dstDim.height; if (hDif < 32) { Dmai_err0("Horizontal up-scaling must not exceed 8x\n"); return Dmai_EINVAL; } if (hDif > 4096) { Dmai_err0("Horizontal down-scaling must not exceed 1/16x\n"); return Dmai_EINVAL; } if (vDif < 32) { Dmai_err0("Vertical up-scaling must not exceed 8x\n"); return Dmai_EINVAL; } if (vDif > 4096) { Dmai_err0("Vertical down-scaling must not exceed 1/16x\n"); return Dmai_EINVAL; } /* Set the driver default parameters and retrieve what was set */ Dmai_clear(rsz_ss_config); rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = 0; rsz_chan_config.config = NULL; /* to set defaults in driver */ if (ioctl(hResize->fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in setting default configuration for single shot mode\n"); goto cleanup; } /* default configuration setting in Resizer successfull */ Dmai_clear(rsz_ss_config); rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = sizeof(struct rsz_single_shot_config); rsz_chan_config.config = &rsz_ss_config; if (ioctl(hResize->fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in getting resizer channel configuration from driver\n"); goto cleanup; } /* input params are set at the resizer */ rsz_ss_config.input.image_width = srcDim.width; rsz_ss_config.input.image_height = srcDim.height; rsz_ss_config.input.ppln = rsz_ss_config.input.image_width + 8; rsz_ss_config.input.lpfr = rsz_ss_config.input.image_height + 10; rsz_ss_config.input.pix_fmt = pixFormatConversion(BufferGfx_getColorSpace(hSrcBuf)); rsz_ss_config.output1.pix_fmt = pixFormatConversion(BufferGfx_getColorSpace(hDstBuf)); rsz_ss_config.output1.enable = 1; rsz_ss_config.output1.width = dstDim.width; rsz_ss_config.output1.height = dstDim.height; rsz_ss_config.output2.enable = 0; rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = sizeof(struct rsz_single_shot_config); if (ioctl(hResize->fd, RSZ_S_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in setting default configuration for single shot mode\n"); goto cleanup; } rsz_chan_config.oper_mode = IMP_MODE_SINGLE_SHOT; rsz_chan_config.chain = 0; rsz_chan_config.len = sizeof(struct rsz_single_shot_config); /* read again and verify */ if (ioctl(hResize->fd, RSZ_G_CONFIG, &rsz_chan_config) < 0) { Dmai_err0("Error in getting configuration from driver\n"); goto cleanup; } return Dmai_EOK; cleanup: close(hResize->fd); hResize->fd = 0; return Dmai_EFAIL; #else Dmai_err0("not implemented\n"); return Dmai_ENOTIMPL; #endif }