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.

Linux/TMS320DM365: h.264 decoding on lcd

Part Number: TMS320DM365

Tool/software: Linux

I would like to decode h.264 stream on LCD interface.

Our LCD interface only need HSYNC, VSYNC, RGB565 data.

So I'm using logicpd lcd device driver and our schematic is like folloings.

Drawing rectangle on Framebuffer works fine with below source code,

but decoding h.264 doesn't work. I modified demo/decode source code for us.

Can anyone give us any hint what is the problem please..??

Thank you for your readings.

Frame Buffer source code

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

int main()
{
	int fbfd = 0;
	struct fb_var_screeninfo vinfo;
	struct fb_fix_screeninfo finfo;
	long int screensize = 0;
	char *fbp = 0;
	int x = 0, y = 0;
	long int location = 0;

	// Open the file for reading and writing
	fbfd = open("/dev/fb/2", O_RDWR);
	if (fbfd == -1) {
		perror("Error: cannot open framebuffer device");
		exit(1);
	}
	printf("The framebuffer device was opened successfully.\n");

	// Get fixed screen information
	if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo) == -1) {
		perror("Error reading fixed information");
		exit(2);
	}

	// Get variable screen information
	if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo) == -1) {
		perror("Error reading variable information");
		exit(3);
	}

	printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);

	// Figure out the size of the screen in bytes
	screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;

	// Map the device to memory
	fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
	if ((int)fbp == -1) {
		perror("Error: failed to map framebuffer device to memory");
		exit(4);
	}
	printf("The framebuffer device was mapped to memory successfully.\n");

	x = 300; y = 100;       // Where we are going to put the pixel

	// Figure out where in memory to put the pixel
	for (y = 100; y < 300; y++)
		for (x = 100; x < 300; x++) {

			location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +
				(y+vinfo.yoffset) * finfo.line_length;

			if (vinfo.bits_per_pixel == 32) {
				*(fbp + location) = 100;        // Some blue
				*(fbp + location + 1) = 15+(x-100)/2;     // A little green
				*(fbp + location + 2) = 200-(y-100)/5;    // A lot of red
				*(fbp + location + 3) = 0;      // No transparency
			} else  { //assume 16bpp
				int b = 10;
				int g = (x-100)/6;     // A little green
				int r = 31-(y-100)/16;    // A lot of red
				unsigned short int t = r<<11 | g << 5 | b;
				*((unsigned short int*)(fbp + location)) = t;
			}

		}
	munmap(fbp, screensize);
	close(fbfd);

	return 0;
}

display.c from decoder application

/*
 * display.c
 *
 * ============================================================================
 * Copyright (c) Texas Instruments Inc 2009
 *
 * Use of this software is controlled by the terms and conditions found in the
 * license agreement under which this software has been supplied or provided.
 * ============================================================================
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>

#include <xdc/std.h>

#include <ti/sdo/dmai/Time.h>
#include <ti/sdo/dmai/Framecopy.h>
#include <ti/sdo/dmai/Fifo.h>
#include <ti/sdo/dmai/Pause.h>
#include <ti/sdo/dmai/Display.h>
#include <ti/sdo/dmai/BufferGfx.h>
#include <ti/sdo/dmai/Rendezvous.h>

#include "display.h"
#include "help.h"
#include "main.h"

/* Display loop delay in us */
#define DISPLAYLOOPLATENCY 33332

/* Buffering for the display driver */
#define NUM_DISPLAY_BUFS         2

/******************************************************************************
 * displayThrFxn
 ******************************************************************************/
Void *displayThrFxn(Void *arg)
{
    DisplayEnv             *envp       = (DisplayEnv *) arg;
    //Display_Attrs           dAttrs     = Display_Attrs_DM365_VID_DEFAULT;
    Display_Attrs           dAttrs     = Display_Attrs_DM365_ATTR_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;

    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 = ((Int32)((BufferGfx_calcLineLength(gfxAttrs.dim.width, colorSpace)+31)/32))*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;			// mach
    dAttrs.displayDevice = "/dev/fb/2";			// mach
//    dAttrs.displayDevice = "/dev/video2";			// mach

    printf("displayDevice is %s\n", dAttrs.displayDevice); fflush(stdout);
#if 1								// mach
    hDisplay = Display_create(hBufTab, &dAttrs);

    if (hDisplay == NULL) {
        ERR("Failed to create display device\n");
        cleanup(THREAD_FAILURE);
    }
#endif

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

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

    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 line @ %s\n", __LINE__, __FILE__); fflush(stdout);

#if 1								// mach
        /* Get a buffer from the display device driver */
        if (Display_get(hDisplay, &hDstBuf) < 0) {
            ERR("Failed to get display buffer\n");
            cleanup(THREAD_FAILURE);
        }
#endif

        BufferGfx_getDimensions(hDstBuf, &dstDim);
	printf("%d line @ %s\n", __LINE__, __FILE__); fflush(stdout);
        
        /* Alter the position of the image to center it */
#if 0								// mach
        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);
            }
        }
#endif

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

#if 0								// mach
        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);
            }
        }
        
        BufferGfx_resetDimensions(hSrcBuf);            
#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();           
        
#if 0								// mach
        BufferGfx_resetDimensions(hDstBuf);
        /* 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);
        }
#endif
        
        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;
}

main.c from decoder application.......

/*
 * main.c
 *
 * ============================================================================
 * Copyright (c) Texas Instruments Inc 2009
 *
 * Use of this software is controlled by the terms and conditions found in the
 * license agreement under which this software has been supplied or provided.
 * ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <getopt.h>
#include <strings.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <signal.h>

#include <xdc/std.h>

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

#include <ti/sdo/dmai/Dmai.h>
#include <ti/sdo/dmai/Fifo.h>
#include <ti/sdo/dmai/Pause.h>
#include <ti/sdo/dmai/BufferGfx.h>
#include <ti/sdo/dmai/Rendezvous.h>

#include "display.h"
#include "video.h"
#include "loader.h"
#include "help.h"
#include "main.h"

#include <ti/sdo/fc/rman/rman.h>

/* The levels of initialization */
#define LOGSINITIALIZED         0x1
#define DISPLAYTHREADCREATED    0x2
#define VIDEOTHREADCREATED      0x4
#define SPEECHTHREADCREATED     0x8
#define LOADERTHREADCREATED     0x10

/* Thread priorities */
#define LOADER_THREAD_PRIORITY  sched_get_priority_max(SCHED_FIFO) - 2
#define SPEECH_THREAD_PRIORITY  sched_get_priority_max(SCHED_FIFO) - 2
#define VIDEO_THREAD_PRIORITY   sched_get_priority_max(SCHED_FIFO) - 1
#define DISPLAY_THREAD_PRIORITY sched_get_priority_max(SCHED_FIFO) 

typedef struct Args {
	Display_Output displayOutput;
	VideoStd_Type  videoStd;
	Char          *videoStdString;
	Char          *speechFile;
	Char          *videoFile;
	Codec         *speechDecoder;
	Codec         *videoDecoder;
	Int            loop;
	Int            keyboard;
	Int            time;
	Int            osd;
	Int            interface;
} Args;

/* Defining infinite time */
#define FOREVER         -1

#define DEFAULT_ARGS { Display_Output_COUNT, VideoStd_D1_NTSC, "D1 NTSC", NULL, NULL, NULL, NULL, \
	FALSE, FALSE, FOREVER, FALSE, FALSE }

/* Global variable declarations for this application */
GlobalData gbl = GBL_DATA_INIT;

/******************************************************************************
 * Signal handler
 ******************************************************************************/
Void signalHandler(int sig)
{
	signal(SIGINT, SIG_DFL);
	gblSetQuit();
}

/******************************************************************************
 * getCodec
 ******************************************************************************/
static Codec *getCodec(Char *extension, Codec *codecs)
{
	Codec *codec = NULL;
	Int i, j;

	i = 0;
	while (codecs[i].codecName) {
		j = 0;
		while (codecs[i].fileExtensions[j]) {
			if (strcmp(extension, codecs[i].fileExtensions[j]) == 0) {
				codec = &codecs[i];
			}
			j++;
		}
		i++;
	}

	return codec;
}

/******************************************************************************
 * usage
 ******************************************************************************/
static Void usage(void)
{
	fprintf(stderr, "Usage: decode [options]\n\n"
			"Options:\n"
			"-s | --speechfile       Speech file to play\n"
			"-v | --videofile        Video file to play\n"
			"-y | --display_standard Video standard to use for display (see below).\n"
			"-O | --display_output   Video output to use (see below).\n"
			"-k | --keyboard         Enable keyboard interface [off]\n"
			"-t | --time             Number of seconds to run the demo [infinite]\n"
			"-l | --loop             Loop to beginning of files when done [off]\n"
			"-o | --osd              Show demo data on an OSD [off]\n"
			"-i | --interface        Launch the demo interface when exiting [off]\n"
			"-h | --help             Print this message\n\n"
			"Video standards available:\n"
			"\t1\tD1 @ 30 fps (NTSC) [Default]\n"
			"\t2\tD1 @ 25 fps (PAL)\n"
			"\t3\t720P @ 60 fps\n"
			"Video outputs available:\n"
			"\tcomposite [Default]\n"
			"\tcomponent (Only 720P available)\n"
			"You must supply at least a video or a speech file\n"
			"with appropriate extensions for the file formats.\n\n");
}

/******************************************************************************
 * parseArgs
 ******************************************************************************/
static Void parseArgs(Int argc, Char *argv[], Args *argsp)
{
	const Char shortOptions[] = "s:v:y:O:kt:lfoih";
	const struct option longOptions[] = {
		{"speechfile",       required_argument, NULL, 's'},
		{"videofile",        required_argument, NULL, 'v'},
		{"display_standard", required_argument, NULL, 'y'},
		{"display_output",   required_argument, NULL, 'O'},
		{"keyboard",         no_argument,       NULL, 'k'},
		{"time",             required_argument, NULL, 't'},
		{"loop",             no_argument,       NULL, 'l'},
		{"osd",              no_argument,       NULL, 'o'},
		{"interface",        no_argument,       NULL, 'i'},
		{"help",             no_argument,       NULL, 'h'},
		{"exit",             no_argument,       NULL, 'e'},            
		{0, 0, 0, 0}
	};

	Int   index;
	Int   c;
	Char *extension;

	for (;;) {
		c = getopt_long(argc, argv, shortOptions, longOptions, &index);

		if (c == -1) {
			break;
		}

		switch (c) {
			case 0:
				break;

			case 's':
				extension = rindex(optarg, '.');
				if (extension == NULL) {
					fprintf(stderr, "Speech file without extension: %s\n",
							optarg);
					exit(EXIT_FAILURE);
				}

				argsp->speechDecoder =
					getCodec(extension, engine->speechDecoders);

				if (!argsp->speechDecoder) {
					fprintf(stderr, "Unknown speech file extension: %s\n",
							extension);
					exit(EXIT_FAILURE);
				}
				argsp->speechFile = optarg;

				break;

			case 'v':
				extension = rindex(optarg, '.');
				if (extension == NULL) {
					fprintf(stderr, "Video file without extension: %s\n",
							optarg);
					exit(EXIT_FAILURE);
				}

				argsp->videoDecoder =
					getCodec(extension, engine->videoDecoders);

				if (!argsp->videoDecoder) {
					fprintf(stderr, "Unknown video file extension: %s\n",
							extension);
					exit(EXIT_FAILURE);
				}
				argsp->videoFile = optarg;

				break;

			case 'y':
				switch (atoi(optarg)) {
					case 1:
						argsp->videoStd = VideoStd_D1_NTSC;
						argsp->videoStdString = "D1 NTSC";
						break;
					case 2:
						argsp->videoStd = VideoStd_D1_PAL;
						argsp->videoStdString = "D1 PAL";
						break;
					case 3:
						argsp->videoStd = VideoStd_720P_60;
						argsp->videoStdString = "720P 60Hz";
						break;
					case 4:
						argsp->videoStd = VideoStd_720P_50;
						argsp->videoStdString = "720P 50Hz";
						break;
					case 5:
						argsp->videoStd = VideoStd_1080I_30;
						argsp->videoStdString = "1080I 30Hz";
						break;
					case 6:
						argsp->videoStd = VideoStd_1080I_25;
						argsp->videoStdString = "1080I 25Hz";
						break;
					case 7:
						argsp->videoStd = VideoStd_VGA;
						argsp->videoStdString = "640x480";
						break;
					default:
						fprintf(stderr, "Unknown display resolution\n");
						usage();
						exit(EXIT_FAILURE);
				}
				break;

			case 'O':
				if (strcmp(optarg, "component") == 0) {
					argsp->displayOutput = Display_Output_COMPONENT;
				} else if (strcmp(optarg, "composite") == 0) {
					argsp->displayOutput = Display_Output_COMPOSITE;
				} else if (strcmp(optarg, "LCD") == 0) {
					argsp->displayOutput = Display_Output_LCD;
				} else {
					fprintf(stderr, "Unknown video output: %s\n", optarg);
					usage();
					exit(EXIT_FAILURE);
				}
				break;

			case 'k':
				argsp->keyboard = TRUE;
				break;

			case 't':
				argsp->time = atoi(optarg);
				break;

			case 'l':
				argsp->loop = TRUE;
				break;

			case 'o':
				argsp->osd = TRUE;
				break;

			case 'i':
				argsp->interface = TRUE;
				break;

			case 'h':
				usage();
				exit(EXIT_SUCCESS);

			default:
				usage();
				exit(EXIT_FAILURE);
		}
	}

	if (argsp->displayOutput == Display_Output_COUNT) {
		if ((argsp->videoStd == VideoStd_D1_NTSC) || (argsp->videoStd == VideoStd_D1_PAL)) {
			argsp->displayOutput = Display_Output_COMPOSITE;
		} else {
			argsp->displayOutput = Display_Output_COMPONENT;
		}
	}
	/* Need at least one file to decode and only one sound file */
	if (!argsp->videoFile && !argsp->speechFile) {
		usage();
		exit(EXIT_FAILURE);
	}
}



/******************************************************************************
 * main
 ******************************************************************************/
Int main(Int argc, Char *argv[])
{
	Args                    args                = DEFAULT_ARGS;
	Uns                     initMask            = 0;
	Int                     status              = EXIT_SUCCESS;
	Pause_Attrs             pAttrs              = Pause_Attrs_DEFAULT;
	Rendezvous_Attrs        rzvAttrs            = Rendezvous_Attrs_DEFAULT;
	Fifo_Attrs              fAttrs              = Fifo_Attrs_DEFAULT;
	Rendezvous_Handle       hRendezvousInit     = NULL;
	Rendezvous_Handle       hRendezvousCleanup  = NULL;
	Rendezvous_Handle       hRendezvousLoop     = NULL;
	Rendezvous_Handle       hRendezvousLoader   = NULL;
	Pause_Handle            hPauseProcess       = NULL;
	Pause_Handle            hPausePrime         = NULL;
	Int                     syncCnt             = 0;
	struct sched_param      schedParam;
	pthread_attr_t          attr;
	pthread_t               displayThread;
	pthread_t               videoThread;
	pthread_t               speechThread;
	pthread_t               loaderThread;
	LoaderEnv               loaderEnv;
	DisplayEnv              displayEnv;
	VideoEnv                videoEnv;
	Int                     numThreads;
	Void                   *ret;

	/* Zero out the thread environments */
	Dmai_clear(loaderEnv);
	Dmai_clear(displayEnv);
	Dmai_clear(videoEnv);

	/* Parse the arguments given to the app and set the app environment */
	parseArgs(argc, argv, &args);

	printf("Decode demo started.\n");

	/* Initialize the mutex which protects the global data */
	pthread_mutex_init(&gbl.mutex, NULL);

	/* Set the priority of this whole process to max (requires root) */
	setpriority(PRIO_PROCESS, 0, -20);

	/* Initialize Codec Engine runtime */
	CERuntime_init();

	/* Initialize signal handler for SIGINT */
	signal(SIGINT, signalHandler);

	/* Initialize Davinci Multimedia Application Interface */
	Dmai_init();

	initMask |= LOGSINITIALIZED;

	/* Create the Pause objects */
	hPauseProcess = Pause_create(&pAttrs);
	hPausePrime = Pause_create(&pAttrs);

	if (hPauseProcess == NULL || hPausePrime == NULL) {
		ERR("Failed to create Pause objects\n");
		cleanup(EXIT_FAILURE);
	}

	/* Determine the number of threads needing synchronization */
	numThreads = 1;

	if (args.videoFile) {
		numThreads += 3;
		syncCnt++;
	}

	if (args.speechFile) {
		numThreads += 1;
		syncCnt++;
	}

	/* Create the objects which synchronizes the thread init and cleanup */
	hRendezvousInit = Rendezvous_create(numThreads, &rzvAttrs);
	hRendezvousCleanup = Rendezvous_create(numThreads, &rzvAttrs);
	hRendezvousLoop = Rendezvous_create(syncCnt, &rzvAttrs);
	hRendezvousLoader = Rendezvous_create(2, &rzvAttrs);

	if (hRendezvousInit == NULL || hRendezvousCleanup == NULL ||
			hRendezvousLoop == NULL || hRendezvousLoader == NULL) {

		ERR("Failed to create Rendezvous objects\n");
		cleanup(EXIT_FAILURE);
	}

	/* Initialize the thread attributes */
	if (pthread_attr_init(&attr)) {
		ERR("Failed to initialize thread attrs\n");
		cleanup(EXIT_FAILURE);
	}

	/* Force the thread to use custom scheduling attributes */
	if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
		ERR("Failed to set schedule inheritance attribute\n");
		cleanup(EXIT_FAILURE);
	}

	/* Set the thread to be fifo real time scheduled */
	if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
		ERR("Failed to set FIFO scheduling policy\n");
		cleanup(EXIT_FAILURE);
	}

	/* Create the video threads if a file name is supplied */
	if (args.videoFile) {
		/* Create the display fifos */
		displayEnv.hInFifo = Fifo_create(&fAttrs);
		displayEnv.hOutFifo = Fifo_create(&fAttrs);

		if (displayEnv.hInFifo == NULL || displayEnv.hOutFifo == NULL) {
			ERR("Failed to create display fifos\n");
			cleanup(EXIT_FAILURE);
		}

		/* Set the display thread priority */
		schedParam.sched_priority = DISPLAY_THREAD_PRIORITY;
		if (pthread_attr_setschedparam(&attr, &schedParam)) {
			ERR("Failed to set scheduler parameters\n");
			cleanup(EXIT_FAILURE);
		}

		/* Create the display thread */
		displayEnv.displayOutput      = args.displayOutput;        
		displayEnv.videoStd           = args.videoStd;
		displayEnv.hRendezvousInit    = hRendezvousInit;
		displayEnv.hRendezvousCleanup = hRendezvousCleanup;
		displayEnv.hPauseProcess      = hPauseProcess;
		displayEnv.hPausePrime        = hPausePrime;
		displayEnv.osd                = args.osd;

		if (pthread_create(&displayThread, &attr, displayThrFxn, &displayEnv)) {
			ERR("Failed to create display thread\n");
			cleanup(EXIT_FAILURE);
		}

		initMask |= DISPLAYTHREADCREATED;

		/* Set the video thread priority */
		schedParam.sched_priority = VIDEO_THREAD_PRIORITY;
		if (pthread_attr_setschedparam(&attr, &schedParam)) {
			ERR("Failed to set scheduler parameters\n");
			cleanup(EXIT_FAILURE);
		}

		/* Create the video thread */
		videoEnv.hRendezvousInit    = hRendezvousInit;
		videoEnv.hRendezvousCleanup = hRendezvousCleanup;
		videoEnv.hRendezvousLoop    = hRendezvousLoop;
		videoEnv.hRendezvousLoader  = hRendezvousLoader;
		videoEnv.hPauseProcess      = hPauseProcess;
		videoEnv.hPausePrime        = hPausePrime;
		videoEnv.hDisplayInFifo     = displayEnv.hInFifo;
		videoEnv.hDisplayOutFifo    = displayEnv.hOutFifo;
		videoEnv.videoFile          = args.videoFile;
		videoEnv.videoDecoder       = args.videoDecoder->codecName;
		videoEnv.params             = args.videoDecoder->params;
		videoEnv.dynParams          = args.videoDecoder->dynParams;
		videoEnv.loop               = args.loop;
		videoEnv.engineName         = engine->engineName;
		videoEnv.videoStd           = args.videoStd;        

		if (pthread_create(&videoThread, &attr, videoThrFxn, &videoEnv)) {
			ERR("Failed to create video thread\n");
			cleanup(EXIT_FAILURE);
		}

		initMask |= VIDEOTHREADCREATED;

		/*
		 * Wait for the Loader to be created in the video thread before
		 * launching the loader thread.
		 */
		Rendezvous_meet(hRendezvousLoader);

		/* Set the loader thread priority */
		schedParam.sched_priority = LOADER_THREAD_PRIORITY;
		if (pthread_attr_setschedparam(&attr, &schedParam)) {
			ERR("Failed to set scheduler parameters\n");
			return -1;
		}

		/* Create the loader thread */
		loaderEnv.hRendezvousInit    = hRendezvousInit;
		loaderEnv.hRendezvousCleanup = hRendezvousCleanup;
		loaderEnv.loop               = args.loop;
		loaderEnv.hLoader            = videoEnv.hLoader;

		if (pthread_create(&loaderThread, &attr, loaderThrFxn, &loaderEnv)) {
			ERR("Failed to create loader thread\n");
			cleanup(EXIT_FAILURE);
		}

		initMask |= LOADERTHREADCREATED;
	}

cleanup:
	/* Make sure the other threads aren't waiting for us */
	if (hRendezvousInit) Rendezvous_force(hRendezvousInit);
	if (hRendezvousLoader) Rendezvous_force(hRendezvousLoader);
	if (hRendezvousLoop) Rendezvous_force(hRendezvousLoop);
	if (hPauseProcess) Pause_off(hPauseProcess);
	if (hPausePrime) Pause_off(hPausePrime);

	if (initMask & SPEECHTHREADCREATED) {
		if (pthread_join(speechThread, &ret) == 0) {
			if (ret == THREAD_FAILURE) {
				status = EXIT_FAILURE;
			}
		}
	}

	if (initMask & LOADERTHREADCREATED) {
		if (pthread_join(loaderThread, &ret) == 0) {
			if (ret == THREAD_FAILURE) {
				status = EXIT_FAILURE;
			}
		}
	}

	if (initMask & VIDEOTHREADCREATED) {
		if (pthread_join(videoThread, &ret) == 0) {
			if (ret == THREAD_FAILURE) {
				status = EXIT_FAILURE;
			}
		}
	}

	if (initMask & DISPLAYTHREADCREATED) {
		if (pthread_join(displayThread, &ret) == 0) {
			if (ret == THREAD_FAILURE) {
				status = EXIT_FAILURE;
			}
		}
	}

	if (displayEnv.hOutFifo) {
		Fifo_delete(displayEnv.hOutFifo);
	}

	if (displayEnv.hInFifo) {
		Fifo_delete(displayEnv.hInFifo);
	}

	if (hRendezvousLoop) {
		Rendezvous_delete(hRendezvousLoop);
	}

	if (hRendezvousCleanup) {
		Rendezvous_delete(hRendezvousCleanup);
	}

	if (hRendezvousInit) {
		Rendezvous_delete(hRendezvousInit);
	}

	if (hPauseProcess) {
		Pause_delete(hPauseProcess);
	}

	if (hPausePrime) {
		Pause_delete(hPausePrime);
	}


	system("sync");
	system("echo 3 > /proc/sys/vm/drop_caches");

	pthread_mutex_destroy(&gbl.mutex);

	if (args.interface) {
		/* Launch the demo selection interface when exiting */
		if (execl("./interface", "interface", "-l 4", (char *) NULL) == -1) {
			status = EXIT_FAILURE;
		}
	}

	exit(status);
}

Schematic  is....

dmesg from prompt says. ( I don't know why printk(KERN_DEBUG...) omits some prefix of logicpd device driver functions.)

---------------------------------8<--------------------------------8<------------------------------------

Linux version 2.6.18_pro500-davinci_IPNC_DM365_2.0.0 (root@localhost.localdomain) (gcc version 4.2.0 (MontaVista 4.2.0-16.0.32.080191
4 2008-08-30)) #1 PREEMPT Thu Jan 25 16:29:27 KST 2018
CPU: ARM926EJ-S [41069265] revision 5 (ARMv5TEJ), cr=00053177
Machine: DaVinci DM365 IPNC
Memory policy: ECC disabled, Data cache writeback
On node 0 totalpages: 19456
  DMA zone: 19456 pages, LIFO batch:3
DaVinci DM0365 variant 0x8
PLL0: fixedrate: 24000000, commonrate: 135000000, vpssrate: 270000000
PLL0: vencrate_sd: 27000000, ddrrate: 270000000 mmcsdrate: 135000000
PLL1: armrate: 297000000, voicerate: 20482758, vencrate_hd: 74250000
CPU0: D VIVT write-back cache
CPU0: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets
CPU0: D cache: 8192 bytes, associativity 4, 32 byte lines, 64 sets
Built 1 zonelists.  Total pages: 19456
Kernel command line: mem=76M console=ttyS1,115200n8 root=/dev/ram0 rw initrd=0x82000000,9M ip=none dm365_imp.oper_mode=0 video=davinc
ifb:vid0=640x480x16@0,0:vid1=640x480x16@0,0:osd0=640x480x16@0,0:osd1=640x480x16@0,0 davinci_enc_mngr.ch0_mode=640x480 davinci_enc_mng
r.ch0_output=LCD
PID hash table entries: 512 (order: 9, 2048 bytes)
Clock event device timer0_0 configured with caps set: 07
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)
Memory: 76MB = 76MB total
Memory: 64804KB available (2236K code, 545K data, 176K init)
Calibrating delay loop... 148.27 BogoMIPS (lpj=741376)
Mount-cache hash table entries: 512
CPU: Testing write buffer coherency: ok
checking if image is initramfs...it isn't (bad gzip magic numbers); looks like an initrd
Freeing initrd memory: 9216K
NET: Registered protocol family 16
DaVinci: 104 gpio irqs
MUX: initialized GIO80_EXTCLK
MUX: initialized SPI0_SDENA1
DM365 IPIPE initialized in Continuous mode
Generic PHY: Registered new driver
ch0 default output "LCD", mode "640x480"
be_encoder_setoutput>
Setting output to Composite
Start of vpbe_encoder_setmode..
pbe_encoder_setmode>
pbe_encoder_setoutput>
VPBE Encoder initialized
be_encoder_enumoutput>
pbe_encoder_enumoutput>
be_encoder_enumoutput>
pbe_encoder_enumoutput>
be_encoder_enumoutput>
pbe_encoder_enumoutput>
be_encoder_getoutput>
pbe_encoder_getoutput>
be_encoder_getmode>
be_encoder_getmode/>
VPBE Encoder Initialized
VPBE Encoder de-initialized
gicpd_encoder_setoutput>
Start of logicpd_encoder_setmode..
ogicpd_encoder_setoutput>
LogicPD Encoder initialized
gicpd_encoder_enumoutput>
ogicpd_encoder_enumoutput>
gicpd_encoder_setoutput>
Start of logicpd_encoder_setmode..
ogicpd_encoder_setoutput>
Start of logicpd_encoder_setmode..
gicpd_encoder_getoutput>
ogicpd_encoder_getoutput>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
MUX: initialized GIO82_LCD_OE
MUX: initialized VOUT_HVSYNC
LogicPD encoder initialized
MUX: initialized SD1_DATA0
NET: Registered protocol family 2
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)
TCP established hash table entries: 4096 (order: 2, 16384 bytes)
TCP bind hash table entries: 2048 (order: 1, 8192 bytes)
TCP: Hash tables configured (established 4096 bind 2048)
TCP reno registered
Initializing Cryptographic API
io scheduler noop registered
io scheduler anticipatory registered (default)
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
davincifb davincifb.0: dm_osd0_fb: 640x480x16@0,0 with framebuffer size 600KB
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
davincifb davincifb.0: dm_vid0_fb: 640x480x16@0,0 with framebuffer size 900KB
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
davincifb davincifb.0: dm_osd1_fb: 640x480x16@0,0 with framebuffer size 600KB
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
davincifb davincifb.0: dm_vid1_fb: 640x480x16@0,0 with framebuffer size 900KB
DAVINCI-WDT: DaVinci Watchdog Timer: heartbeat 60 sec
imp serializer initialized
davinci_previewer initialized
davinci_resizer initialized
Serial: 8250/16550 driver $Revision: 1.90 $ 2 ports, IRQ sharing disabled
serial8250.0: ttyS0 at MMIO map 0x1c20000 mem 0xfbc20000 (irq = 40) is a 16550A
serial8250.0: ttyS1 at MMIO map 0x1d06000 mem 0xfbd06000 (irq = 41) is a 16550A
RAMDISK driver initialized: 1 RAM disks of 9216K size 512 blocksize
Fixed PHY: Registered new driver
MUX: initialized SPI1_SCLK
Davinci EMAC MII Bus: probed
MAC address is deadbeaf
TI DaVinci EMAC Linux version updated 4.0
Linux video capture interface: v2.00
vpfe_init
MUX: initialized VOUT_COUTL_EN
MUX: initialized VOUT_COUTH_EN

starting ccdc_reset...<7>
End of ccdc_reset...<5>vpfe_probe
vinci_display_init>
Trying to register davinci display video device.
layer=c28b6600,layer->video_dev=c28b6760
Trying to register davinci display video device.
layer=c28b6400,layer->video_dev=c28b6560
davinci_init:DaVinci V4L2 Display Driver V1.0 loaded
avinci_init>
i2c /dev entries driver
MUX: initialized GIO79_VCLK
davinci-mmc davinci-mmc.0: Supporting 4-bit mode
davinci-mmc davinci-mmc.0: Using DMA mode
TCP bic registered
NET: Registered protocol family 1
NET: Registered protocol family 17
RAMDISK: cramfs filesystem found at block 0
RAMDISK: Loading 8548KiB [1 disk] into ram disk... <6>Time: timer0_1 clocksource has been installed.
Clock event device timer0_0 configured with caps set: 08
Switched to high resolution mode on CPU 0
<6>mmcblk0: mmc0:0001 00000 31260672KiB
done.
 mmcblk0:VFS: Mounted root (cramfs filesystem) readonly.
Freeing init memory: 176K
 p1
CMEMK module: built on Oct 27 2017 at 19:37:37
  Reference Linux version 2.6.18
  File /home/ciel/work/minienc/dvsdk_2_10_01_18/linuxutils_2_24_03/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
allocated heap buffer 0xc6000000 of size 0x1d2000
CMEM Range Overlaps Kernel Physical - allowing overlap
CMEM phys_start (0x1000) overlaps kernel (0x80000000 -> 0x84c00000)
cmemk initialized
IRQK module: built on Oct 27 2017 at 19:37:39
  Reference Linux version 2.6.18
  File /home/ciel/work/minienc/dvsdk_2_10_01_18/linuxutils_2_24_03/packages/ti/sdo/linuxutils/irq/src/module/irqk.c
irqk initialized
EDMAK module: built on Oct 27 2017 at 19:37:38
  Reference Linux version 2.6.18
  File /home/ciel/work/minienc/dvsdk_2_10_01_18/linuxutils_2_24_03/packages/ti/sdo/linuxutils/edma/src/module/edmak.c
be_encoder_enumoutput>
pbe_encoder_enumoutput>
be_encoder_enumoutput>
pbe_encoder_enumoutput>
be_encoder_enumoutput>
pbe_encoder_enumoutput>
gicpd_encoder_enumoutput>
ogicpd_encoder_enumoutput>
LogicPD Encoder de-initialized
gicpd_encoder_setoutput>
Start of logicpd_encoder_setmode..
ogicpd_encoder_setoutput>
LogicPD Encoder initialized
gicpd_encoder_setoutput>
Start of logicpd_encoder_setmode..
ogicpd_encoder_setoutput>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
gicpd_encoder_getoutput>
ogicpd_encoder_getoutput>
gicpd_encoder_getmode>
ogicpd_encoder_getmode>
Start of logicpd_encoder_setmode..
Invalid id...
gicpd_encoder_getmode>
ogicpd_encoder_getmode>