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>
