This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

h264 decoder fails to display decoded frames on lcd

Other Parts Discussed in Thread: OMAP3530, DM3730, OMAPL138

hi,

i am using dvsdk_dm368-evm_4_02_00_06  with latest h264 codecs i:e H.264 Encoder, Version 2.30.00.06 & H.264 Decoder, Version 2.00.00.13  

I tried to make a application for realtime H264 encode and decode by using TI dmai  video_loopback  api as a reference. integrated H264 encode and decode api's into video_loopback api which works fine i can able to encode yuv420sp  frames comming from capture driver  and write it to filesystem the .h264 file plays sucessfully  on media player

Also i can able to decode the same file generated at the encoder side which i can able to see properly on 7yuv player 

 But When I try to display same decoded frames on lcd it shows fully  blurred image .

Does anyone can help me for this problem, please?   

 

here is  the code for decoder side which will decode and display on lcd 

This applications decodes an elementary stream video file using a specified
* codec to a raw yuv file.and will display the same on lcd 

 

 

#include <stdio.h>
#include <string.h>

#include <xdc/std.h>

#include <ti/sdo/ce/Engine.h>
#include <ti/sdo/ce/CERuntime.h>

#include <ti/sdo/dmai/Dmai.h>
#include <ti/sdo/dmai/Time.h>
#include <ti/sdo/dmai/Cpu.h>
#include <ti/sdo/dmai/BufTab.h>
#include <ti/sdo/dmai/Loader.h>
#include <ti/sdo/dmai/Display.h>
#include <ti/sdo/dmai/ColorSpace.h>
#include <ti/sdo/dmai/VideoStd.h>
#include <ti/sdo/dmai/ce/Vdec2.h>
#include <ti/sdo/dmai/BufferGfx.h>


#include <ti/sdo/dmai/Display.h>
#include <ti/sdo/dmai/Capture.h>


#define NUM_BUFS 3

#include "appMain.h"

/* Temporary compilation error fix for OMAP 3530.
Remove the definition when it uses CE 2.22 or later */
#ifdef Dmai_Device_omap3530
#define XDM_YUV_420SP 9
#endif

/* Align buffers to this cache line size (in bytes)*/
#define BUFSIZEALIGN 128

/* vbuf size that has been selected based on size/performance tradeoff */
#define VBUFSIZE 20480

static Char vbuffer[VBUFSIZE];

/* These definitions missing in some OS build environments (eg: WinCE) */
#ifndef _IOFBF
#define _IOFBF 0
#endif /* _IOFBF */
#ifndef _IOLBF
#define _IOLBF 1
#endif /* _IOLBF */
#ifndef _IONBF
#define _IONBF 2
#endif /* _IONBF */


Int ret = Dmai_EOK;


/******************************************************************************
* resizeBufTab
******************************************************************************/
Int resizeBufTab(Vdec2_Handle hVd2, Int displayBufs)
{
BufTab_Handle hBufTab = Vdec2_getBufTab(hVd2);
Int numBufs, numCodecBuffers, numExpBufs;
Buffer_Handle hBuf;
Int32 frameSize;

/* How many buffers can the codec keep at one time? */
numCodecBuffers = Vdec2_getMinOutBufs(hVd2);

if (numCodecBuffers < 0) {
fprintf(stderr, "Failed to get buffer requirements\n");
return -1;
}

/*
* Total number of frames needed are the number of buffers the codec
* can keep at any time, plus the number of frames in the display pipe.
*/
numBufs = numCodecBuffers + displayBufs;

/* Get the size of output buffers needed from codec */
frameSize = Vdec2_getOutBufSize(hVd2);

/*
* Get the first buffer of the BufTab to determine buffer characteristics.
* All buffers in a BufTab share the same characteristics.
*/
hBuf = BufTab_getBuf(hBufTab, 0);

/* Do we need to resize the BufTab? */
if (numBufs > BufTab_getNumBufs(hBufTab) ||
frameSize < Buffer_getSize(hBuf)) {

/* Should we break the current buffers in to many smaller buffers? */
if (frameSize < Buffer_getSize(hBuf)) {

/* First undo any previous chunking done */
BufTab_collapse(Vdec2_getBufTab(hVd2));

/*
* Chunk the larger buffers of the BufTab in to smaller buffers
* to accomodate the codec requirements.
*/
numExpBufs = BufTab_chunk(hBufTab, numBufs, frameSize);

if (numExpBufs < 0) {
fprintf(stderr, "Failed to chunk %d bufs size %d to %d bufsize %d\n",
BufTab_getNumBufs(hBufTab), (Int)Buffer_getSize(hBuf),
numBufs, (Int)frameSize);
return -1;
}

/*
* Did the current BufTab fit the chunked buffers,
* or do we need to expand the BufTab (numExpBufs > 0)?
*/
if (BufTab_expand(hBufTab, numExpBufs) < 0) {
fprintf(stderr, "Failed to expand BufTab with %d buffers\n",
numExpBufs);
return -1;
}
}
else {
/* Just expand the BufTab with more buffers */
if (BufTab_expand(hBufTab, numBufs - BufTab_getNumBufs(hBufTab)) < 0) {
fprintf(stderr,"Failed to expand BufTab with %d buffers\n",
numCodecBuffers);
return -1;
}
}
}

return numBufs;
}

/******************************************************************************
* writeFrame420P
******************************************************************************/
Int writeFrame420P(Buffer_Handle hBuf, FILE *outFile, Cpu_Device device)
{
Int8 *yPtr, *cbcrPtr;
UInt32 offset;
Int y, x;

BufferGfx_Dimensions dim;
BufferGfx_getDimensions(hBuf, &dim);

offset = dim.y * dim.lineLength + dim.x;

/* Write Y plane */
yPtr = Buffer_getUserPtr(hBuf) + offset;
for (y = 0; y < dim.height; y++) {
if (fwrite(yPtr, dim.width, 1, outFile) != 1) {
fprintf(stderr, "Failed to write data to disk\n");
return -1;
}

yPtr += dim.lineLength;
}

if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) {
offset = dim.y * dim.lineLength / 2 + dim.x;
} else {
/* *Default* Assume DM6467 behavior */
offset = dim.y * dim.lineLength + dim.x;
}

/* Separate Cb from CbCr interleaved and save Cb plane */
cbcrPtr = Buffer_getUserPtr(hBuf) + offset + 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) + offset + 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 420P frame size %d (%dx%d) to disk\n",
(Int) (dim.width * 3 / 2 * dim.height),
(Int) dim.width, (Int) dim.height);

return 0;
}

/******************************************************************************
* writeFrame420SP
******************************************************************************/
Int writeFrame420SP(Buffer_Handle hBuf,FILE *outFile,Cpu_Device device)//, FILE *outFile, Cpu_Device device)
{

Int8 *yPtr, *cbcrPtr;
UInt32 offset;
Int y;

BufferGfx_Dimensions dim;

//Int8 *dispbuf = Buffer_getUserPtr(dbuf);


#if 1


BufferGfx_getDimensions(hBuf, &dim);

offset = dim.y * dim.lineLength + dim.x;

/* Write Y plane */
yPtr = Buffer_getUserPtr(hBuf) + offset;
for (y = 0; y < dim.height; y++) {

if (fwrite(yPtr, dim.width, 1, outFile) != 1) {
fprintf(stderr, "Failed to write data to disk\n");
return -1;
}
// memcpy(dispbuf, yPtr,dim.width);
yPtr += dim.lineLength;
}

if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) {
offset = dim.y * dim.lineLength / 2 + dim.x;
} else {
/* *Default* Assume DM6467 behavior */
offset = dim.y * dim.lineLength + dim.x;
}

/* Separate Cb from CbCr interleaved */
cbcrPtr = Buffer_getUserPtr(hBuf) + offset + Buffer_getSize(hBuf) * 2 / 3;
for (y = 0; y < dim.height / 2; y++) {

if (fwrite(cbcrPtr, dim.width, 1, outFile) != 1) {
fprintf(stderr, "Failed to write data to disk\n");
return -1;
}
// memcpy(dispbuf,cbcrPtr,dim.width);
cbcrPtr += dim.lineLength;
}
/*
if (fwrite(dispbuf, 195840,1 , outFile) != 1) {
fprintf(stderr, "Failed to write data to disk\n");
return -1;
}
*/
printf("Wrote 420SP frame size %d (%dx%d) to disk\n",
(Int) (dim.width * 3 / 2 * dim.height),
(Int) dim.width, (Int) dim.height);


/* copy decoded image to display buffer
//Int8* outbuf = (Int8*)Buffer_getUserPtr(hBuf);

Int buf= Buffer_setUserPtr(dBuf,outbuf);
if(buf!=Dmai_EOK){
//ret = Dmai_EFAIL;
printf("Failed to set UserPtr\n");
return -1;
}
*/

#endif
return 0;

}

/******************************************************************************
* writeFrameUYVY
******************************************************************************/
Int writeFrameUYVY(Buffer_Handle hBuf, FILE *outFile)
{
Int8 *ptr;
UInt32 offset;
Int y;

BufferGfx_Dimensions dim;
BufferGfx_getDimensions(hBuf, &dim);

offset = dim.y * dim.lineLength + dim.x * 2;
ptr = Buffer_getUserPtr(hBuf) + offset;

for (y = 0; y < dim.height; y++) {
if (fwrite(ptr, dim.width * 2, 1, outFile) != 1) {
fprintf(stderr, "Failed to write data to disk\n");
return -1;
}

ptr += dim.lineLength;
}

printf("Wrote UYVY frame size %d (%dx%d) to disk\n",
(Int) (dim.width * 2 * dim.height),
(Int) dim.width, (Int) dim.height);

return 0;
}

/******************************************************************************
* appMain
******************************************************************************/
Int appMain(Args * args)
{
VIDDEC2_Params params = Vdec2_Params_DEFAULT;
VIDDEC2_DynamicParams dynParams = Vdec2_DynamicParams_DEFAULT;
Loader_Attrs lAttrs = Loader_Attrs_DEFAULT;
BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT;
Time_Attrs tAttrs = Time_Attrs_DEFAULT;
Vdec2_Handle hVd2 = NULL;
Loader_Handle hLoader = NULL;
Engine_Handle hEngine = NULL;
BufTab_Handle hBufTab = NULL;
Buffer_Handle hDstBuf = NULL;
Time_Handle hTime = NULL;
FILE *outFile = NULL;
Bool flushed = FALSE;
// Int ret = Dmai_EOK;
Int numFrame = 1;
Int numFrameDisp = 1;
Buffer_Handle hInBuf, hOutBuf, hFreeBuf;
ColorSpace_Type colorSpace;
Cpu_Device device;
Int numBufs;
UInt32 time;
BufferGfx_Dimensions dim;
Bool vc1Offset = FALSE;
Bool mpeg4Offset = FALSE;


BufferGfx_Attrs vfxAttrs = BufferGfx_Attrs_DEFAULT;
//Time_Attrs tAttrs = Time_Attrs_DEFAULT;
Display_Handle hDisplay = NULL;
// Capture_Handle hCapture = NULL;
BufTab_Handle BufTab = NULL;
//Time_Handle hTime = NULL;
//Int numFrame = 0;
Display_Attrs dAttrs;
Capture_Attrs cAttrs;
Buffer_Handle dBuf;
//VideoStd_Type videoStd;
//UInt32 time;
Int32 bufSize;
//Cpu_Device device;
// ColorSpace_Type colorSpace;
Int32 width, height, lineLength;
printf("Starting application...\n");

/* 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;
}

/* Initialize platform-specific settings */
if ((device == Cpu_Device_DM6467) ||
(device == Cpu_Device_DM365) ||
(device == Cpu_Device_DM368)) {
colorSpace = ColorSpace_YUV420PSEMI;
numBufs = 5;
}
else {
colorSpace = ColorSpace_UYVY;
numBufs = 2;
}

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();


/*###################### decoder initilization starts ##################*/

/* Open output file */
outFile = fopen(args->outFile, "wb");

if (outFile == NULL) {
fprintf(stderr,"Failed to create output file %s\n", args->outFile);
ret = Dmai_EFAIL;
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 up codec parameters depending on device */
if ((device == Cpu_Device_DM6467) ||
(device == Cpu_Device_DM365) ||
(device == Cpu_Device_DM368)) {
params.forceChromaFormat = XDM_YUV_420SP;
params.maxWidth = 480;//VideoStd_1080I_WIDTH;
params.maxHeight = 272+8;//VideoStd_1080I_HEIGHT + 8;
}
else if (device == Cpu_Device_DM3730) {
params.forceChromaFormat = XDM_YUV_422ILE;
params.maxWidth = VideoStd_720P_WIDTH;
params.maxHeight = VideoStd_720P_HEIGHT;
}
else {
params.forceChromaFormat = XDM_YUV_422ILE;
params.maxWidth = VideoStd_D1_WIDTH;
params.maxHeight = VideoStd_D1_PAL_HEIGHT;
}

if(device == Cpu_Device_DM6467) {
if (!strcmp(args->codecName, "mpeg4dec")) {
params.maxWidth = VideoStd_576P_WIDTH;
params.maxHeight = VideoStd_576P_HEIGHT;
mpeg4Offset = TRUE;
}
}

if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) {
if (!strcmp(args->codecName, "vc1dec")) {
vc1Offset = TRUE;
}
}

/* Create the XDM 1.2 based video decoder */
hVd2 = Vdec2_create(hEngine, args->codecName, &params, &dynParams);

if (hVd2 == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to create video decoder: %s\n", args->codecName);
goto cleanup;
}

/* Align buffers to cache line boundary */
gfxAttrs.bAttrs.memParams.align = lAttrs.mParams.align = BUFSIZEALIGN;

/* Use cached buffers if requested */
if (args->cache) {
gfxAttrs.bAttrs.memParams.flags = lAttrs.mParams.flags = Memory_CACHED;
}

gfxAttrs.colorSpace = colorSpace;
gfxAttrs.dim.width = params.maxWidth;
gfxAttrs.dim.height = params.maxHeight;
gfxAttrs.dim.lineLength = BufferGfx_calcLineLength(params.maxWidth,
colorSpace);

/* Create a table of output buffers of the size requested by the codec */
hBufTab = BufTab_create(numBufs,
Dmai_roundUp(Vdec2_getOutBufSize(hVd2), BUFSIZEALIGN),
BufferGfx_getBufferAttrs(&gfxAttrs));

if (hBufTab == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to allocate contiguous buffers\n");
goto cleanup;
}

/* Set output buffer table */
Vdec2_setBufTab(hVd2, hBufTab);

/* Ask the codec how much input data it needs */
lAttrs.readSize = Vdec2_getInBufSize(hVd2);

/* Make the total ring buffer larger */
lAttrs.readBufSize = Dmai_roundUp(lAttrs.readSize * 2, BUFSIZEALIGN);

/* Increase the stdio buffer size for loader for better RTDX performance */
lAttrs.vBufSize = VBUFSIZE;

/* Create the elementary stream file loader */
hLoader = Loader_create(args->inFile, &lAttrs);

if (hLoader == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr, "Failed to create loader\n");
goto cleanup;
}

/* Prime the file loader */
Loader_prime(hLoader, &hInBuf);


printf("Loader created and primed, entering main loop..\n");


/*********************************************************************************
// video loopback initilation
*********************************************************************************/
/* 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;
}

switch (device) {
case Cpu_Device_DM6467:
colorSpace = ColorSpace_YUV422PSEMI;
dAttrs = Display_Attrs_DM6467_VID_DEFAULT;
cAttrs = Capture_Attrs_DM6467_DEFAULT;
break;
case Cpu_Device_DM365:
case Cpu_Device_DM368:
colorSpace = ColorSpace_YUV420PSEMI;
dAttrs = Display_Attrs_DM365_VID_DEFAULT;
cAttrs = Capture_Attrs_DM365_DEFAULT;
cAttrs.videoInput = args->videoInput;
break;
case Cpu_Device_OMAPL138:
colorSpace = ColorSpace_YUV422PSEMI;
dAttrs = Display_Attrs_OMAPL138_VID_DEFAULT;
cAttrs = Capture_Attrs_OMAPL138_DEFAULT;
break;
case Cpu_Device_OMAP3530:
case Cpu_Device_DM3730:
colorSpace = ColorSpace_UYVY;
dAttrs = Display_Attrs_O3530_VID_DEFAULT;
cAttrs = Capture_Attrs_OMAP3530_DEFAULT;
dAttrs.rotation = 270;
break;
default:
colorSpace = ColorSpace_UYVY;
dAttrs = Display_Attrs_DM6446_DM355_VID_DEFAULT;
cAttrs = Capture_Attrs_DM6446_DM355_DEFAULT;
break;
}

if (args->benchmark) {
hTime = Time_create(&tAttrs);

if (hTime == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to create Time object\n");
goto cleanup;
}
}

//if (args->videoStd == VideoStd_AUTO) {
// /* Detect which video input is connected on the component input */
// if (Capture_detectVideoStd(NULL, &videoStd, &cAttrs) < 0) {
// ret = Dmai_EFAIL;
// fprintf(stderr,"Failed to detect input video standard, input connected?\n");
// goto cleanup;
// }
//}
//else {
// videoStd = args->videoStd;
//}

//if (VideoStd_getResolution(videoStd, &width, &height) < 0) {
// goto cleanup;
//}

width = 480;
height = 272;

lineLength = BufferGfx_calcLineLength(width, colorSpace);
if (lineLength < 0) {
goto cleanup;
}


fprintf(stderr,"K: Buffer linelength %d Width: %d \n\n\n",(int)lineLength,(int)width);

if ((device == Cpu_Device_DM365) || (device == Cpu_Device_DM368)) {
/* In DM365, the capture buffer lineLength need to be divisible by 32 */
lineLength = Dmai_roundUp(lineLength, 32);
}

if (colorSpace == ColorSpace_YUV422PSEMI) {
bufSize = lineLength * height * 2;
}
else if (colorSpace == ColorSpace_YUV420PSEMI) {
bufSize = lineLength * height * 3 / 2;
}
else {
bufSize = lineLength * height;
}

/* Calculate the dimensions of the video standard */
if (BufferGfx_calcDimensions(VideoStd_LCD_272, colorSpace, &vfxAttrs.dim) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to calculate dimensions for video driver buffers\n");
goto cleanup;
}

vfxAttrs.colorSpace = colorSpace;

/* Create a table of buffers to use with the capture and display drivers */
BufTab = BufTab_create(NUM_BUFS, bufSize,
BufferGfx_getBufferAttrs(&vfxAttrs));

if (BufTab == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to allocate contiguous buffers\n");
goto cleanup;
}

/* Create the display display driver instance */
dAttrs.numBufs = NUM_BUFS;
dAttrs.colorSpace = colorSpace;
dAttrs.videoStd = VideoStd_LCD_272; // Karol B
dAttrs.videoOutput = args->videoOutput;
hDisplay = Display_create(BufTab, &dAttrs);

if (hDisplay == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to create display device\n");
goto cleanup;
}

/* Free buffers for Display driver */
BufTab_freeAll(BufTab);


/* Create the capture display driver instance */
/* Get image from CAM -> where Source resolution is 1920x1080
* -> Output Resolution is 480x272
*/


/* Calculate the dimensions of the video standard */
if (BufferGfx_calcDimensions(VideoStd_LCD_272, colorSpace, &vfxAttrs.dim) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to calculate dimensions for video driver buffers\n");
goto cleanup;
}


/* Main loop */
while (1) {


if (ret != Dmai_EFIRSTFIELD && ret != Dmai_EBITERROR) {
/* Get a free buffer from the BufTab */
hDstBuf = BufTab_getFreeBuf(hBufTab);

if (hDstBuf == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr, "Failed to get a free contiguous buffer from BufTab\n");
BufTab_print(hBufTab);
goto cleanup;
}
}

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(hDstBuf), Buffer_getSize(hDstBuf));

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);
}
}

/* Make sure the whole buffer is used for output */
BufferGfx_resetDimensions(hDstBuf);
#if 0
/*Get a frame from the display_lcd device */
if (Display_get(hDisplay, &dBuf) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to get display buffer\n");
goto cleanup;
}

#endif
/* Decode the video buffer */
ret = Vdec2_process(hVd2, hInBuf, hDstBuf);

if (ret < 0) {
ret = Dmai_EFAIL;
fprintf(stderr, "Failed to decode video buffer\n");
goto cleanup;
}


if (args->benchmark) {
if (Time_delta(hTime, &time) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr, "Failed to get decode time\n");
goto cleanup;
}

printf("Frame %d - Decode: %uus\n", numFrame, (Uns)time);
}

if (numFrame == 1) {
/* Resize the BufTab after the first frame has been processed */
numBufs = resizeBufTab(hVd2, numBufs);

if (numBufs < 0) {
ret = 1;
goto cleanup;
}
}

/* Query the codec for display buffers and write them to a file */
hOutBuf = Vdec2_getDisplayBuf(hVd2);

/* If the codec was previously flushed and there are no more display
* buffers exit main thread.
*/

if (flushed&&(hOutBuf==NULL)) {
Buffer_delete(hInBuf);
break;
}

#if 0
Int8 *framePtrscr = Buffer_getUserPtr(hOutBuf);

Int val = Buffer_setUserPtr(dBuf, framePtrscr);

if(val!=Dmai_EOK){
//ret = Dmai_EFAIL;
printf("Failed to set UserPtr\n");
return -1;
}

/* Give the frame from the capture device to the display device */
if (Display_put(hDisplay, dBuf) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to put display buffer\n");
goto cleanup;
}
#endif


/*****
write data to file
*******/

while (hOutBuf) {

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 \n",
(Uns) time);
}
}

if (vc1Offset) {
/* The VC1 codec for DM365 puts the CbCr plane in
* (dim.y * dim.lineLength / 2) offset more than the expected
* place. So we (virtual) increase buffer size which will cause
* other components to pick up CbCr data from right place.
*/
BufferGfx_getDimensions(hOutBuf, &dim);
Buffer_setVirtualSize(hOutBuf,
Buffer_getSize(hOutBuf) +
(dim.y * dim.lineLength / 2) * 3 / 2);
}

if (mpeg4Offset) {
/* The MPEG4 codec for DM6467 puts the CbCr plane in
* (dim.y * dim.lineLength / 2) offset less than the expected
* place. So we (virtual) decrease buffer size which will cause
* other components to pick up CbCr data from right place.
*/
BufferGfx_getDimensions(hOutBuf, &dim);
Buffer_setVirtualSize(hOutBuf,
Buffer_getSize(hOutBuf) -
(dim.y * dim.lineLength / 2) * 3 / 2);
}

if (numFrameDisp++ >= args->startFrame) {
printf("Display Frame %d: ", numFrameDisp - 1);


if ((device == Cpu_Device_DM6467) ||
(device == Cpu_Device_DM365) ||
(device == Cpu_Device_DM368)) {


/*Get a frame from the display_lcd device */
if (Display_get(hDisplay, &dBuf) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to get display buffer\n");
goto cleanup;
}



if(args->sp) {
if (writeFrame420SP(hOutBuf,outFile,device)< 0) {//, outFile, device) < 0) {
ret = Dmai_EFAIL;
goto cleanup;
}
} else {
if (writeFrame420P(hOutBuf, outFile, device) < 0) {
ret = Dmai_EFAIL;
goto cleanup;
}
}
}
else {
if (writeFrameUYVY(hOutBuf, outFile) < 0) {
ret = Dmai_EFAIL;
goto cleanup;
}
}
}

Int8* outbuf = (Int8*)Buffer_getUserPtr(hOutBuf);
Int buf= Buffer_setUserPtr(dBuf,outbuf);
if(buf!=Dmai_EOK){
//ret = Dmai_EFAIL;
printf("Failed to set UserPtr\n");
return -1;
}

/* Give the frame from the capture device to the display device */
if (Display_put(hDisplay, dBuf) < 0) {
ret = Dmai_EFAIL;
fprintf(stderr,"Failed to put display buffer\n");
goto cleanup;
}

if (vc1Offset) {
Buffer_setVirtualSize(hOutBuf, 0);
}
if (mpeg4Offset) {
Buffer_setVirtualSize(hOutBuf, 0);
}

/* Get another buffer for display from the codec */
hOutBuf = Vdec2_getDisplayBuf(hVd2);
}

/* Get a buffer to free from the codec */
hFreeBuf = Vdec2_getFreeBuf(hVd2);
while (hFreeBuf) {
/* The codec is no longer using the buffer */
BufTab_freeBuf(hFreeBuf);
hFreeBuf = Vdec2_getFreeBuf(hVd2);
}

if (!flushed) {

printf("Loaded Frame %d: frame size %d\n", numFrame,
(Int)Buffer_getNumBytesUsed(hInBuf));

/* Load a new frame from the file system */
Loader_getFrame(hLoader, hInBuf);

if (numFrame++ == args->numFrames ||
Buffer_getUserPtr(hInBuf) == NULL){
flushed = TRUE;

/* Flush the codec for display frames */
Vdec2_flush(hVd2);

/*
* Temporarily create a temporary dummy buffer for the process
* call. After a flush the codec ignores the input buffer, but
* since Codec Engine still address translates the buffer, it
* needs to exist.
*/
hInBuf = Buffer_create(1, BufferGfx_getBufferAttrs(&gfxAttrs));

if (hInBuf == NULL) {
ret = Dmai_EFAIL;
fprintf(stderr, "Failed to allocate dummy buffer\n");
goto cleanup;
}

Buffer_setNumBytesUsed(hInBuf, 1);
}
}

if (flushed) {
Buffer_setNumBytesUsed(hInBuf, 1);
}

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 (hLoader) {
Loader_delete(hLoader);
}

if (hVd2) {
Vdec2_delete(hVd2);
}

if (hBufTab) {
BufTab_delete(hBufTab);
}

if (hEngine) {
Engine_close(hEngine);
}

if (hTime) {
Time_delete(hTime);
}

if (outFile) {
fclose(outFile);
}
if (hDisplay) {
Display_delete(hDisplay);
}


if (BufTab) {
BufTab_delete(BufTab);
}
printf("End of application.\n");

if (ret == Dmai_EFAIL)
return 1;
else
return 0;
}