Void *displayThrFxn(Void *arg)
{
Resize_Attrs rszAttrs = Resize_Attrs_DEFAULT;
DisplayEnv *envp = (DisplayEnv *) arg;
Display_Attrs dAttrs = Display_Attrs_DM365_VID_DEFAULT;
Display_Handle hDisplay = NULL;
Framecopy_Handle hFc = NULL;
Void *status = THREAD_SUCCESS;
Uns frameCnt = 0;
BufferGfx_Dimensions srcDim,dim;
Buffer_Handle hSrcBuf, hDstBuf;
Resize_Handle hRsz = NULL;
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;
Int bufCnt = 1;
BufTab_Handle hDisplayBufTab;
hTime = Time_create(&tAttrs);
Int bufIdx;
if (hTime == NULL) {
ERR("Failed to create Time object\n");
cleanup(THREAD_FAILURE);
}
/* Create the resize job */
hRsz = Resize_create(&rszAttrs);
if (hRsz == NULL) {
/// ret = Dmai_EFAIL;
ERR("Failed to create resize job\n");
cleanup(THREAD_FAILURE);
}
if(Time_reset(hTime) != Dmai_EOK) {
ERR("Failed to reset timer\n");
cleanup(THREAD_FAILURE);
}
if (bufCnt == 1) { // Create the Display at the first frame
gfxAttrs.dim.width =960;
gfxAttrs.dim.height =540+17;
gfxAttrs.dim.lineLength =Dmai_roundUp(BufferGfx_calcLineLength(gfxAttrs.dim.width,
colorSpace), 32)+64;
printf("jjjj=%d\n",gfxAttrs.dim.lineLength);
gfxAttrs.dim.x =4;// srcDim.x;
gfxAttrs.dim.y =-2;// srcDim.y;
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.delayStreamon = TRUE;
dAttrs.numBufs = NUM_DISPLAY_BUFS;
dAttrs.videoStd = envp->videoStd;
/*
* Round down the width to a multiple of 32 as required by
* display driver. Otherwise, the driver would internally round
* up the width, resulting in the codec padding showing up
* on the display when the image width is not a multiple of 32.
*/
dAttrs.width = ((gfxAttrs.dim.width & 0x1f) ?
(gfxAttrs.dim.width & ~(0x1f)) : gfxAttrs.dim.width);
dAttrs.height = gfxAttrs.dim.height;
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);
}
hDisplayBufTab = Display_getBufTab(hDisplay);
for (bufIdx = 0; bufIdx < BufTab_getNumBufs(hDisplayBufTab); bufIdx++)
{
hDstBuf = BufTab_getBuf(hDisplayBufTab, bufIdx);
BufferGfx_getDimensions(hDstBuf, &dim);
dim.width =gfxAttrs.dim.width;
dim.height =gfxAttrs.dim.height;
dim.x = gfxAttrs.dim.x;
dim.y = gfxAttrs.dim.y;
// dim.lineLength=gfxAttrs.dim.lineLength;
if (BufferGfx_setDimensions(hDstBuf, &dim) < 0)
{
//ret = Dmai_EFAIL;
fprintf(stderr,"Output resolution does not fit in display frame\n");
// goto cleanup;
}
if (Display_put(hDisplay, hDstBuf) < 0)
{
ERR("Failed to put display buffer\n");
cleanup(THREAD_FAILURE);
}
}
}
bufCnt++;
/* Signal that initialization is done and wait for other threads */
Rendezvous_meet(envp->hRendezvousInit);
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);
// printf("+%d +%d +%d +%d+%d\n",srcDim.width,srcDim.height,srcDim.x,srcDim.y,srcDim.lineLength);
/* Get a buffer from the display device driver */
if (Display_get(hDisplay, &hDstBuf) < 0) {
ERR("Failed to get display buffer\n");
cleanup(THREAD_FAILURE);
}
if (Resize_420_to_420_execute(hRsz, hSrcBuf, hDstBuf) < 0) {////Resize_doYUV420SP/////Resize_420_to_420_execute
ERR("Failed to execute resize job\n");
cleanup(THREAD_FAILURE);
}
/* 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);
}
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);
}
}
/* 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 (hFc) {
Framecopy_delete(hFc);
}
if (hDisplay) {
Display_delete(hDisplay);
}
/* Clean up the thread before exiting */
if (hBufTab) {
BufTab_delete(hBufTab);
}
if(hTime) {
Time_delete(hTime);
}
return status;
}