Hi,Guys.
Device is DM365, DVSDK-demos is 4.0.0.21, DMAI is 2.2.0.14 .
Now I can display video in a 800x480 LCD, but since the display thread is using framecopy, the video can only be shown a part of it.
So I decide to use the resizer module ,and show the whole video in LCD, but I met some problem.
Since it's the first time for me to use resizer, I change the output to TV, not LCD, the hardware connection is :【PAL input】->tvp5150->DM365->【TV-PAL output】.
here is my code display.c from decode demo:
#include <ti/sdo/dmai/Resize.h> #include "display.h" #include "../demo.h" /* Display loop delay in us */ #define DISPLAYLOOPLATENCY 33332 /* Buffering for the display driver */ #define NUM_DISPLAY_BUFS 4 #define DRESIZE_IS_FRAMECOPY 1 #define DRESIZE_IS_RESIZER 2 #define DRESIZE_SELECTION DRESIZE_IS_RESIZER extern BufTab_Handle getVideoDecoderBufTab(void); /****************************************************************************** * displayThrFxn ******************************************************************************/ Void *displayThrFxn(Void *arg) { DisplayEnv *envp = (DisplayEnv *) arg; Display_Attrs dAttrs = Display_Attrs_DM365_VID_DEFAULT; Framecopy_Attrs fcAttrs = Framecopy_Attrs_DEFAULT; Display_Handle hDisplay = NULL; Framecopy_Handle hFc = NULL; Void *status = THREAD_SUCCESS; Uns frameCnt = 0; Int32 clipWidth = 0; Int32 clipHeight = 0; Int32 srcWidth = 0; Int32 srcHeight = 0; Int32 dstWidth = 0; Int32 dstHeight = 0; Int32 dstX = 0; Int32 dstY = 0; BufferGfx_Dimensions srcDim, dstDim; Buffer_Handle hSrcBuf, hDstBuf; Int fifoRet; ColorSpace_Type colorSpace = ColorSpace_YUV420PSEMI; BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; BufTab_Handle hBufTab = NULL; Int32 bufSize; Time_Attrs tAttrs = Time_Attrs_DEFAULT; Time_Handle hTime = NULL; Int32 time, waitTime; Resize_Attrs rszAttrs = Resize_Attrs_DEFAULT; Resize_Handle hRsz = NULL; int resizer_is_cfged = 0; //ColorSpace_Type colorSpace = ColorSpace_UYVY; if (VideoStd_getResolution(envp->videoStd, &gfxAttrs.dim.width, &gfxAttrs.dim.height) < 0) { ERR("Failed to calculate resolution of video standard\n"); cleanup(THREAD_FAILURE); } gfxAttrs.dim.lineLength = Dmai_roundUp(BufferGfx_calcLineLength(gfxAttrs.dim.width, colorSpace), 32); gfxAttrs.dim.x = 0; gfxAttrs.dim.y = 0; if (colorSpace == ColorSpace_YUV420PSEMI) { bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 3 / 2; } else { bufSize = gfxAttrs.dim.lineLength * gfxAttrs.dim.height * 2; } /* Create a table of buffers to use with the device drivers */ gfxAttrs.colorSpace = colorSpace; hBufTab = BufTab_create(NUM_DISPLAY_BUFS, bufSize, BufferGfx_getBufferAttrs(&gfxAttrs)); if (hBufTab == NULL) { ERR("Failed to create buftab\n"); cleanup(THREAD_FAILURE); } /* Create the display device instance */ dAttrs.numBufs = NUM_DISPLAY_BUFS; dAttrs.videoStd = envp->videoStd; dAttrs.videoOutput = envp->displayOutput; dAttrs.colorSpace = colorSpace; hDisplay = Display_create(hBufTab, &dAttrs); if (hDisplay == NULL) { ERR("Failed to create display device\n"); cleanup(THREAD_FAILURE); } #if (DRESIZE_SELECTION == DRESIZE_IS_FRAMECOPY) /* Create the frame copy job */ fcAttrs.accel = TRUE; hFc = Framecopy_create(&fcAttrs); if (hFc == NULL) { ERR("Failed to create frame copy job\n"); cleanup(THREAD_FAILURE); } #elif (DRESIZE_SELECTION == DRESIZE_IS_RESIZER) /* API will set oper_mode to single_shot,if driver not set to ss,return error */ hRsz = Resize_create(&rszAttrs); if (hRsz == NULL) { printf("Failed to create resizer\n"); cleanup(THREAD_FAILURE); } #endif hTime = Time_create(&tAttrs); if (hTime == NULL) { ERR("Failed to create Time object\n"); cleanup(THREAD_FAILURE); } if(Time_reset(hTime) != Dmai_EOK) { ERR("Failed to reset timer\n"); cleanup(THREAD_FAILURE); } /* Signal that initialization is done and wait for other threads */ Rendezvous_meet(envp->hRendezvousInit); printf("Display prepare OK,enter loop\n"); while (!gblGetQuit()) { /* Pause processing? */ Pause_test(envp->hPauseProcess); /* Pause for priming? */ Pause_test(envp->hPausePrime); /* Get decoded video frame */ fifoRet = Fifo_get(envp->hInFifo, &hSrcBuf); if (fifoRet < 0) { ERR("Failed to get buffer from video thread\n"); cleanup(THREAD_FAILURE); } /* Did the video thread flush the fifo? */ if (fifoRet == Dmai_EFLUSH) { cleanup(THREAD_SUCCESS); } BufferGfx_getDimensions(hSrcBuf, &srcDim); /* Get a buffer from the display device driver */ if (Display_get(hDisplay, &hDstBuf) < 0) { ERR("Failed to get display buffer\n"); cleanup(THREAD_FAILURE); } BufferGfx_getDimensions(hDstBuf, &dstDim); #if (DRESIZE_SELECTION == DRESIZE_IS_FRAMECOPY) /* Alter the position of the image to center it */ if (srcDim.width != clipWidth || srcDim.height != clipHeight) { clipWidth = srcDim.width; clipHeight = srcDim.height; /* Update global data for user interface */ gblSetImageWidth(srcDim.width); gblSetImageHeight(srcDim.height); /* Clamp the width and center if clip is wider than screen */ if (srcDim.width > dstDim.width) { dstWidth = dstDim.width; srcWidth = dstDim.width; dstX = 0; } else { dstWidth = srcDim.width; srcWidth = srcDim.width; dstX = ((dstDim.width - srcDim.width) / 2) & ~0xf; } /* Clamp the height if clip is higher than screen */ if (srcDim.height > dstDim.height) { dstHeight = dstDim.height; srcHeight = dstDim.height; dstY = 0; } else { dstHeight = srcDim.height; srcHeight = srcDim.height; dstY = (dstDim.height - srcDim.height) / 2; } dstDim.x = dstX; dstDim.y = dstY; dstDim.width = dstWidth; dstDim.height = dstHeight; BufferGfx_setDimensions(hDstBuf, &dstDim); srcDim.width = srcWidth; srcDim.height = srcHeight; BufferGfx_setDimensions(hSrcBuf, &srcDim); if (Framecopy_config(hFc, hSrcBuf, hDstBuf) < 0) { ERR("Failed to configure frame copy job\n"); cleanup(THREAD_FAILURE); } } srcDim.width = srcWidth; srcDim.height = srcHeight; BufferGfx_setDimensions(hSrcBuf, &srcDim); dstDim.width = dstWidth; dstDim.height = dstHeight; dstDim.x = dstX; dstDim.y = dstY; BufferGfx_setDimensions(hDstBuf, &dstDim); /* Copy the decoded buffer from the video thread to the display. */ if (Framecopy_execute(hFc, hSrcBuf, hDstBuf) < 0) { ERR("Failed to execute frame copy job\n"); cleanup(THREAD_FAILURE); } #elif (DRESIZE_SELECTION == DRESIZE_IS_RESIZER) if (srcDim.width != clipWidth || srcDim.height != clipHeight){ printf("Resizer:srcDim.w=%d/h=%d,clipWidth=%d,dstDim.w=%d/h=%d\n", (int)srcDim.width,(int)srcDim.height, (int)clipWidth,(int)dstDim.width,(int)dstDim.height); clipWidth = srcDim.width; clipHeight = srcDim.height; resizer_is_cfged = 1; /* Configure the resize job color space cannot be IPIPE_420SP? */ //BufferGfx_setColorSpace(BufTab_getBuf(getVideoDecoderBufTab(), 0),ColorSpace_UYVY); if (Resize_config(hRsz, BufTab_getBuf(getVideoDecoderBufTab(), 0), BufTab_getBuf(hBufTab, 0)) < 0) { printf("Failed to configure resize job\n"); cleanup(THREAD_FAILURE); } BufferGfx_setColorSpace(BufTab_getBuf(getVideoDecoderBufTab(), 0),ColorSpace_YUV420PSEMI); } /* Resize the captured frame to the resolution of the display frame */ BufferGfx_setColorSpace(hSrcBuf,ColorSpace_UYVY); BufferGfx_getDimensions(hSrcBuf, &srcDim); printf("video buffer,dim.w=%d,.h=%d,.linelength=%d\n", (int)srcDim.width,(int)srcDim.height,(int)srcDim.lineLength); if (Resize_execute(hRsz, hSrcBuf, hDstBuf) < 0) { printf("Failed to execute resize job\n"); cleanup(THREAD_FAILURE); } BufferGfx_setColorSpace(hSrcBuf,ColorSpace_YUV420PSEMI); #endif if(envp->videoStd == VideoStd_720P_60) { if (Time_delta(hTime, (UInt32*)&time) < 0) { ERR("Failed to get timer delta\n"); cleanup(THREAD_FAILURE); } waitTime = DISPLAYLOOPLATENCY - time; if(waitTime > 0) { usleep(waitTime); } if(Time_reset(hTime) != Dmai_EOK) { ERR("Failed to reset timer\n"); cleanup(THREAD_FAILURE); } } #if (DRESIZE_SELECTION == DRESIZE_IS_FRAMECOPY) BufferGfx_resetDimensions(hSrcBuf); BufferGfx_resetDimensions(hDstBuf); #endif /* Send buffer back to the video thread */ if (Fifo_put(envp->hOutFifo, hSrcBuf) < 0) { ERR("Failed to send buffer to video thread\n"); cleanup(THREAD_FAILURE); } /* Incremement statistics for the user interface */ gblIncFrames(); /* Give a filled buffer back to the display device driver */ if (Display_put(hDisplay, hDstBuf) < 0) { ERR("Failed to put display buffer\n"); cleanup(THREAD_FAILURE); } frameCnt++; } cleanup: /* Make sure the other threads aren't waiting for us */ Rendezvous_force(envp->hRendezvousInit); Pause_off(envp->hPauseProcess); Pause_off(envp->hPausePrime); Fifo_flush(envp->hOutFifo); /* Meet up with other threads before cleaning up */ Rendezvous_meet(envp->hRendezvousCleanup); /* Clean up the thread before exiting */ #if (DRESIZE_SELECTION == DRESIZE_IS_FRAMECOPY) if (hFc) { Framecopy_delete(hFc); } #elif (DRESIZE_SELECTION == DRESIZE_IS_RESIZER) if (hRsz) { printf("Resize_delete\n"); Resize_delete(hRsz); } #endif if (hDisplay) { Display_delete(hDisplay); } /* Clean up the thread before exiting */ if (hBufTab) { BufTab_delete(hBufTab); } if(hTime) { Time_delete(hTime); } return status; } |
since the resizer_config need a BufTab handle from source, I provide a api from video.c to get the input BufTab:
static BufTab_Handle g_video_buftab; BufTab_Handle getVideoDecoderBufTab(void) { return g_video_buftab; } |
And set the variable to vidoe.c's hBufTab after it's created.
/* The codec is going to use this BufTab for output buffers */
Vdec2_setBufTab(hVd2, hBufTab);
g_video_buftab = hBufTab;
=====================Now here is the problem==========================
1、if I donot set the colorspace of BufTab from video.c to UYVY ,the resize_config() fail:
//BufferGfx_setColorSpace(BufTab_getBuf(getVideoDecoderBufTab(), 0),ColorSpace_UYVY); // comment this line
report: davinci_resizer davinci_resizer.2: rsz_validate_out_pix_formatspix format not supported, 9
So I uncomment BufferGfx_setColorSpace(BufTab_getBuf(getVideoDecoderBufTab(), 0),ColorSpace_UYVY); now it config OK.
2、resize_execute() fail. no matter whether I comment "BufferGfx_setColorSpace(hSrcBuf,ColorSpace_UYVY);" or not before calling it.
report:decode: linux/dm365/Resize.c:334: Resize_execute: Assertion `(rsz.in_buff.offset & 0x1F) == 0' failed.
Aborted
It seems the offset should not be zero???
I have check this post:
http://e2e.ti.com/support/dsp/davinci_digital_media_processors/f/100/t/7583.aspx
http://e2e.ti.com/support/embedded/linux/f/354/t/38577.aspx
but still have no idea, could you provide more information how to use it?