📄 main.c
字号:
/* * main.c * * ============================================================================ * Copyright (c) Texas Instruments Inc 2005 * * 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. * ============================================================================ *//* Standard Linux headers */#include <stdio.h>#include <errno.h>#include <fcntl.h>#include <stdlib.h>#include <getopt.h>#include <unistd.h>#include <string.h>#include <pthread.h>#include <sys/ioctl.h>#include <sys/resource.h>/* Davinci specific kernel headers */#include <video/davincifb.h>/* Codec Engine headers */#include <xdc/std.h>#include <ti/sdo/ce/Engine.h>#include <ti/sdo/ce/trace/gt.h>#include <ti/sdo/ce/CERuntime.h>#include <ti/sdo/ce/utils/trace/TraceUtil.h>/* Demo headers */#include <rendezvous.h>#include "decode.h"#include "video.h"#include "audio.h"#include "speech.h"#include "ctrl.h"/* The levels of initialization */#define LOGSINITIALIZED 0x1#define RENDEZVOUSOPENED 0x2#define VIDEOTHREADCREATED 0x4#define AUDIOTHREADCREATED 0x8#define SPEECHTHREADCREATED 0x10typedef struct Args { SpeechDecoder speechDecoder; AudioDecoder audioDecoder; VideoDecoder videoDecoder; char *speechFile; char *audioFile; char *videoFile; int loop; int keyboard; int time; int interface;} Args;/* Global variable declarations for this application */GlobalData gbl = { 0, 1, 0, 0, 0, 0, 0, FALSE, NOSTD };/****************************************************************************** * usage ******************************************************************************/static void usage(void){ printf("Usage: decode [options]\n\n" "Options:\n" "-a | --audiofile Audio file to play\n" "-s | --speechfile Speech file to play\n" "-v | --videofile Video file to play\n" "-k | --keyboard Enable keyboard interface\n" "-t | --time Number of seconds to run the demo [infinite]\n" "-l | --loop Loop to beginning of files when done [off]\n" "-i | --interface Launch the demo interface when exiting [off]\n" "-h | --help Print this message\n\n" "You must supply at least a video or a speech or an audio file\n" "with appropriate extensions for the file formats.\n" "You must NOT supply BOTH an audio and a speech file.\n\n");}/****************************************************************************** * parseArgs ******************************************************************************/static void parseArgs(int argc, char *argv[], Args *argsp){ const char shortOptions[] = "a:s:v:kt:lih"; const struct option longOptions[] = { {"audiofile", required_argument, NULL, 'a'}, {"speechfile", required_argument, NULL, 's'}, {"videofile", required_argument, NULL, 'v'}, {"keyboard", no_argument, NULL, 'k'}, {"time", required_argument, NULL, 't'}, {"loop", no_argument, NULL, 'l'}, {"interface", no_argument, NULL, 'i'}, {"help", no_argument, NULL, 'h'}, {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 'a': extension = rindex(optarg, '.'); if (extension == NULL) { fprintf(stderr, "Audio file without extension: %s\n", optarg); exit(EXIT_FAILURE); } if (strcmp(extension, ".mp2") == 0) { argsp->audioDecoder = MPEG1L2_AUDIO_DECODER; } else if (strcmp(extension, ".aac") == 0) { argsp->audioDecoder = MPEG2AAC_AUDIO_DECODER; } else { fprintf(stderr, "Unknown audio file extension: %s\n", extension); exit(EXIT_FAILURE); } argsp->audioFile = optarg; break; case 's': extension = rindex(optarg, '.'); if (extension == NULL) { fprintf(stderr, "Speech file without extension: %s\n", optarg); exit(EXIT_FAILURE); } if (strcmp(extension, ".g711") == 0) { argsp->speechDecoder = G711_SPEECH_DECODER; } else { 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); break; } if (strcmp(extension, ".m2v") == 0) { argsp->videoDecoder = MPEG2_VIDEO_DECODER; } else if (strcmp(extension, ".264") == 0) { argsp->videoDecoder = H264_VIDEO_DECODER; } else if (strcmp(extension, ".mpeg4") == 0) { argsp->videoDecoder = MPEG4_VIDEO_DECODER; } else { fprintf(stderr, "Unknown video file extension: %s\n", extension); exit(EXIT_FAILURE); } argsp->videoFile = optarg; break; case 'k': argsp->keyboard = TRUE; break; case 't': argsp->time = atoi(optarg); break; case 'l': argsp->loop = TRUE; break; case 'i': argsp->interface = TRUE; break; case 'h': usage(); exit(EXIT_SUCCESS); default: usage(); exit(EXIT_FAILURE); } } /* Need at least one file to decode and only one sound file */ if ((!argsp->videoFile && !(argsp->audioFile || argsp->speechFile)) || (argsp->audioFile && argsp->speechFile)) { usage(); exit(EXIT_FAILURE); }}/****************************************************************************** * detectVideoStandard ******************************************************************************/static int detectVideoStandard(void){ int fd; int std; /* Open video display device */ fd = open(FBVID_DEVICE, O_RDWR); if (fd == -1) { ERR("Failed to open fb device %s (%s)\n", FBVID_DEVICE, strerror(errno)); return FAILURE; } /* Query the display device driver for video standard chosen */ if (ioctl(fd, FBIO_GETSTD, &std) == -1) { ERR("Failed to get video standard from display device driver\n"); return FAILURE; } if ((std >> 16) == 0x1) { DBG("NTSC selected\n"); gblSetYFactor(NTSCSTD); } else { DBG("PAL selected\n"); gblSetYFactor(PALSTD); } close(fd); return SUCCESS;}/****************************************************************************** * main ******************************************************************************/int main(int argc, char *argv[]){ unsigned int initMask = 0; int status = EXIT_SUCCESS; int numThreads; struct sched_param schedParam; Rendezvous_Obj rendezvous; pthread_t videoThread; pthread_t audioThread; pthread_t speechThread; VideoEnv videoEnv; AudioEnv audioEnv; SpeechEnv speechEnv; CtrlEnv ctrlEnv; pthread_attr_t attr; void *ret; Args args = { 0, 0, 0, NULL, NULL, NULL, FALSE, FALSE, FOREVER, FALSE }; /* Detect PAL or NTSC */ if (detectVideoStandard() == FAILURE) { cleanup(EXIT_FAILURE); } /* 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(); DBG("Codec Engine initialized\n"); /* Initialize the logs. Must be done after CERuntime_init() */ TraceUtil_start(ENGINE_NAME); initMask |= LOGSINITIALIZED; DBG("Logging initialized\n"); /* Open the object which synchronizes the thread initialization */ numThreads = 1; if (args.videoFile) { numThreads += 2; gbl.targetMask |= VIDEO_DONE; } if (args.speechFile || args.audioFile) { numThreads += 1; gbl.targetMask |= SOUND_DONE; } Rendezvous_open(&rendezvous, numThreads); initMask |= RENDEZVOUSOPENED; DBG("Rendezvous opened for %d threads\n", numThreads); /* 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); } /* Start the video thread if a file name is supplied */ if (args.videoFile) { /* Set the thread priority */ schedParam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 1; if (pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } /* Create the thread */ videoEnv.hRendezvous = &rendezvous; videoEnv.videoFile = args.videoFile; videoEnv.videoDecoder = args.videoDecoder; videoEnv.loop = args.loop; if (pthread_create(&videoThread, &attr, videoThrFxn, &videoEnv)) { ERR("Failed to create video thread\n"); cleanup(EXIT_FAILURE); } initMask |= VIDEOTHREADCREATED; } /* Start the speech thread if a file name is supplied */ if (args.speechFile) { /* Set the thread priority */ schedParam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 2; if (pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } /* Create the thread */ speechEnv.hRendezvous = &rendezvous; speechEnv.speechFile = args.speechFile; speechEnv.speechDecoder = args.speechDecoder; speechEnv.loop = args.loop; if (pthread_create(&speechThread, &attr, speechThrFxn, &speechEnv)) { ERR("Failed to create speech thread\n"); cleanup(EXIT_FAILURE); } initMask |= SPEECHTHREADCREATED; } /* Start the audio thread if a file name is supplied */ if (args.audioFile) { /* Set the thread priority */ schedParam.sched_priority = sched_get_priority_max(SCHED_FIFO) - 2; if (pthread_attr_setschedparam(&attr, &schedParam)) { ERR("Failed to set scheduler parameters\n"); cleanup(EXIT_FAILURE); } /* Create the thread */ audioEnv.hRendezvous = &rendezvous; audioEnv.audioFile = args.audioFile; audioEnv.audioDecoder = args.audioDecoder; audioEnv.loop = args.loop; if (pthread_create(&audioThread, &attr, audioThrFxn, &audioEnv)) { ERR("Failed to create audio thread\n"); cleanup(EXIT_FAILURE); } initMask |= AUDIOTHREADCREATED; } /* Main thread becomes the control thread */ ctrlEnv.hRendezvous = &rendezvous; ctrlEnv.keyboard = args.keyboard; ctrlEnv.time = args.time; ctrlEnv.videoFile = args.videoFile; ctrlEnv.videoDecoder = args.videoDecoder; ctrlEnv.speechFile = args.speechFile; ctrlEnv.speechDecoder = args.speechDecoder; ctrlEnv.audioFile = args.audioFile; ctrlEnv.audioDecoder = args.audioDecoder; ret = ctrlThrFxn(&ctrlEnv); if (ret == THREAD_FAILURE) { status = EXIT_FAILURE; }cleanup: /* Make sure the other threads aren't waiting for init to complete */ Rendezvous_force(&rendezvous); /* Wait until the other threads terminate */ if (initMask & SPEECHTHREADCREATED) { if (pthread_join(speechThread, &ret) == 0) { if (ret == THREAD_FAILURE) { status = EXIT_FAILURE; } } } if (initMask & AUDIOTHREADCREATED) { if (pthread_join(audioThread, &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 & RENDEZVOUSOPENED) { Rendezvous_close(&rendezvous); } if (initMask & LOGSINITIALIZED) { TraceUtil_stop(); } /* Destroy the global mutex */ pthread_mutex_destroy(&gbl.mutex); if (status == EXIT_SUCCESS && args.interface) { if (execl("./interface", "interface", "-l 4", NULL) == -1) { status = EXIT_FAILURE; } } exit(status);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -