Void CapBuf_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: { ERR("Unsupported color space (%d) for _Dmai_blackFill\n", BufferGfx_getColorSpace(hBuf)); break; } } }
/****************************************************************************** * 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_execute(Framecopy_Handle hFc, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { vdce_address_start_t params; BufferGfx_Dimensions srcDim; BufferGfx_Dimensions dstDim; UInt32 srcOffset, dstOffset; assert(hFc); assert(hSrcBuf); assert(hDstBuf); /* VDCE addresses must be a multiple of 8 */ assert((((UInt32) Buffer_getUserPtr(hDstBuf)) & 0x7) == 0); assert((((UInt32) Buffer_getUserPtr(hSrcBuf)) & 0x7) == 0); /* Buffer sizes / 4 must be a multiple of 8 */ assert(((Buffer_getSize(hSrcBuf) / 4) & 0x7) == 0); assert(((Buffer_getSize(hDstBuf) / 4) & 0x7) == 0); BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); assert(srcDim.x >= 0); assert(srcDim.y >= 0); assert(dstDim.x >= 0); assert(dstDim.y >= 0); assert((srcDim.x & 0x7) == 0); assert((dstDim.x & 0x7) == 0); srcOffset = srcDim.y * srcDim.lineLength + srcDim.x; dstOffset = dstDim.y * dstDim.lineLength + dstDim.x; params.buffers[VDCE_BUF_IN].index = -1; params.buffers[VDCE_BUF_IN].buf_type = VDCE_BUF_IN; params.buffers[VDCE_BUF_IN].virt_ptr = ((Int32) Buffer_getUserPtr(hSrcBuf)+ srcOffset); params.buffers[VDCE_BUF_IN].size = Buffer_getSize(hSrcBuf); params.buffers[VDCE_BUF_OUT].index = -1; params.buffers[VDCE_BUF_OUT].buf_type = VDCE_BUF_OUT; params.buffers[VDCE_BUF_OUT].virt_ptr = ((Int32) Buffer_getUserPtr(hDstBuf)+ dstOffset); params.buffers[VDCE_BUF_OUT].size = Buffer_getSize(hDstBuf); params.src_horz_pitch = srcDim.lineLength; params.res_horz_pitch = dstDim.lineLength; if (ioctl(hFc->fd, VDCE_START, ¶ms) < 0) { Dmai_err0("Failed VDCE_START\n"); return Dmai_EFAIL; } if (BufferGfx_getColorSpace(hDstBuf) == ColorSpace_YUV420PSEMI) { Buffer_setNumBytesUsed(hDstBuf, dstDim.width * dstDim.height * 3 / 2); } else { Buffer_setNumBytesUsed(hDstBuf, dstDim.width * dstDim.height * 2); } 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_execute ******************************************************************************/ Int Resize_execute(Resize_Handle hResize, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf, Buffer_Handle hsDstBuf) { struct imp_convert rsz; struct rsz_channel_config rsz_chan_config; struct rsz_single_shot_config rsz_ss_config; BufferGfx_Dimensions srcDim; BufferGfx_Dimensions dstDim; BufferGfx_Dimensions sdstDim; UInt32 srcOffset; UInt32 dstOffset; UInt32 sdstOffset; UInt32 srcSize; UInt32 dstSize; assert(hResize); assert(hSrcBuf); assert(hDstBuf); Dmai_clear(rsz); BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); hsDstBuf?BufferGfx_getDimensions(hsDstBuf, &sdstDim):NULL; srcSize = srcDim.width * srcDim.height; dstSize = dstDim.width * dstDim.height; /* the resize operation to ColorSpace_UYVY is different from ColorSpace_YUV420PSEMI*/ if (BufferGfx_getColorSpace(hSrcBuf) == ColorSpace_UYVY) { srcOffset = srcDim.y * srcDim.lineLength + (srcDim.x << 1); dstOffset = dstDim.y * dstDim.lineLength + (dstDim.x << 1); sdstOffset = hsDstBuf?(sdstDim.y * sdstDim.lineLength + (sdstDim.x << 1)):0; rsz.in_buff.index = -1; rsz.in_buff.buf_type = IMP_BUF_IN; rsz.in_buff.offset = Buffer_getPhysicalPtr(hSrcBuf) + srcOffset; rsz.in_buff.size = Buffer_getSize(hSrcBuf); rsz.out_buff1.index = -1; rsz.out_buff1.buf_type = IMP_BUF_OUT1; rsz.out_buff1.offset = Buffer_getPhysicalPtr(hDstBuf) + dstOffset; rsz.out_buff1.size = Buffer_getSize(hDstBuf); rsz.out_buff2.index = -1; rsz.out_buff2.buf_type = IMP_BUF_OUT2; rsz.out_buff2.offset = hsDstBuf?(Buffer_getPhysicalPtr(hsDstBuf) + sdstOffset):0; rsz.out_buff2.size = hsDstBuf?Buffer_getSize(hsDstBuf):0; /* * The IPIPE requires that the memory offsets of the input and output * buffers start on 32-byte boundaries. */ assert((rsz.in_buff.offset & 0x1F) == 0); assert((rsz.out_buff1.offset & 0x1F) == 0); assert((rsz.out_buff2.offset & 0x1F) == 0); /* Start IPIPE operation */ if (ioctl(hResize->fd, RSZ_RESIZE, &rsz) == -1) { Dmai_err0("Failed RSZ_RESIZE\n"); return Dmai_EFAIL; } Buffer_setNumBytesUsed(hDstBuf, Buffer_getSize(hDstBuf)); hsDstBuf?Buffer_setNumBytesUsed(hsDstBuf, Buffer_getSize(hsDstBuf)):NULL; } else { /* configure for the ColorSpace_YUV420PSEMI*/ 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"); return Dmai_EFAIL; } /* 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 configuration from driver\n"); return Dmai_EFAIL; } /* 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 = IPIPE_420SP_Y; 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"); return Dmai_EFAIL; } 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"); return Dmai_EFAIL; } /* execute for ColorSpace_YUV420PSEMI*/ Dmai_clear(rsz); //srcOffset = srcDim.y * srcDim.lineLength + (srcDim.x << 1); //dstOffset = dstDim.y * dstDim.lineLength + (dstDim.x << 1); rsz.in_buff.buf_type = IMP_BUF_IN; rsz.in_buff.index = -1; rsz.in_buff.offset = Buffer_getPhysicalPtr(hSrcBuf); //rsz.in_buff.size = Buffer_getSize(hSrcBuf); rsz.in_buff.size = srcSize; rsz.out_buff1.buf_type = IMP_BUF_OUT1; rsz.out_buff1.index = -1; rsz.out_buff1.offset = Buffer_getPhysicalPtr(hDstBuf); //rsz.out_buff1.size = Buffer_getSize(hDstBuf); rsz.out_buff1.size = dstSize; /* * The IPIPE requires that the memory offsets of the input and output * buffers start on 32-byte boundaries. */ assert((rsz.in_buff.offset & 0x1F) == 0); assert((rsz.out_buff1.offset & 0x1F) == 0); /* Start IPIPE operation */ if (ioctl(hResize->fd, RSZ_RESIZE, &rsz) == -1) { Dmai_err0("Failed RSZ_RESIZE\n"); return Dmai_EFAIL; } /* input params are set at the resizer */ rsz_ss_config.input.image_width = srcDim.width; rsz_ss_config.input.image_height = srcDim.height>>1; 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 = IPIPE_420SP_C; 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"); return Dmai_EFAIL; } 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"); return Dmai_EFAIL; } Dmai_clear(rsz); //srcOffset = srcDim.y * srcDim.lineLength + (srcDim.x << 1); //dstOffset = dstDim.y * dstDim.lineLength + (dstDim.x << 1); rsz.in_buff.buf_type = IMP_BUF_IN; rsz.in_buff.index = -1; rsz.in_buff.offset = Buffer_getPhysicalPtr(hSrcBuf) + srcSize; rsz.in_buff.size = srcSize>>1; rsz.out_buff1.buf_type = IMP_BUF_OUT1; rsz.out_buff1.index = -1; rsz.out_buff1.offset = Buffer_getPhysicalPtr(hDstBuf) + dstSize; rsz.out_buff1.size = dstSize>>1; /* * The IPIPE requires that the memory offsets of the input and output * buffers start on 32-byte boundaries. */ assert((rsz.in_buff.offset & 0x1F) == 0); assert((rsz.out_buff1.offset & 0x1F) == 0); /* Start IPIPE operation */ if (ioctl(hResize->fd, RSZ_RESIZE, &rsz) == -1) { Dmai_err0("Failed RSZ_RESIZE\n"); return Dmai_EFAIL; } Buffer_setNumBytesUsed(hDstBuf, Buffer_getNumBytesUsed(hSrcBuf)); } return Dmai_EOK; }
/****************************************************************************** * _Dmai_blackFill ******************************************************************************/ 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; Int32 cbCrSize = Buffer_getSize(hBuf) - ySize; Int i; /* Fill the Y plane */ for (i = 0; i < ySize; i++) { yPtr[i] = 0x0; } for (i = 0; i < cbCrSize; i++) { cbcrPtr[i] = 0x80; } break; } case ColorSpace_YUV420PSEMI: { Int8 *bufPtr = Buffer_getUserPtr(hBuf); Int y; Int bpp = ColorSpace_getBpp(ColorSpace_YUV420PSEMI); BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); for (y = 0; y < dim.height; y++) { memset(bufPtr, 0x0, dim.width * bpp / 8); bufPtr += dim.lineLength; } for (y = 0; y < (dim.height / 2); y++) { memset(bufPtr, 0x80, dim.width * bpp / 8); bufPtr += dim.lineLength; } break; } case ColorSpace_UYVY: { Int32 *bufPtr = (Int32*)Buffer_getUserPtr(hBuf); Int32 bufSize = Buffer_getSize(hBuf) / sizeof(Int32); Int i; /* Make sure display buffer is 4-byte aligned */ assert((((UInt32) bufPtr) & 0x3) == 0); for (i = 0; i < bufSize; i++) { bufPtr[i] = UYVY_BLACK; } break; } case ColorSpace_RGB565: { memset(Buffer_getUserPtr(hBuf), 0, Buffer_getSize(hBuf)); break; } default: Dmai_err0("Unsupported color space for _Dmai_blackFill\n"); break; } }
/****************************************************************************** * 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; }
/****************************************************************************** * 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 }
/****************************************************************************** * appMain ******************************************************************************/ Int appMain(Args * args) { IMGDEC1_Params params = Idec1_Params_DEFAULT; IMGDEC1_DynamicParams dynParams = Idec1_DynamicParams_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Idec1_Handle hId = NULL; Engine_Handle hEngine = NULL; Time_Handle hTime = NULL; Buffer_Handle hInBuf = NULL; Buffer_Handle hOutBuf = NULL; FILE *outFile = NULL; FILE *inFile = NULL; Int numBytes = 0; Int ret = Dmai_EOK; Cpu_Device device; UInt32 time; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Determine which device the application is running on */ if (Cpu_getDevice(NULL, &device) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to determine target board\n"); goto cleanup; } /* Open input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open file %s\n", args->inFile); goto cleanup; } /* Open output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create output file %s\n", args->outFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to open codec engine %s\n", args->engineName); goto cleanup; } /* * Set output color format to UYVY or Planar output. * Here XDM_DEFUALT sets the output planar format to * the planar fromat of the encoded image. * */ switch (args->oColorSpace) { case ColorSpace_UYVY: params.forceChromaFormat = XDM_YUV_422ILE; break; case ColorSpace_NOTSET: params.forceChromaFormat = XDM_CHROMAFORMAT_DEFAULT; break; case ColorSpace_YUV444P: params.forceChromaFormat = XDM_YUV_444P; break; case ColorSpace_YUV422P: params.forceChromaFormat = XDM_YUV_422P; break; case ColorSpace_YUV420P: params.forceChromaFormat = XDM_YUV_420P; break; case ColorSpace_YUV420PSEMI: params.forceChromaFormat = XDM_YUV_420SP; break; case ColorSpace_GRAY: params.forceChromaFormat = ColorSpace_GRAY; break; default: ret = Dmai_EFAIL; fprintf(stderr,"Unsupported output color space %d.\n", args->oColorSpace); goto cleanup; } if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) { params.maxHeight = VideoStd_720P_HEIGHT; params.maxWidth = VideoStd_720P_WIDTH; } if (device == Cpu_Device_DM6467) { params.maxHeight = VideoStd_720P_HEIGHT; params.maxWidth = VideoStd_720P_WIDTH; } /* Create the image decoder */ hId = Idec1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hId == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create image decoder: %s\n", args->codecName); goto cleanup; } /* Align buffers to cache line boundary */ gfxAttrs.bAttrs.memParams.align = bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { gfxAttrs.bAttrs.memParams.flags = bAttrs.memParams.flags = Memory_CACHED; } gfxAttrs.colorSpace = args->oColorSpace; gfxAttrs.dim.width = params.maxWidth; gfxAttrs.dim.height = params.maxHeight; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(params.maxWidth, gfxAttrs.colorSpace); /* Create an output buffer for decoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Idec1_getOutBufSize(hId), BUFSIZEALIGN), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hOutBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffers\n"); goto cleanup; } /* Create an input buffer for encoded data */ hInBuf = Buffer_create(Dmai_roundUp(Idec1_getInBufSize(hId), BUFSIZEALIGN), &bAttrs); if (hInBuf == NULL) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to create contiguous buffers\n"); goto cleanup; } /* Read encoded image data */ numBytes = fread(Buffer_getUserPtr(hInBuf), 1, Idec1_getInBufSize(hId), inFile); Buffer_setNumBytesUsed(hInBuf, numBytes); if (args->benchmark) { if (Time_reset(hTime) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to reset timer\n"); goto cleanup; } } if (args->cache) { /* * To meet xDAIS DMA Rule 7, when input buffers are cached, we * must writeback the cache into physical memory. Also, per DMA * Rule 7, we must invalidate the output buffer from * cache before providing it to any xDAIS algorithm. */ Memory_cacheWbInv(Buffer_getUserPtr(hInBuf), Buffer_getSize(hInBuf)); /* Per DMA Rule 7, our output buffer cache lines must be cleaned */ Memory_cacheInv(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus \n", (Uns) time); } } printf("Decoding image...\n"); /* Decode the image frame */ ret = Idec1_process(hId, hInBuf, hOutBuf); if (ret < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to decode image buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Frame - Decode: %uus \n", (unsigned int)time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } /* Write decoded image to a file */ if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_UYVY){ if (writeFrameUYVY(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420PSEMI) { if (writeFrameSemiPlanar(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else if (BufferGfx_getColorSpace(hOutBuf) == ColorSpace_YUV420P || ColorSpace_YUV422P || ColorSpace_YUV444P || ColorSpace_GRAY){ /* For XDM_GRAY ignoring the color planes */ if (args->oColorSpace == ColorSpace_GRAY){ BufferGfx_setColorSpace (hOutBuf, ColorSpace_GRAY); } if (writeFramePlanar(hOutBuf, outFile) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to write image to file\n"); goto cleanup; } } else { ret = Dmai_EFAIL; fprintf(stderr,"Invalid output colorspace.\n"); goto cleanup; } if (args->benchmark) { if (Time_total(hTime, &time) < 0) { ret = Dmai_EFAIL; fprintf(stderr,"Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } cleanup: /* Clean up the application */ if (hId) { Idec1_delete(hId); } if (hInBuf) { Buffer_delete(hInBuf); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } if (hTime) { Time_delete(hTime); } if (inFile) { fclose(inFile); } if (outFile) { fclose(outFile); } printf("End of application.\n"); if (ret == Dmai_EFAIL) return 1; else return 0; }
/****************************************************************************** * writeFrameSemiPlanar ******************************************************************************/ Int writeFrameSemiPlanar(Buffer_Handle hBuf, FILE *outFile) { Int8 *yPtr, *cbcrPtr; UInt32 ySize; /* Size of Luma data */ Uint32 cbcrSize; /* Size of Chroma (cb and cr) data */ Char *colorFmt; Int y, x; BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); /* The three color planes are evenly spaced in the output buffer. Each * plane has been allocated a size equal to the input creation parameter * maxWidth x maxHeight. */ ySize = dim.width * dim.height; switch(BufferGfx_getColorSpace(hBuf)){ case ColorSpace_YUV420PSEMI: cbcrSize = dim.width * dim.height / 2; colorFmt = "420P"; break; default: printf("Unsupported output color space %d.\n", BufferGfx_getColorSpace(hBuf)); return -1; } /* Write Y plane */ yPtr = Buffer_getUserPtr(hBuf); if (fwrite(yPtr, 1, ySize, outFile) != ySize ) { fprintf(stderr,"Failed to write y data to disk\n"); return -1; } /* Separate Cb from CbCr interleaved and save Cb plane */ cbcrPtr = Buffer_getUserPtr(hBuf) + Buffer_getSize(hBuf) * 2/3; for (y = 0; y < dim.height / 2; y++) { for (x = 0; x < dim.width; x += 2) { if (fwrite(&cbcrPtr[x], 1, 1, outFile) != 1) { fprintf(stderr,"Failed to write data to disk\n"); return -1; } } cbcrPtr += dim.lineLength; } /* Separate Cr from CbCr interleaved and save Cr plane */ cbcrPtr = Buffer_getUserPtr(hBuf) + Buffer_getSize(hBuf) * 2 / 3; for (y = 0; y < dim.height / 2; y++) { for (x = 1; x < dim.width; x += 2) { if (fwrite(&cbcrPtr[x], 1, 1, outFile) != 1) { fprintf(stderr,"Failed to write data to disk\n"); return -1; } } cbcrPtr += dim.lineLength; } printf("Wrote %s image size %d (%dx%d) to disk\n", colorFmt, (Int) (ySize + cbcrSize), (Int) dim.width, (Int) dim.height); return 0; }
/****************************************************************************** * writeFramePlanar ******************************************************************************/ Int writeFramePlanar(Buffer_Handle hBuf, FILE *outFile) { Int8 *yPtr, *cbcrPtr; UInt32 ySize; /* Size of Luma data */ Uint32 cbcrSize; /* Size of Chroma (cb and cr) data */ Uint32 cbOffset, crOffSet; Char *colorFmt; BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); /* The three color planes are evenly spaced in the output buffer. Each * plane has been allocated a size equal to the input creation parameter * maxWidth x maxHeight. */ cbOffset = Buffer_getSize(hBuf) * 1/3; crOffSet = Buffer_getSize(hBuf) * 2/3; ySize = dim.width * dim.height; switch(BufferGfx_getColorSpace(hBuf)){ case ColorSpace_YUV444P: cbcrSize = dim.width * dim.height * 2; colorFmt = "444P"; break; case ColorSpace_YUV422P: cbcrSize = dim.width * dim.height; colorFmt = "422P"; break; case ColorSpace_YUV420P: cbcrSize = dim.width * dim.height / 2; colorFmt = "420P"; break; case ColorSpace_GRAY: cbcrSize = 0; colorFmt = "GRAY"; break; default: printf("Unsupported output color space %d.\n", BufferGfx_getColorSpace(hBuf)); return -1; } /* Write Y plane */ yPtr = Buffer_getUserPtr(hBuf); if (fwrite(yPtr, 1, ySize, outFile) != ySize ) { fprintf(stderr,"Failed to write y data to disk\n"); return -1; } /* Write Cb plane */ cbcrPtr = Buffer_getUserPtr(hBuf) + cbOffset; if (fwrite(cbcrPtr, 1, cbcrSize / 2 , outFile) != cbcrSize / 2 ) { fprintf(stderr,"Failed to write y data to disk\n"); return -1; } /* Write Cr plane */ cbcrPtr = Buffer_getUserPtr(hBuf) + crOffSet; if (fwrite(cbcrPtr, 1, cbcrSize / 2 , outFile) != cbcrSize / 2 ) { fprintf(stderr,"Failed to write y data to disk\n"); return -1; } printf("Wrote %s image size %d (%dx%d) to disk\n", colorFmt, (Int) (ySize + cbcrSize), (Int) dim.width, (Int) dim.height); return 0; }