/****************************************************************************** * 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; }
/****************************************************************************** * gst_tiprepencbuf_convert_gst_to_dmai * This function convert gstreamer buffer into DMAI graphics buffer. *****************************************************************************/ static Buffer_Handle gst_tiprepencbuf_convert_gst_to_dmai(GstTIPrepEncBuf * prepencbuf, GstBuffer * buf, gboolean reference) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; Buffer_Handle hBuf = NULL; gfxAttrs.bAttrs.reference = reference; gfxAttrs.dim.width = prepencbuf->srcWidth; gfxAttrs.dim.height = prepencbuf->srcHeight; gfxAttrs.colorSpace = prepencbuf->srcColorSpace; gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(gfxAttrs.dim.width, prepencbuf->srcColorSpace); hBuf = Buffer_create(GST_BUFFER_SIZE(buf), BufferGfx_getBufferAttrs(&gfxAttrs)); if (hBuf == NULL) { GST_ERROR("failed to create buffer\n"); return NULL; } Buffer_setUserPtr(hBuf, (Int8 *) GST_BUFFER_DATA(buf)); Buffer_setNumBytesUsed(hBuf, GST_BUFFER_SIZE(buf)); return hBuf; }
/****************************************************************************** * readFrameUYVY ******************************************************************************/ Int readFrameUYVY(Buffer_Handle hBuf, FILE *outFile) { Int8 *ptr = Buffer_getUserPtr(hBuf); Int y; BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); for (y = 0; y < dim.height; y++) { if (fread(ptr, dim.width * 2, 1, outFile) != 1) { fprintf(stderr,"Failed to read data from file\n"); return -1; } ptr += dim.lineLength; } printf("Read UYVY frame size %d (%dx%d) from file\n", (Int) (dim.width * 2 * dim.height), (Int) dim.width, (Int) dim.height); Buffer_setNumBytesUsed(hBuf, dim.width * 2 * dim.height); return 0; }
/****************************************************************************** * Framecopy_resizer_accel_execute ******************************************************************************/ Int Framecopy_resizer_accel_execute(Framecopy_Handle hFc, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { #if defined(CONFIG_VIDEO_OMAP34XX_ISP_RESIZER) Int i; struct v4l2_buffer qbuf[2]; assert(hFc); assert(hSrcBuf); assert(hDstBuf); /* Pointers must be a multiple of 32 bytes */ assert((Buffer_getPhysicalPtr(hDstBuf) & 0x1F) == 0); assert((Buffer_getPhysicalPtr(hSrcBuf) & 0x1F) == 0); /* Queue the resizer buffers */ for (i=0; i < 2; i++) { qbuf[i].type = V4L2_BUF_TYPE_VIDEO_CAPTURE; qbuf[i].memory = V4L2_MEMORY_USERPTR; qbuf[i].index = i; if (ioctl (hFc->fd, RSZ_QUERYBUF, &qbuf[i]) == -1) { Dmai_err1("Failed to query buffer index %d\n", i); return Dmai_EFAIL; } if (i == 0) { qbuf[i].m.userptr = (unsigned long) Buffer_getUserPtr(hSrcBuf); } else { qbuf[i].m.userptr = (unsigned long) Buffer_getUserPtr(hDstBuf); } if (ioctl (hFc->fd, RSZ_QUEUEBUF, &qbuf[i]) == -1) { Dmai_err1("Failed to queue buffer index %d\n",i); return Dmai_EFAIL; } } if (ioctl(hFc->fd, RSZ_RESIZE, NULL) == -1) { Dmai_err0("Failed to execute resize job\n"); return Dmai_EFAIL; } Buffer_setNumBytesUsed(hDstBuf, Buffer_getNumBytesUsed(hSrcBuf)); return Dmai_EOK; #else Dmai_err0("not implemented\n"); return Dmai_ENOTIMPL; #endif /* end CONFIG_VIDEO_OMAP34XX_ISP_RESIZER */ }
/****************************************************************************** * readFrame420P ******************************************************************************/ Int readFrame420P(Buffer_Handle hBuf, FILE *outFile, Int imageHeight) { Int8 *yPtr = Buffer_getUserPtr(hBuf); Int8 *cbcrPtr; Int y, x; BufferGfx_Dimensions dim; BufferGfx_getDimensions(hBuf, &dim); /* Write Y plane */ for (y = 0; y < imageHeight; y++) { if (fread(yPtr, dim.width, 1, outFile) != 1) { fprintf(stderr,"Failed to read data from file\n"); return -1; } yPtr += dim.lineLength; } /* Join Cb to CbCr interleaved */ cbcrPtr = Buffer_getUserPtr(hBuf) + Buffer_getSize(hBuf) * 2 / 3; for (y = 0; y < imageHeight / 2; y++) { for (x = 0; x < dim.width; x += 2) { if (fread(&cbcrPtr[x], 1, 1, outFile) != 1) { fprintf(stderr,"Failed to read data from file\n"); return -1; } } cbcrPtr += dim.lineLength; } /* Join Cr to CbCr interleaved */ cbcrPtr = Buffer_getUserPtr(hBuf) + Buffer_getSize(hBuf) * 2 / 3; for (y = 0; y < imageHeight / 2; y++) { for (x = 1; x < dim.width; x += 2) { if (fread(&cbcrPtr[x], 1, 1, outFile) != 1) { fprintf(stderr,"Failed to read data from file\n"); return -1; } } cbcrPtr += dim.lineLength; } printf("Read 420P frame size %d (%dx%d) from file\n", (Int) (dim.width * 3 / 2 * imageHeight), (Int) dim.width, (Int) imageHeight); Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf)); return 0; }
/****************************************************************************** * Resize_execute ******************************************************************************/ Int Resize_execute(Resize_Handle hResize, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { #ifdef CONFIG_DM365_IPIPE struct imp_convert rsz; BufferGfx_Dimensions srcDim; BufferGfx_Dimensions dstDim; UInt32 srcOffset; UInt32 dstOffset; assert(hResize); assert(hSrcBuf); assert(hDstBuf); Dmai_clear(rsz); BufferGfx_getDimensions(hSrcBuf, &srcDim); BufferGfx_getDimensions(hDstBuf, &dstDim); srcOffset = srcDim.y * srcDim.lineLength + (srcDim.x << 1); dstOffset = dstDim.y * dstDim.lineLength + (dstDim.x << 1); rsz.in_buff.index = -1; rsz.in_buff.buf_type = IMP_BUF_IN; rsz.in_buff.offset = (UInt32) Buffer_getUserPtr(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 = (UInt32) Buffer_getUserPtr(hDstBuf) + dstOffset; rsz.out_buff1.size = Buffer_getSize(hDstBuf); /* * 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; #else Dmai_err0("not implemented\n"); return Dmai_ENOTIMPL; #endif }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
/****************************************************************************** * processReconData * Transform reconstructed buffer data into a UYVY frame. The format of * the reconstructed buffer data is expected to conform to the specification * found in "MPEG4 Simple Profile Encoder Codec on DM355 User's Guide" * (SPRUFE4C), and may not work for other codecs. ******************************************************************************/ Void processReconData(IVIDEO1_BufDesc* reconBufs, Buffer_Handle hSrcBuf, Buffer_Handle hDstBuf) { Int16 mbSizeY; Int16 mbSizeX; Uint32 lumaColLength; Uint32 chromaColSize; Uint32 UYVYRowLength; Uint32 UYVYMbSize; UInt8 *lum_buf; UInt8 *chr_buf; UInt8 *curr_mb; UInt8 *curr_lum_mb; UInt8 *curr_chroma_mb; Int16 i, j, k, l; BufferGfx_Dimensions dim; /* * A single Master Block is 16x16 pixels. Get our master block dimensions * by divding the pixel height and width by 16. */ BufferGfx_getDimensions(hSrcBuf, &dim); mbSizeY = dim.height >> 4; mbSizeX = dim.width >> 4; /* * Our luma buffer is a series of 16x16 byte blocks, and our chroma buffer * is a series of 16x8 byte blocks. Each block corresponds to information * for one master block. The first block in each buffer contains header * information. Set lum_buf and chr_buf to the first block after the * header. */ lum_buf = (UInt8*) (reconBufs->bufDesc[0].buf + 16 * 16); chr_buf = (UInt8*) (reconBufs->bufDesc[1].buf + 16 * 8); /* * The luma and chroma buffers are constructed in column-major order. * The blocks for a single column are followed by two padding blocks * before the next column starts. Set lumaColLength and chromaColSize * to the number of bytes that must be skipped over to get to the next * column in the corresponding buffer. */ lumaColLength = (16*16) * (mbSizeY + 2); chromaColSize = (16*8) * (mbSizeY + 2); /* * Calculate the number of bytes that must be skipped over to go to the * next row in the reconstructed UYVY frame. Also calculate how many * bytes in the UYVY file are needed to represent a single master block. */ UYVYRowLength = 32 * mbSizeX; UYVYMbSize = 32 * 16; /* * Copy the reconstructed buffer information into a UYVY frame. */ for (i = 0; i < mbSizeX; i++) { for (j = 0; j < mbSizeY; j++) { /* Calculate input and output buffer offsets for the current */ /* master block */ curr_lum_mb = lum_buf + (lumaColLength * i) + (256 * j); curr_chroma_mb = chr_buf + (chromaColSize * i) + (128 * j); curr_mb = (UInt8 *) Buffer_getUserPtr(hDstBuf) + (j * (UYVYMbSize * mbSizeX)) + (i * 32); /* Copy Luma information */ for (k = 0; k < 16; k++) { for (l = 0; l < 16; l++) { curr_mb[(k * UYVYRowLength) + (l * 2) + 1] = curr_lum_mb[k * 16 + l]; } } /* Copy Chroma information */ for (k = 0; k < 8; k++) { for (l = 0; l < 16; l++) { curr_mb[((k * 2) * UYVYRowLength) + (l * 2)] = curr_chroma_mb[k * 16 + l]; curr_mb[((k * 2 + 1) * UYVYRowLength) + (l * 2)] = curr_chroma_mb[k * 16 + l]; } } } } Buffer_setNumBytesUsed(hDstBuf, dim.width * dim.height * 2); }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
/****************************************************************************** * appMain ******************************************************************************/ Void appMain(Args * args) { Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Time_Attrs tAttrs = Time_Attrs_DEFAULT; SPHENC1_Params params = Senc1_Params_DEFAULT; SPHENC1_DynamicParams dynParams = Senc1_DynamicParams_DEFAULT; Senc1_Handle hSe1 = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; Buffer_Handle hInBuf = NULL; Time_Handle hTime = NULL; FILE *inFile = NULL; FILE *outFile = NULL; Int numFrame = 0; Int32 bytesRead; UInt32 time; printf("Starting application...\n"); if (args->benchmark) { hTime = Time_create(&tAttrs); if (hTime == NULL) { printf("Failed to create Time object\n"); goto cleanup; } } /* Initialize the codec engine run time */ CERuntime_init(); /* Initialize DMAI */ Dmai_init(); /* Open the output file */ outFile = fopen(args->outFile, "wb"); if (outFile == NULL) { printf("Failed to create output file %s\n", args->outFile); goto cleanup; } /* Open the input file */ inFile = fopen(args->inFile, "rb"); if (inFile == NULL) { printf("Failed to open input file %s\n", args->inFile); goto cleanup; } /* Using a larger vbuf to enhance performance of file i/o */ if (setvbuf(outFile, vbuffer, _IOFBF, sizeof(vbuffer)) != 0) { printf("Failed to setvbuf on file descriptor\n"); goto cleanup; } /* Open the codec engine */ hEngine = Engine_open(args->engineName, NULL, NULL); if (hEngine == NULL) { printf("Failed to open codec engine %s\n", args->engineName); goto cleanup; } params.compandingLaw = args->compandingLaw; /* Create the SPHENC1 based speech encoder */ hSe1 = Senc1_create(hEngine, args->codecName, ¶ms, &dynParams); if (hSe1 == NULL) { printf("Failed to create %s\n", args->codecName); goto cleanup; } /* Align buffers to cache line boundary */ bAttrs.memParams.align = BUFSIZEALIGN; /* Use cached buffers if requested */ if (args->cache) { bAttrs.memParams.flags = Memory_CACHED; } /* Create an output buffer for encoded data */ hOutBuf = Buffer_create( Dmai_roundUp(Senc1_getOutBufSize(hSe1), BUFSIZEALIGN), &bAttrs); if (hOutBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } /* Create an input buffer for input data */ hInBuf = Buffer_create(Dmai_roundUp(Senc1_getInBufSize(hSe1), BUFSIZEALIGN), &bAttrs); if (hInBuf == NULL) { printf("Failed to create contiguous buffer\n"); goto cleanup; } while (numFrame++ < args->numFrames) { printf("Frame %d: ", numFrame); if (args->benchmark) { if (Time_reset(hTime) < 0) { printf("Failed to reset timer\n"); goto cleanup; } } /* Read raw PCM data from input file */ bytesRead = fread(Buffer_getUserPtr(hInBuf), 1, Senc1_getInBufSize(hSe1), inFile); if (bytesRead < Senc1_getInBufSize(hSe1)) { if (ferror(inFile)) { printf("Failed to read data from input file\n"); goto cleanup; } printf("Failed to read full frame %ld bytes, read %ld bytes\n", Senc1_getInBufSize(hSe1),bytesRead); goto cleanup; } Buffer_setNumBytesUsed(hInBuf, bytesRead); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Read: %uus ", (Uns) time); } 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) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Pre-process cache maintenance: %uus ", (Uns) time); } } /* Encode the speech buffer */ if (Senc1_process(hSe1, hInBuf, hOutBuf) < 0) { printf("Failed to encode speech buffer\n"); goto cleanup; } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Encode: %uus ", (Uns) time); } if (args->cache) { /* Writeback the outBuf. */ Memory_cacheWb(Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Post-process cache write back: %uus ", (Uns) time); } } printf("Write encoded speech data to output file \n"); /* Write the encoded frame to the file system */ if (Buffer_getNumBytesUsed(hOutBuf)) { if (fwrite(Buffer_getUserPtr(hOutBuf), Buffer_getNumBytesUsed(hOutBuf), 1, outFile) != 1) { printf("Failed to write encoded speech data to file\n"); goto cleanup; } } if (args->benchmark) { if (Time_delta(hTime, &time) < 0) { printf("Failed to get timer delta\n"); goto cleanup; } printf("Write: %uus ", (Uns) time); if (Time_total(hTime, &time) < 0) { printf("Failed to get timer total\n"); goto cleanup; } printf("Total: %uus\n", (unsigned int)time); } } cleanup: /* Clean up the application */ if (hSe1) { Senc1_delete(hSe1); } 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"); return; }
/****************************************************************************** * _Dmai_v4l2DriverAlloc ******************************************************************************/ Int _Dmai_v4l2DriverAlloc(Int fd, Int numBufs, enum v4l2_buf_type type, struct _VideoBufDesc **bufDescsPtr, BufTab_Handle *hBufTabPtr, Int topOffset, ColorSpace_Type colorSpace) { BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; struct v4l2_requestbuffers req; struct v4l2_format fmt; _VideoBufDesc *bufDesc; Buffer_Handle hBuf; Int bufIdx; Int8 *virtPtr; Dmai_clear(fmt); fmt.type = type; if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) { Dmai_err1("VIDIOC_G_FMT failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } Dmai_clear(req); req.count = numBufs; req.type = type; req.memory = V4L2_MEMORY_MMAP; /* Allocate buffers in the capture device driver */ if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { Dmai_err1("VIDIOC_REQBUFS failed (%s)\n", strerror(errno)); return Dmai_ENOMEM; } if (req.count < numBufs || !req.count) { Dmai_err0("Insufficient device driver buffer memory\n"); return Dmai_ENOMEM; } /* Allocate space for buffer descriptors */ *bufDescsPtr = calloc(numBufs, sizeof(_VideoBufDesc)); if (*bufDescsPtr == NULL) { Dmai_err0("Failed to allocate space for buffer descriptors\n"); return Dmai_ENOMEM; } gfxAttrs.dim.width = fmt.fmt.pix.width; gfxAttrs.dim.height = fmt.fmt.pix.height; gfxAttrs.dim.lineLength = fmt.fmt.pix.bytesperline; gfxAttrs.colorSpace = colorSpace; gfxAttrs.bAttrs.reference = TRUE; *hBufTabPtr = BufTab_create(numBufs, fmt.fmt.pix.sizeimage, BufferGfx_getBufferAttrs(&gfxAttrs)); if (*hBufTabPtr == NULL) { return Dmai_ENOMEM; } for (bufIdx = 0; bufIdx < numBufs; bufIdx++) { bufDesc = &(*bufDescsPtr)[bufIdx]; /* Ask for information about the driver buffer */ Dmai_clear(bufDesc->v4l2buf); bufDesc->v4l2buf.type = type; bufDesc->v4l2buf.memory = V4L2_MEMORY_MMAP; bufDesc->v4l2buf.index = bufIdx; if (ioctl(fd, VIDIOC_QUERYBUF, &bufDesc->v4l2buf) == -1) { Dmai_err1("Failed VIDIOC_QUERYBUF (%s)\n", strerror(errno)); return Dmai_EFAIL; } /* Map the driver buffer to user space */ virtPtr = mmap(NULL, bufDesc->v4l2buf.length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, bufDesc->v4l2buf.m.offset) + topOffset; if (virtPtr == MAP_FAILED) { Dmai_err1("Failed to mmap buffer (%s)\n", strerror(errno)); return Dmai_EFAIL; } /* Initialize the Buffer with driver buffer information */ hBuf = BufTab_getBuf(*hBufTabPtr, bufIdx); Buffer_setNumBytesUsed(hBuf, fmt.fmt.pix.bytesperline * fmt.fmt.pix.height); Buffer_setUseMask(hBuf, gfxAttrs.bAttrs.useMask); Buffer_setUserPtr(hBuf, virtPtr); /* Initialize buffer to black */ _Dmai_blackFill(hBuf); Dmai_dbg3("Driver buffer %d mapped to %#x has physical address " "%#lx\n", bufIdx, (Int) virtPtr, Buffer_getPhysicalPtr(hBuf)); bufDesc->hBuf = hBuf; /* Queue buffer in device driver */ if (ioctl(fd, VIDIOC_QBUF, &bufDesc->v4l2buf) == -1) { Dmai_err1("VIODIOC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } } return Dmai_EOK; }
/****************************************************************************** * _Dmai_v4l2UserAlloc ******************************************************************************/ Int _Dmai_v4l2UserAlloc(Int fd, Int numBufs, enum v4l2_buf_type type, struct _VideoBufDesc **bufDescsPtr, BufTab_Handle hBufTab, Int topOffset, ColorSpace_Type colorSpace, Int queueBuffers) { struct v4l2_requestbuffers req; struct v4l2_format fmt; _VideoBufDesc *bufDesc; Buffer_Handle hBuf; Int bufIdx; Dmai_clear(fmt); fmt.type = type; if (ioctl(fd, VIDIOC_G_FMT, &fmt) == -1) { Dmai_err1("VIDIOC_G_FMT failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } if (Buffer_getSize(BufTab_getBuf(hBufTab, 0)) < fmt.fmt.pix.width * fmt.fmt.pix.height * 2) { Dmai_err0("Supplied buffers not large enough for video standard\n"); return Dmai_EINVAL; } /* Set the actual size of the buffers allocated */ fmt.type = type; fmt.fmt.pix.sizeimage = Buffer_getSize(BufTab_getBuf(hBufTab, 0)); fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY; fmt.fmt.pix.bytesperline = fmt.fmt.pix.width; if (ioctl(fd, VIDIOC_S_FMT, &fmt) == -1) { Dmai_err1("VIDIOC_S_FMT failed (%s)\n", strerror(errno)); return Dmai_EIO; } /* * Tell the driver that we will use user allocated buffers, but don't * allocate any buffers in the driver (just the internal descriptors). */ Dmai_clear(req); req.type = type; req.count = numBufs; req.memory = V4L2_MEMORY_USERPTR; if (ioctl(fd, VIDIOC_REQBUFS, &req) == -1) { Dmai_err0("Could not allocate video display buffers\n"); return Dmai_ENOMEM; } /* The driver may return less buffers than requested */ if (req.count < numBufs || !req.count) { Dmai_err0("Insufficient device driver buffer memory\n"); return Dmai_ENOMEM; } /* Allocate space for buffer descriptors */ *bufDescsPtr = calloc(numBufs, sizeof(_VideoBufDesc)); if (*bufDescsPtr == NULL) { Dmai_err0("Failed to allocate space for buffer descriptors\n"); return Dmai_ENOMEM; } for (bufIdx = 0; bufIdx < numBufs; bufIdx++) { bufDesc = &(*bufDescsPtr)[bufIdx]; hBuf = BufTab_getBuf(hBufTab, bufIdx); if (hBuf == NULL) { Dmai_err0("Failed to get buffer from BufTab for display\n"); return Dmai_ENOMEM; } if (Buffer_getType(hBuf) != Buffer_Type_GRAPHICS) { Dmai_err0("Buffer supplied to Display not a Graphics buffer\n"); return Dmai_EINVAL; } Dmai_clear(bufDesc->v4l2buf); bufDesc->v4l2buf.index = bufIdx; bufDesc->v4l2buf.type = type; bufDesc->v4l2buf.memory = V4L2_MEMORY_USERPTR; bufDesc->v4l2buf.m.userptr = (UInt32) Buffer_getUserPtr(hBuf); bufDesc->v4l2buf.length = (fmt.fmt.pix.sizeimage + 4096) & (~0xFFF); bufDesc->hBuf = hBuf; bufDesc->used = (queueBuffers == FALSE) ? TRUE : FALSE; /* If queueBuffers is TRUE, initialize the buffers to black and queue * them into the driver. */ if (queueBuffers == TRUE) { Buffer_setNumBytesUsed(hBuf, Buffer_getSize(hBuf)); _Dmai_blackFill(hBuf); /* Queue buffer in device driver */ if (ioctl(fd, VIDIOC_QBUF, &bufDesc->v4l2buf) == -1) { Dmai_err1("VIODIC_QBUF failed (%s)\n", strerror(errno)); return Dmai_EFAIL; } } } return Dmai_EOK; }
/***************************************************************************** * gst_tidmaiaccel_prepare_output_buffer * Function is used to allocate output buffer *****************************************************************************/ static GstFlowReturn gst_tidmaiaccel_prepare_output_buffer (GstBaseTransform *trans, GstBuffer *inBuf, gint size, GstCaps *caps, GstBuffer **outBuf) { GstTIDmaiaccel *dmaiaccel = GST_TIDMAIACCEL(trans); Buffer_Handle hOutBuf; Bool isContiguous = FALSE; UInt32 phys = 0; /* Always check if the buffer is contiguous */ phys = Memory_getBufferPhysicalAddress( GST_BUFFER_DATA(inBuf), GST_BUFFER_SIZE(inBuf), &isContiguous); if (isContiguous && dmaiaccel->width){ GST_DEBUG("Is contiguous video buffer"); Memory_registerContigBuf((UInt32)GST_BUFFER_DATA(inBuf), GST_BUFFER_SIZE(inBuf),phys); /* This is a contiguous buffer, create a dmai buffer transport */ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; gfxAttrs.bAttrs.reference = TRUE; gfxAttrs.dim.width = dmaiaccel->width; gfxAttrs.dim.height = dmaiaccel->height; gfxAttrs.colorSpace = dmaiaccel->colorSpace; gfxAttrs.dim.lineLength = dmaiaccel->lineLength; hOutBuf = Buffer_create(GST_BUFFER_SIZE(inBuf), &gfxAttrs.bAttrs); BufferGfx_setDimensions(hOutBuf,&gfxAttrs.dim); BufferGfx_setColorSpace(hOutBuf,gfxAttrs.colorSpace); Buffer_setUserPtr(hOutBuf, (Int8*)GST_BUFFER_DATA(inBuf)); Buffer_setNumBytesUsed(hOutBuf, GST_BUFFER_SIZE(inBuf)); *outBuf = gst_tidmaibuffertransport_new(hOutBuf, NULL, NULL, FALSE); gst_buffer_set_data(*outBuf, (guint8*) Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); gst_buffer_copy_metadata(*outBuf,inBuf,GST_BUFFER_COPY_ALL); gst_buffer_set_caps(*outBuf, GST_PAD_CAPS(trans->srcpad)); /* We need to grab a reference to the input buffer since we have * a pointer to his buffer */ gst_buffer_ref(inBuf); gst_tidmaibuffertransport_set_release_callback( (GstTIDmaiBufferTransport *)*outBuf, dmaiaccel_release_cb,inBuf); return GST_FLOW_OK; } else { GST_DEBUG("Copying into contiguous video buffer"); /* This is a contiguous buffer, create a dmai buffer transport */ if (!dmaiaccel->bufTabAllocated){ /* Initialize our buffer tab */ BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; gfxAttrs.dim.width = dmaiaccel->width; gfxAttrs.dim.height = dmaiaccel->height; gfxAttrs.colorSpace = dmaiaccel->colorSpace; gfxAttrs.dim.lineLength = dmaiaccel->lineLength; dmaiaccel->hOutBufTab = BufTab_create(2, GST_BUFFER_SIZE(inBuf), BufferGfx_getBufferAttrs(&gfxAttrs)); pthread_mutex_init(&dmaiaccel->bufTabMutex, NULL); pthread_cond_init(&dmaiaccel->bufTabCond, NULL); if (dmaiaccel->hOutBufTab == NULL) { GST_ELEMENT_ERROR(dmaiaccel,RESOURCE,NO_SPACE_LEFT,(NULL), ("failed to create output buffer tab")); return GST_FLOW_ERROR; } dmaiaccel->bufTabAllocated = TRUE; } pthread_mutex_lock(&dmaiaccel->bufTabMutex); hOutBuf = BufTab_getFreeBuf(dmaiaccel->hOutBufTab); if (hOutBuf == NULL) { GST_INFO("Failed to get free buffer, waiting on bufTab\n"); pthread_cond_wait(&dmaiaccel->bufTabCond, &dmaiaccel->bufTabMutex); hOutBuf = BufTab_getFreeBuf(dmaiaccel->hOutBufTab); if (hOutBuf == NULL) { GST_ELEMENT_ERROR(dmaiaccel,RESOURCE,NO_SPACE_LEFT,(NULL), ("failed to get a free contiguous buffer from BufTab")); pthread_mutex_unlock(&dmaiaccel->bufTabMutex); return GST_FLOW_ERROR; } } pthread_mutex_unlock(&dmaiaccel->bufTabMutex); memcpy(Buffer_getUserPtr(hOutBuf),GST_BUFFER_DATA(inBuf), GST_BUFFER_SIZE(inBuf)); Buffer_setNumBytesUsed(hOutBuf, GST_BUFFER_SIZE(inBuf)); *outBuf = gst_tidmaibuffertransport_new(hOutBuf, &dmaiaccel->bufTabMutex, &dmaiaccel->bufTabCond, FALSE); gst_buffer_set_data(*outBuf, (guint8*) Buffer_getUserPtr(hOutBuf), Buffer_getSize(hOutBuf)); gst_buffer_copy_metadata(*outBuf,inBuf,GST_BUFFER_COPY_ALL); gst_buffer_set_caps(*outBuf, GST_PAD_CAPS(trans->srcpad)); return GST_FLOW_OK; } }
/****************************************************************************** * speechThrFxn ******************************************************************************/ Void *speechThrFxn(Void *arg) { SpeechEnv *envp = (SpeechEnv *) arg; SPHDEC1_Params defaultParams = Sdec1_Params_DEFAULT; SPHDEC1_DynamicParams defaultDynParams = Sdec1_DynamicParams_DEFAULT; Void *status = THREAD_SUCCESS; Sound_Attrs sAttrs = Sound_Attrs_MONO_DEFAULT; Loader_Attrs lAttrs = Loader_Attrs_DEFAULT; Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; Sdec1_Handle hSd1 = NULL; Sound_Handle hSound = NULL; Loader_Handle hLoader = NULL; Engine_Handle hEngine = NULL; Buffer_Handle hOutBuf = NULL; SPHDEC1_Params *params; SPHDEC1_DynamicParams *dynParams; Buffer_Handle hInBuf; /* Open the codec engine */ hEngine = Engine_open(envp->engineName, NULL, NULL); if (hEngine == NULL) { ERR("Failed to open codec engine %s\n", envp->engineName); cleanup(THREAD_FAILURE); } /* Create the sound device */ sAttrs.sampleRate = 8000; sAttrs.mode = Sound_Mode_OUTPUT; sAttrs.leftGain = 127; sAttrs.rightGain = 127; sAttrs.bufSize = 128; hSound = Sound_create(&sAttrs); if (hSound == NULL) { ERR("Failed to create audio device\n"); cleanup(THREAD_FAILURE); } /* Set the sample rate for the user interface */ gblSetSamplingFrequency(sAttrs.sampleRate); /* Use supplied params if any, otherwise use defaults */ params = envp->params ? envp->params : &defaultParams; dynParams = envp->dynParams ? envp->dynParams : &defaultDynParams; /* Create the speech decoder */ hSd1 = Sdec1_create(hEngine, envp->speechDecoder, params, dynParams); if (hSd1 == NULL) { ERR("Failed to create speech decoder: %s\n", envp->speechDecoder); cleanup(THREAD_FAILURE); } /* * Make the output buffer size twice the size of what the codec needs * as the codec needs mono and the Sound module converts the decoded * mono samples to stereo before writing to the device driver. */ hOutBuf = Buffer_create(OUTBUFSIZE, &bAttrs); if (hOutBuf == NULL) { ERR("Failed to allocate output buffer\n"); cleanup(THREAD_FAILURE); } /* How much encoded data to feed the codec each process call */ lAttrs.readSize = INBUFSIZE; /* Make the total ring buffer larger */ lAttrs.readBufSize = lAttrs.readSize * 512; /* Create the file loader for reading encoded data */ hLoader = Loader_create(envp->speechFile, &lAttrs); if (hLoader == NULL) { ERR("Failed to create loader\n"); cleanup(THREAD_FAILURE); } /* Signal that initialization is done and wait for other threads */ Rendezvous_meet(envp->hRendezvousInit); /* Prime the file loader */ Loader_prime(hLoader, &hInBuf); while (!gblGetQuit()) { /* Pause processing? */ Pause_test(envp->hPauseProcess); /* Decode the audio buffer */ if (Sdec1_process(hSd1, hInBuf, hOutBuf) < 0) { ERR("Failed to decode audio buffer\n"); cleanup(THREAD_FAILURE); } /* Increment statistics for user interface */ gblIncSoundBytesProcessed(Buffer_getNumBytesUsed(hInBuf)); /* * Force the output buffer size since we are forcing the size of the * output buffer allocated as opposed to asking the codec for a size. */ Buffer_setNumBytesUsed(hOutBuf, OUTBUFSIZE); /* Write the decoded samples to the sound device */ if (Sound_write(hSound, hOutBuf) < 0) { ERR("Failed to write audio buffer\n"); cleanup(THREAD_FAILURE); } /* Load a new frame from the file system */ if (Loader_getFrame(hLoader, hInBuf) < 0) { ERR("Failed to read a frame of encoded data\n"); cleanup(THREAD_FAILURE); } /* Check if the clip has ended */ if (Buffer_getUserPtr(hInBuf) == NULL) { /* Wait for the video clip to finish, if applicable */ Rendezvous_meet(envp->hRendezvousLoop); /* If we are to loop the clip, start over */ if (envp->loop) { /* Recreate the speech codec */ Sdec1_delete(hSd1); hSd1 = Sdec1_create(hEngine, envp->speechDecoder, params, dynParams); if (hSd1 == NULL) { ERR("Failed to create speech decoder: %s\n", envp->speechDecoder); cleanup(THREAD_FAILURE); } /* Re-prime the file loader */ Loader_prime(hLoader, &hInBuf); } else { printf("End of clip reached, exiting..\n"); cleanup(THREAD_SUCCESS); } } } cleanup: /* Make sure the other threads aren't waiting for us */ Rendezvous_force(envp->hRendezvousInit); Rendezvous_force(envp->hRendezvousLoop); Pause_off(envp->hPauseProcess); /* Meet up with other threads before cleaning up */ Rendezvous_meet(envp->hRendezvousCleanup); /* Clean up the thread before exiting */ if (hLoader) { Loader_delete(hLoader); } if (hSd1) { Sdec1_delete(hSd1); } if (hSound) { Sound_delete(hSound); } if (hOutBuf) { Buffer_delete(hOutBuf); } if (hEngine) { Engine_close(hEngine); } return status; }
/****************************************************************************** * 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; }
/****************************************************************************** * gst_ticircbuffer_get_data ******************************************************************************/ GstBuffer* gst_ticircbuffer_get_data(GstTICircBuffer *circBuf) { Buffer_Handle hCircBufWindow; Buffer_Attrs bAttrs; GstBuffer *result; Int32 bufSize; if (circBuf == NULL) { return NULL; } /* Reset our mutex condition so calling wait_on_consumer will block */ Rendezvous_reset(circBuf->waitOnProducer); /* Reset the read pointer to the beginning of the buffer when we're * approaching the buffer's end (see function definition for reset * conditions). */ gst_ticircbuffer_reset_read_pointer(circBuf); /* Don't return any data util we have a full window available */ while (!circBuf->drain && !gst_ticircbuffer_window_available(circBuf)) { GST_LOG("blocking output until a full window is available\n"); gst_ticircbuffer_wait_on_producer(circBuf); GST_LOG("unblocking output\n"); gst_ticircbuffer_reset_read_pointer(circBuf); /* Reset our mutex condition so calling wait_on_consumer will block */ Rendezvous_reset(circBuf->waitOnProducer); } /* Set the size of the buffer to be no larger than the window size. Some * audio codecs have an issue when you pass a buffer larger than 64K. * We need to pass it smaller buffer sizes though, as the EOS is detected * when we return a 0 size buffer. */ bufSize = gst_ticircbuffer_data_available(circBuf); if (bufSize > circBuf->windowSize) { bufSize = circBuf->windowSize; } /* Return a reference buffer that points to the area of the circular * buffer we want to decode. */ Buffer_getAttrs(circBuf->hBuf, &bAttrs); bAttrs.reference = TRUE; hCircBufWindow = Buffer_create(bufSize, &bAttrs); Buffer_setUserPtr(hCircBufWindow, circBuf->readPtr); Buffer_setNumBytesUsed(hCircBufWindow, bufSize); GST_LOG("returning data at offset %u\n", circBuf->readPtr - Buffer_getUserPtr(circBuf->hBuf)); result = (GstBuffer*)(gst_tidmaibuffertransport_new(hCircBufWindow, NULL)); GST_BUFFER_TIMESTAMP(result) = circBuf->dataTimeStamp; GST_BUFFER_DURATION(result) = GST_CLOCK_TIME_NONE; return result; }
/****************************************************************************** * 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; }
/****************************************************************************** * 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; }
Void *deiThrFxn(Void *arg) { DeiEnv *envp = (DeiEnv *) arg; Void *status = THREAD_SUCCESS; Uint32 sysRegBase = 0; VIDENC1_Handle hDei = NULL; IDEI_Params deiParams; Uint16 frame_width = 0, frame_height = 0; Uint16 threshold_low = 0, threshold_high = 0; IVIDEO1_BufDescIn inBufDesc; XDM_BufDesc outBufDesc; XDAS_Int8 *outbufs[2]; XDAS_Int32 outBufSizeArray[2]; VIDENC1_InArgs inArgs; IDEI_OutArgs outArgs; Uint32 bufferSize; CMEM_AllocParams cmemPrm; Uint32 prevBufAddr, outBufAddr; Buffer_Handle cBuf, dBuf; Int ret = 0; int fd = -1; dm365mmap_params_t dm365mmap_params; pthread_mutex_t Dmai_DM365dmaLock = PTHREAD_MUTEX_INITIALIZER; /* ▼▼▼▼▼ Initialization ▼▼▼▼▼ */ DM365MM_init(); printf("\n"); /* dm365mm issue */ sysRegBase = DM365MM_mmap(0x01C40000, 0x4000); CMEM_init(); cmemPrm.type = CMEM_HEAP; cmemPrm.flags = CMEM_NONCACHED; cmemPrm.alignment = 32; prevBufAddr = (Uint32)CMEM_alloc(IN_OUT_BUF_SIZE, &cmemPrm); outBufAddr = (Uint32)CMEM_alloc(IN_OUT_BUF_SIZE, &cmemPrm); frame_width = 720; frame_height = 576; threshold_low = 16; threshold_high = 20; /* Create DEI instance */ deiParams.videncParams.size = sizeof(IDEI_Params); deiParams.frameHeight = frame_height; deiParams.frameWidth = frame_width; deiParams.inLineOffset = frame_width; deiParams.outLineOffset = (frame_width - 8); deiParams.threshold_low = threshold_low; deiParams.threshold_high = threshold_high; deiParams.inputFormat = XDM_YUV_422ILE; deiParams.outputFormat = XDM_YUV_420SP; deiParams.q_num = 1; deiParams.askIMCOPRes = 0; deiParams.sysBaseAddr = sysRegBase; hDei = VIDENC1_create(envp->hEngine, "dei", (VIDENC1_Params *)&deiParams); if(hDei == NULL) { ERR("DEI alg creation failed\n"); cleanup(THREAD_FAILURE); } fd = open("/dev/dm365mmap", O_RDWR | O_SYNC); Rendezvous_meet(envp->hRendezvousInit); /* ▲▲▲▲▲ Initialization ▲▲▲▲▲ */ while (1) { if (Fifo_get(envp->hFromCaptureFifo, &cBuf) < 0) { ERR("Failed to get buffer from capture thread\n"); cleanup(THREAD_FAILURE); } if (Fifo_get(envp->hFromDisplayFifo, &dBuf) < 0) { ERR("Failed to get buffer from display thread\n"); cleanup(THREAD_FAILURE); } inBufDesc.numBufs = 4; bufferSize = (frame_width * frame_height); inBufDesc.bufDesc[0].bufSize = bufferSize; inBufDesc.bufDesc[0].buf = (XDAS_Int8 *)Buffer_getUserPtr(cBuf); inBufDesc.bufDesc[0].accessMask = 0; inBufDesc.bufDesc[1].bufSize = bufferSize; inBufDesc.bufDesc[1].buf = (XDAS_Int8 *)(Buffer_getUserPtr(cBuf) + bufferSize); inBufDesc.bufDesc[1].accessMask = 0; inBufDesc.bufDesc[2].bufSize = bufferSize; inBufDesc.bufDesc[2].buf = (XDAS_Int8 *)prevBufAddr; inBufDesc.bufDesc[2].accessMask = 0; inBufDesc.bufDesc[3].bufSize = bufferSize; inBufDesc.bufDesc[3].buf = (XDAS_Int8 *)(prevBufAddr + bufferSize); inBufDesc.bufDesc[3].accessMask = 0; /* Output buffers */ outBufDesc.numBufs = 2; outbufs[0] = (XDAS_Int8*)outBufAddr; outbufs[1] = (XDAS_Int8*)(outBufAddr + bufferSize); outBufSizeArray[0] = bufferSize; outBufSizeArray[1] = bufferSize / 2; outBufDesc.bufSizes = outBufSizeArray; outBufDesc.bufs = outbufs; inArgs.size = sizeof(VIDENC1_InArgs); outArgs.videncOutArgs.size = sizeof(IDEI_OutArgs); ret = VIDENC1_process((VIDENC1_Handle)hDei, &inBufDesc, &outBufDesc, &inArgs, (IVIDENC1_OutArgs *)&outArgs); if (ret != VIDENC1_EOK) { ERR("DEI process failed\n"); cleanup(THREAD_FAILURE); } dm365mmap_params.src = CMEM_getPhys(outbufs[0]); dm365mmap_params.srcmode = 0; dm365mmap_params.dst = Buffer_getPhysicalPtr(dBuf); dm365mmap_params.dstmode = 0; dm365mmap_params.srcbidx = 712; dm365mmap_params.dstbidx = 704; dm365mmap_params.acnt = 704; dm365mmap_params.bcnt = 576; dm365mmap_params.ccnt = 1; dm365mmap_params.bcntrld = dm365mmap_params.bcnt; dm365mmap_params.syncmode = 1; pthread_mutex_lock(&Dmai_DM365dmaLock); if (ioctl(fd, DM365MMAP_IOCMEMCPY, &dm365mmap_params) == -1) { ERR("memcpy: Failed to do memcpy\n"); cleanup(THREAD_FAILURE); } pthread_mutex_unlock(&Dmai_DM365dmaLock); dm365mmap_params.src = CMEM_getPhys(outbufs[1]); dm365mmap_params.srcmode = 0; dm365mmap_params.dst = Buffer_getPhysicalPtr(dBuf) + (Buffer_getSize(dBuf) * 2 / 3); dm365mmap_params.dstmode = 0; dm365mmap_params.srcbidx = 712; dm365mmap_params.dstbidx = 704; dm365mmap_params.acnt = 712; dm365mmap_params.bcnt = 570 / 2; dm365mmap_params.ccnt = 1; dm365mmap_params.bcntrld = dm365mmap_params.bcnt; dm365mmap_params.syncmode = 1; pthread_mutex_lock(&Dmai_DM365dmaLock); if (ioctl(fd, DM365MMAP_IOCMEMCPY, &dm365mmap_params) == -1) { ERR("memcpy: Failed to do memcpy\n"); cleanup(THREAD_FAILURE); } pthread_mutex_unlock(&Dmai_DM365dmaLock); Buffer_setNumBytesUsed(dBuf, 704 * 576 * 3 / 2); dm365mmap_params.src = Buffer_getPhysicalPtr(cBuf); dm365mmap_params.srcmode = 0; dm365mmap_params.dst = prevBufAddr; dm365mmap_params.dstmode = 0; dm365mmap_params.srcbidx = 1440; dm365mmap_params.dstbidx = 1440; dm365mmap_params.acnt = 1440; dm365mmap_params.bcnt = 576; dm365mmap_params.ccnt = 1; dm365mmap_params.bcntrld = dm365mmap_params.bcnt; dm365mmap_params.syncmode = 1; pthread_mutex_lock(&Dmai_DM365dmaLock); if (ioctl(fd, DM365MMAP_IOCMEMCPY, &dm365mmap_params) == -1) { ERR("memcpy: Failed to do memcpy\n"); cleanup(THREAD_FAILURE); } pthread_mutex_unlock(&Dmai_DM365dmaLock); /* Send buffer to display thread */ if (Fifo_put(envp->hToDisplayFifo, dBuf) < 0) { ERR("Failed to send buffer to dei thread\n"); cleanup(THREAD_FAILURE); } /* Send buffer to display thread */ if (Fifo_put(envp->hToCaptureFifo, cBuf) < 0) { ERR("Failed to send buffer to dei thread\n"); cleanup(THREAD_FAILURE); } } cleanup: Rendezvous_force(envp->hRendezvousInit); Rendezvous_meet(envp->hRendezvousCleanup); /* Delete DEI ALG instance */ VIDENC1_delete(hDei); DM365MM_ummap(sysRegBase,0x4000); DM365MM_exit(); if (fd > 0) { close(fd); } return status; }