[MPlayer-dev-eng] mplayer slave suggestion

Chandan Pitta chandan.pitta at gmail.com
Thu Oct 12 22:54:22 CEST 2006


Not sure what exactly you need. Yes mplayer dumps everything on the
output and you have to parse the output to get what you need. I wrote
a small application a while ago for an embedded system that uses
mplayer to play audio and video files. Basically it loads up mplayer
in "-idle -slave" mode and reads commands such as "play", "pause",
"loadfile" from a java application using a file and sends proper
commands to the mplayer process. It also parses the output from
mplayer to obtain details like total time, current position, artist,
title, album, audio and video bitrates etc. take a look at the code.
All you need to understand is sendInfo() and sendCommand().

Also here is the link to a demo of the java application that uses
mplayer via C++ code:
http://video.google.com/videoplay?docid=2746307597104554801



On 10/11/06, Kevron Rees <kev000 at email.com> wrote:
> hello,
>
> If I may make a suggestion about the mplayer slave documentation:  After searching google for hours trying to find a suitable solution I have come to the conclusion that example code on the use of mplayer as a slave application to a front-end is lacking.  I am making a front-end using mplayer in a car computer setting.  This, to my knowledge has never been done so I needed to start from scratch.  I have no problem writing commands to mplayer.  sending a write(write_fd[1]...) works without problem, but when I want to read read(read_fd[0]...) I get everything that mplayer outputs when it starts up (i.e. "...CPU runtime detection..." etc etc). I know you guys are working hard developing mplayer but if anyone has an idea of where I can find additional info or example code I would be most grateful.  If there is no current documentation or example code if anyone is willing to help me solve my simple problem I would be more than happy to write and document a great howto on using mplayer as a slave.  This would help any future users in my situation find the resources they need without spamming the dev mailing lists.  Thanks in advance for any help.
>
> -Kev
>
> P.S. if some noble soul is willing to help me here is my example code:
> http://nextabyte.com/nanonymous/current/example-code.txt
>
> --
> ___________________________________________________
> Play 100s of games for FREE! http://games.mail.com
>
> _______________________________________________
> MPlayer-dev-eng mailing list
> MPlayer-dev-eng at mplayerhq.hu
> http://lists.mplayerhq.hu/mailman/listinfo/mplayer-dev-eng
>
-------------- next part --------------
// TODO: synchronize commpipe0 and commpipe1
// TODO: optimize to clear pause buffers in ao_pcm and here
// TODO: kill all mplayer threads in sig_handler

#include <sys/shm.h>
#include <sys/stat.h>
#include <signal.h>
#include <sys/sem.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/wait.h>
#include <strings.h>
#include <sys/timeb.h>

#include "ChandanSoundEngine.h"

union semun {
	int              val;    /* Value for SETVAL */
	struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
	unsigned short  *array;  /* Array for GETALL, SETALL */
	struct seminfo  *__buf;  /* Buffer for IPC_INFO (Linux specific) */
};

SOUNDM_Audio_NormalDevice *pDev_;
char *buffer_ = 0;
int segmentID_ = -1, semaphoreID_ = -1;
int BUFFER_SIZE = 65536;
FILE *in_fp_, *out_fp_;
pthread_t soundThreadID_, mediaThreadID_;
int pipeIn_[2], pipeOut_[2];
int playerState_ = PLAYER_STATE_STOPPED;
int mediaTime_ = 0;
timeb lastCmdTime;

int writeToSoundDevice(char *buffer, int wc)
{
	int ret = pDev_->write((short *)buffer, wc >> 1);	// we do >> 1 since we are transfering
														// shorts from char buffer (8 bits to 16 bits)
	if (ret < 0) {
		return wc;
	}
					
	return (ret << 1);
}

int writeRequiredBytes(char *buffer, int ac)
{
	// write only WRITE_SIZE bytes, so as to avoid blocking read thread until we write all data in buffer. 
	// Doing that is as bad as having everything done in one thread. So we write a chunk and free that 
	// space in the buffer for the read thread to use.
	
	if (ac >= WRITE_SIZE) {	// if we have more bytes available than the number of bytes needed to write
		//printf("Required: %d\n", WRITE_SIZE);
		return writeToSoundDevice(buffer, WRITE_SIZE);		// write the required bytes
	}
	else {
		//printf("Required: %d\n", ac);
		return writeToSoundDevice(buffer, ac);	// write the rest of buffer. We do not loop back and write more data 
												// until wc becomes 0. The rest of the data will be written in the 
												// next loop. So its better to have BUFFER_SIZE as an integer 
												// multiple of WRITE_SIZE so we do not come to this section of code 
												// which writes partial data
	}
}

void printQueue(int head, int tail)
{
	for (int i=0; i<BUFFER_SIZE/1024; i++) {
		if (i == head / 1024)
			printf("H");
		else if (i == tail / 1024)
			printf("T");
		else
			printf(".");
	}
	printf("\n");
}

void *dataWriterThread(void *data)
{
	nice(-5);
	printf("dataWriterThread() ---> Data writer thread started\n");
	int head, tail;
	while (1) {		// loop for ever
		while (1) {	// write until the buffer is empty
			if (!semctl(semaphoreID_, M_PLAY, GETVAL)) {
				printf("dataWriterThread() ---> Paused\n");
				break;
			}
			head = semctl(semaphoreID_, HEAD, GETVAL) << SHIFT_BITS;
			tail = semctl(semaphoreID_, TAIL, GETVAL) << SHIFT_BITS;
			
			if (head == tail) break;	// end loop if there is no more data
			
			int wc;
			if (tail > head) {		// need to write the rest of buffer and then write upto head
				wc = writeRequiredBytes(buffer_ + tail, BUFFER_SIZE - tail);
			}
			else { 	// meaning we don't have to wrap around for the data
				wc = writeRequiredBytes(buffer_ + tail, head - tail);
			}
			
			tail += wc;
			if (tail == BUFFER_SIZE)
				tail = 0;
			//printQueue(head, tail);
			
			union semun argument;
			if (!semctl(semaphoreID_, RESET, GETVAL)) {
				argument.val = tail >> SHIFT_BITS;
				semctl(semaphoreID_, TAIL, SETVAL, argument);
			}
			else {
				printf("dataWriterThread() ---> Buffer got reset\n");
				pDev_->flush();
				argument.val = 0;
				semctl(semaphoreID_, RESET, SETVAL, argument);
			}
			//printQueue(head, tail);
		}
		
		//printf("dataWriterThread() ---> waiting\n");
		struct sembuf operations[1];
		operations[0].sem_num = DATA_ARRIVED;
		operations[0].sem_op = -1;
		operations[0].sem_flg = SEM_UNDO;
		semop(semaphoreID_, operations, 1);
	}
}

void allDone(int retval)
{
	printf("allDone() ---> All done exiting now\n");
	if (buffer_ != NULL) {
		// detach shared memory
		shmdt(buffer_);
	}
	if (segmentID_ >= 0) {
		// deallocate shared memory
		shmctl(segmentID_, IPC_RMID, 0);
	}
	if (semaphoreID_ >= 0)  {
		// deallocate shared memory
		semctl(semaphoreID_, NUM_SEMS, IPC_RMID, 0);
	}
	if (in_fp_ != NULL) {
		fclose(in_fp_);
	}	
	if (out_fp_ != NULL) {
		fclose(out_fp_);
	}	
	exit(retval);
}

static void exit_sighandler(int x) {
	printf("exit_sighandler() ---> Caught signal: %d\n", x);
	// TODO: exit cleanly based on the type of signal
	switch(x){
		case SIGHUP:     //         1       Exit       Hangup (see termio(7I))
		case SIGINT:     //         2       Exit       Interrupt (see termio(7I))
		case SIGQUIT:    //         3       Core       Quit (see termio(7I))
		case SIGILL:     //         4       Core       Illegal Instruction
		case SIGTRAP:    //         5       Core       Trace or Breakpoint Trap
		case SIGABRT:    //         6       Core       Abort
//		case SIGEMT:     //         7       Core       Emulation Trap
		case SIGFPE:     //         8       Core       Arithmetic Exception
		case SIGKILL:    //         9       Exit       Killed
		case SIGBUS:     //         10      Core       Bus Error
		case SIGSEGV:    //         11      Core       Segmentation Fault
		case SIGSYS:     //         12      Core       Bad System Call
		case SIGPIPE:    //         13      Exit       Broken Pipe
		case SIGALRM:    //         14      Exit       Alarm Clock
		case SIGTERM:    //         15      Exit       Terminated
		case SIGPOLL:    //         22      Exit       Pollable Event (see streamio(7I))
		case SIGSTOP:    //         23      Stop       Stopped (signal)
		case SIGTSTP:    //         24      Stop       Stopped (user) (see termio(7I))
		case SIGCONT:    //         25      Ignore     Continued
		case SIGTTIN:    //         26      Stop       Stopped (tty input) (see termio(7I))
		case SIGTTOU:    //         27      Stop       Stopped (tty output) (see termio(7I))
		case SIGVTALRM:  //         28      Exit       Virtual Timer Expired
		case SIGPROF:    //         29      Exit       Profiling Timer Expired
		case SIGXCPU:    //         30      Core       CPU time limit exceeded (see getrlimit(2))
		case SIGXFSZ:    //         31      Core       File size limit exceeded (see getrlimit(2))
			allDone(100);
		
		case SIGUSR1:    //         16      Exit       User Signal 1
		case SIGUSR2:    //         17      Exit       User Signal 2
		case SIGCHLD:    //         18      Ignore     Child Status Changed
		case SIGPWR:     //         19      Ignore     Power Fail or Restart
		case SIGWINCH:   //         20      Ignore     Window Size Change
		case SIGURG:     //         21      Ignore     Urgent Socket Condition
//		case SIGWAITING: //         32      Ignore     Concurrency signal reserved by threads library
//		case SIGLWP:     //         33      Ignore     Inter-LWP signal reserved by  threads library
//		case SIGFREEZE:  //         34      Ignore     Check point Freeze
//		case SIGTHAW:    //         35      Ignore     Check point Thaw
//		case SIGCANCEL:  //         36      Ignore     Cancellation signal reserved by threads library
		default:
			return;
	}
}

void initAudio()
{
	// Catch signals
	signal(SIGCHLD, exit_sighandler);
	//========= Catch terminate signals: ================
	// terminate requests:
	signal(SIGTERM,exit_sighandler); // kill
	signal(SIGHUP,exit_sighandler);  // kill -HUP  /  xterm closed
	signal(SIGINT,exit_sighandler);  // Interrupt from keyboard
	signal(SIGQUIT,exit_sighandler); // Quit from keyboard
	// fatal errors:
	signal(SIGBUS,exit_sighandler);  // bus error
	signal(SIGSEGV,exit_sighandler); // segfault
	signal(SIGILL,exit_sighandler);  // illegal instruction
	signal(SIGFPE,exit_sighandler);  // floating point exc.
	signal(SIGABRT,exit_sighandler); // abort()
	
	printf("main() ---> Buffer size: %d\n", BUFFER_SIZE);
	printf("main() ---> Write size: %d\n", WRITE_SIZE);
	printf("main() ---> Creating key for semaphore\n");
	key_t keyS = ftok("ChandanSoundEngine", 'S');
	printf("main() ---> Allocating semaphore\n");
	// create the following semaphores
	// 1. for head
	// 2. for tail
	// 3. for signaling new data arrival
	semaphoreID_ = semget(keyS, NUM_SEMS, IPC_CREAT | 0666);
	if (semaphoreID_ == -1) {
		perror("main() ---> Failed to create semaphores\n");
		allDone(1);
	}
	
	printf("main() ---> Initializing semaphores\n");
	union semun arguments;
	unsigned short values[NUM_SEMS];
	for (int i=0; i<NUM_SEMS; i++) {
		values[i] = 0;
	}
	arguments.array = values;
	if (semctl(semaphoreID_, NUM_SEMS, SETALL, arguments) < 0) {
		perror("main() ---> Failed to initialize semaphores");
		allDone(2);
	}
	
	printf("main() ---> Creating key for buffer segment\n");
	key_t keyB = ftok("ChandanSoundEngine", 'B');
	printf("main() ---> Allocating segment");
	segmentID_ = shmget(keyB, BUFFER_SIZE, IPC_CREAT | 0666);
	if (segmentID_ == -1) {
		perror("main() ---> Failed to create segment");
		allDone(3);
	}
	
	printf("main() ---> Obtaining segment address\n");
	buffer_ = (char *)shmat(segmentID_, NULL, SHM_RND);
	if (buffer_ == (char *)-1) {
		printf("main() ---> Failed to obtain segment address\n");
		allDone(4);
	}
	
	printf("main() ---> Determining segment size\n");
	struct shmid_ds shmbuffer;
	shmctl(segmentID_, IPC_STAT, &shmbuffer);
	BUFFER_SIZE = shmbuffer.shm_segsz;
	printf("main() ---> Buffer size: %d bytes\n", BUFFER_SIZE);
	
	printf("main() ---> Obtaining audio device\n");
	pDev_ = new SOUNDM_Audio_NormalDevice();
	if (pDev_ < 0) {
		printf("main() ---> Audio device failed\n");
		allDone(5);
	}
	pDev_->setAudioDevice(44100, 2, 2);
	pDev_->setVolume(1);
	
	printf("main() ---> Starting thread\n");
	pthread_create(&soundThreadID_, NULL, dataWriterThread, NULL);
}

int getChar(FILE *fp)
{
	int retval;
	while(1) {
		retval = fgetc(fp);
		if (retval != -1) {
			break;
		}
		usleep(DELAY);
	}
	return retval;
}

long getLong(FILE *fp) 
{
	long retval = 0;
	int i = 0;
	for (i=0; i<8; i++) {
		retval = (retval << 8) + getChar(fp);
	}
	return retval;
}

long getInt(FILE *fp) 
{
	long retval = 0;
	int i = 0;
	for (i=0; i<4; i++) {
		retval = (retval << 8) + getChar(fp);
	}
	return retval;
}

void getString(char *str, int len, FILE *fp)
{
	while(1) {
		if (fgets(str, len, fp) != NULL) {
			break;
		}
		usleep(DELAY);
	}
}

void sendCommand(char *cmd)
{
	write(pipeOut_[1], cmd, strlen(cmd));
}

void writeUTF(FILE *fp, char *buf)
{
	int len = strlen(buf);
	// for UTF the next 2 bytes should be he length of the string
	putc((len >> 8) & 0xff, fp);
	putc(len & 0xff, fp);
	fprintf(fp, "%s", buf);
}

void setAudioParms(char *buf)
{
	int hz, ch, bps;
	char s;
	
	sscanf(buf, "%d Hz, %d ch, %c%dle", &hz, &ch, &s, &bps);
	bps >>= 3;
	printf("setAudio() ---> setting audio to %d hz, %d ch, %d bps\n", hz, ch, bps);
	pDev_->setAudioDevice(hz, ch, bps);
}

void sendInfo(char *buf)
{
	char *msgs[20] = { 
		"Failed to open",		// 0
		"Starting playback...",	// 1
		" Title:",				// 2
		" Artist:",				// 3
		" Album:",				// 4
		" Year:",				// 5
		" Comment:",			// 6
		" Genre:", 				// 7
		"ANS_TIME_POSITION",	// 8
		"ANS_LENGTH", 			// 9
		"EOF",					// 10
		"AUDIO:",				// 11
		"VIDEO:"				// 12
	};
	
	for (int i=0; i<13; i++) {
		int msgLen = strlen(msgs[i]);
		if (strncmp(buf, msgs[i], msgLen) == 0) {
			putc(i, out_fp_);
			if (i != 0 && i != 1 && i != 10) {
				buf = buf + msgLen + 1;
				// for media time we should store the values
				if (i == 8 || i == 9) {
					char *buf1 = index(buf, '.');
					if (buf1 != NULL)
						buf1[0] = 0;
				}
				
				// if we got some audio info set the values to the local device
				if (i == 11) {
					setAudioParms(buf);
				}
				writeUTF(out_fp_, buf);
			}
			fflush(out_fp_);
			break;
		}
	}
}

void *mediaPlayerThread(void *data)
{
	pid_t pid;
	
	// keep creating mplayer process endlessly if the process exits
	while (1) {
		/* Setup communication pipeline first */
		if (pipe(pipeIn_)) {
			fprintf(stderr,"Pipe error!\n");
			allDone(10);
		}

		/* Setup communication pipeline first */
		if (pipe(pipeOut_)) {
			fprintf(stderr,"Pipe error!\n");
			allDone(11);
		}

		/* Attempt to fork and check for errors */
		if ((pid = fork()) == -1){
			fprintf(stderr,"Fork error. Exiting.\n");  /* something went wrong */
			allDone(12);
		}
	
		if (pid) {
			/* A positive (non-negative) PID indicates the parent process */
			//dup2(commpipeParent[1],1);	/* Replace stdout with out side of the pipe */
			close(pipeOut_[0]);	/* Close unused side of pipe (in side) */
			//dup2(commpipeChild[0],0);	/* Replace stdin with the in side of the pipe */
			close(pipeIn_[1]);	/* Close unused side of pipe (out side) */
			//sleep(5);
			//write(commpipe1[1], "quit\n", 5);
			//waitpid(pid, NULL, 0);
			
			FILE *infp = fdopen(pipeIn_[0], "r");
			char buf[CMD_BUFFER_SIZE];
			while (1) {
				fgets(buf, CMD_BUFFER_SIZE, infp);
				sendInfo(buf);
			}
			fclose(infp);
			
			// if we are here that means the child process has exited
			close(pipeOut_[1]);	/* Close unused side of pipe (out side) */
			close(pipeIn_[0]);	/* Close unused side of pipe (out side) */
			// better kill the child if it is still alive
			kill(pid, SIGKILL);
		}
		else{
			nice(-5);
			/* A zero PID indicates that this is the child process */
			dup2(pipeIn_[1], 1);	/* Replace stdout with out side of the pipe */
			//close(commpipe0[0]);	/* Close unused side of pipe (in side) */
			dup2(pipeOut_[0], 0);	/* Replace stdin with the in side of the pipe */
			dup2(1, 2);		// divert stderr to stdout
			//close(commpipe1[1]);	/* Close unused side of pipe (out side) */
			setvbuf(stdout,(char*)NULL,_IONBF,0);	/* Set non-buffered output on stdout */
			setvbuf(stdin,(char*)NULL,_IONBF,0);	/* Set non-buffered output on stdin */
			/* Replace the child fork with a new process */
			if(execl("mplayer", "mplayer", "-autosync", "100", "-ac", "mad,", "-ao", "pcm", "-vo", "fbdev", "-bpp", "19",
					"-fs", "-dr", "-delay", "0.8", "-fixed-vo", "-quiet", "-slave", "-idle", "-v", NULL) == -1) {
				fprintf(stderr,"execl Error!");
				allDone(13);
			}
		}
	}
}

void doWait()
{
	long oldTime = lastCmdTime.time*1000l + lastCmdTime.millitm;
	while (1) {
		struct timeb t_current;
		ftime(&t_current);
		long curTime = t_current.time*1000l + t_current.millitm;
		if (curTime - oldTime >= CMD_WAIT_TIME)
			break;
		usleep(10000l);
	}
}

int waitMore()
{
	long oldTime = lastCmdTime.time*1000l + lastCmdTime.millitm;
	struct timeb t_current;
	ftime(&t_current);
	long curTime = t_current.time*1000l + t_current.millitm;
	if (curTime - oldTime < CMD_WAIT_TIME)
		return 1;
	return 0;
}

int main(void)
{
	char cmdBuff[CMD_BUFFER_SIZE];			// select a buffer large enough to read long filenames
	int volume = 3;
	initAudio();
	pthread_create(&mediaThreadID_, NULL, mediaPlayerThread, NULL);
	printf("main() ---> waiting for thread to join (endless wait)\n");
	//pthread_join(soundThreadID_, NULL);
	//allDone(0);
	
	printf("main() ---> Opening file %s\n", IN_FILE);
	// delete old file
	unlink(IN_FILE);
	// create and close the file again
	close(creat(IN_FILE, 0666));
	in_fp_ = fopen(IN_FILE, "r");
	chmod(IN_FILE, 0666);
	
	printf("main() ---> Opening file %s\n", OUT_FILE);
	// delete old file
	unlink(OUT_FILE);
	// create and close the file again
	close(creat(OUT_FILE, 0666));
	chmod(OUT_FILE, 0666);
	out_fp_ = fopen(OUT_FILE, "w");
	
	// keep receiving connections from clients for ever
	while (1) {
		// as long as the connection is open read the command in blocking mode
		printf("main() ---> waiting for command\n");
		int cmd = getChar(in_fp_);
		printf("main() ---> received command: %d\n", cmd);
		
		// take action based on the command
		switch(cmd) {
			case LOAD_FILE:
				printf("main() ---> [ LOAD_FILE ] waiting for filename\n");
				// read the file name
				getString(cmdBuff, CMD_BUFFER_SIZE, in_fp_);
				printf("main() ---> [ LOAD_FILE ] obtained filename: %s\n", cmdBuff);
				playerState_ = PLAYER_STATE_PAUSED;
				
/*				fclose(in_fp_);
				truncate(IN_FILE, 0);
				in_fp_ = fopen(IN_FILE, "r");
				fclose(out_fp_);
				truncate(OUT_FILE, 0);
				out_fp_ = fopen(OUT_FILE, "w");*/
				
				printf("main() ---> [ LOAD_FILE ] sending filename to mplayer\n");
				// mute before loading the file
				sendCommand(LOAD_CMD);
				// fortunately the filename end with '\n' so no need to send it after the filename
				sendCommand(cmdBuff);
				//sendCommand(PAUSE_CMD);
				printf("main() ---> [ LOAD_FILE ] done loading file\n");
				ftime(&lastCmdTime);
				break;
				
			case PLAY:
				// This message is received after LOAD_FILE or after PAUSE
				// in either case the player is waiting for a signal from this thread
				if (playerState_ != PLAYER_STATE_PAUSED) {
					printf("main() ---> [ PLAY ] player is not in paused state, ignoring command\n");
				}
				else {
					ftime(&lastCmdTime);
					printf("main() ---> [ PLAY ] changing state to playing\n");
					playerState_ = PLAYER_STATE_PLAYING;
					printf("main() ---> [ PLAY ] sending pause command\n");
					sendCommand(PAUSE_CMD);
				}
				break;
				
			case PAUSE:	
				// This message is received only after a PLAY message
				if (playerState_ != PLAYER_STATE_PLAYING) {
					printf("main() ---> [ PAUSE ] player is not in playing state, ignoring command\n");
				}
				else {
					ftime(&lastCmdTime);
					printf("main() ---> [ PAUSE ] changing state to paused\n");
					playerState_ = PLAYER_STATE_PAUSED;
					printf("main() ---> [ PAUSE ] sending pause command\n");
					sendCommand(PAUSE_CMD);
				}
				break;
				
			case CLOSE_FILE:
				if (playerState_ == PLAYER_STATE_PLAYING) {
					ftime(&lastCmdTime);
					printf("main() ---> [ CLOSE_FILE ] sending pause command\n");
					sendCommand(PAUSE_CMD);
				}
				printf("main() ---> [ CLOSE_FILE ] changing state to stopped\n");
				playerState_ = PLAYER_STATE_STOPPED;
				// nothing else to do!
				break;
				
			case SET_VOLUME:
				volume = getChar(in_fp_);
				printf("main() ---> [ SET_VOLUME ] setting volume %d\n", volume);
				pDev_->setVolume(volume);
				break;
				
			case SET_MEDIA_TIME:
				printf("main() ---> [ SET_MEDIA_TIME ] waiting for time\n");
				mediaTime_ = getInt(in_fp_);
				printf("main() ---> [ SET_MEDIA_TIME ] setting media time to %ld\n", time);
				sendCommand(SEEK_CMD_HEAD);
				sprintf(cmdBuff, "%d", mediaTime_);
				sendCommand(cmdBuff);
				sendCommand(SEEK_CMD_TAIL);
				break;
			
			case GET_MEDIA_TIME:
				//printf("main() ---> [ GET_MEDIA_TIME ] obtaining time\n");
				//doWait();
				if (!waitMore())
					sendCommand(MEDIA_TIME_CMD);
/*				if (!waitMore())
					sendCommand(MEDIA_TIME_CMD);
				sprintf(cmdBuff, "%d", mediaTime_);
				putc(8, out_fp_);
				writeUTF(out_fp_, cmdBuff);
				fflush(out_fp_);*/
				break;
			
			case GET_MEDIA_DURATION:
				//printf("main() ---> [ GET_MEDIA_DURATION ] obtaining time\n");
				//doWait();
				if (!waitMore())
					sendCommand(MEDIA_DURATION_CMD);
/*				if (!waitMore())
					sendCommand(MEDIA_DURATION_CMD);
				sprintf(cmdBuff, "%d", duration_);
				putc(9, out_fp_);
				writeUTF(out_fp_, cmdBuff);
				fflush(out_fp_);*/
				break;
				
			case SEND_MPLAYER_CMD:
				printf("main() ---> [ SEND_MPLAYER_CMD ] waiting for mplayer command\n");
				cmd = getChar(in_fp_);
				char *cmdStr;
				printf("main() ---> [ SEND_MPLAYER_CMD ] got %d\n", cmd);
				switch (cmd) {
					case 1:
						cmdStr = "pausing_keep contrast -5\n";
						break;
					case 2:
						cmdStr = "pausing_keep contrast +5\n";
						break;
					case 3:
						cmdStr = "pausing_keep brightness -5\n";
						break;
					case 4:
						cmdStr = "pausing_keep brightness +5\n";
						break;
					case 7:
						cmdStr = "pausing_keep saturation -5\n";
						break;
					case 8:
						cmdStr = "pausing_keep saturation +5\n";
						break;
				}
				printf("main() ---> [ SEND_MPLAYER_CMD ] command: %s\n", cmdStr);
				sendCommand(cmdStr);
				break;
				
			case RESTART:
				fclose(in_fp_);
				truncate(IN_FILE, 0);
				in_fp_ = fopen(IN_FILE, "r");
				fclose(out_fp_);
				truncate(OUT_FILE, 0);
				out_fp_ = fopen(OUT_FILE, "w");
				break;
		}
	}			
}




More information about the MPlayer-dev-eng mailing list