[Mvpmc-cvs] mvpmc/src audio.c,1.15,1.16 fb.c,1.20,1.21 gui.c,1.62,1.63 main.c,1.36,1.37 mvpmc.h,1.47
Status: Alpha
Brought to you by:
gettler
From: Jon G. <ge...@us...> - 2005-09-23 03:24:55
|
Update of /cvsroot/mvpmc/mvpmc/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18637/src Modified Files: audio.c fb.c gui.c main.c mvpmc.h playlist.c Log Message: Switch the audio playback for the filebrowser to use a seperate thread, rather than the libwidget idle function. Index: mvpmc.h =================================================================== RCS file: /cvsroot/mvpmc/mvpmc/src/mvpmc.h,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** mvpmc.h 20 Sep 2005 02:05:23 -0000 1.47 --- mvpmc.h 23 Sep 2005 03:24:40 -0000 1.48 *************** *** 161,164 **** --- 161,166 ---- extern volatile int jumping; extern volatile int paused; + extern volatile int audio_playing; + extern volatile int audio_stop; extern int video_init(void); *************** *** 202,205 **** --- 204,208 ---- extern void *audio_write_start(void*); extern void *display_thread(void*); + extern void* audio_start(void *arg); extern void replaytv_back_to_mvp_main_menu(void); *************** *** 213,216 **** --- 216,220 ---- extern pthread_t video_write_thread; extern pthread_t audio_write_thread; + extern pthread_t audio_thread; extern pthread_attr_t thread_attr, thread_attr_small; Index: gui.c =================================================================== RCS file: /cvsroot/mvpmc/mvpmc/src/gui.c,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** gui.c 20 Sep 2005 02:05:23 -0000 1.62 --- gui.c 23 Sep 2005 03:24:40 -0000 1.63 *************** *** 25,28 **** --- 25,29 ---- #include <string.h> #include <pthread.h> + #include <signal.h> #ifndef MVPMC_HOST *************** *** 1023,1026 **** --- 1024,1033 ---- break; case MVPW_KEY_SKIP: + audio_stop = 1; + pthread_kill(audio_thread, SIGURG); + while (audio_playing && audio_stop) { + audio_play(NULL); + usleep(1000); + } audio_clear(); video_clear(); *************** *** 1029,1032 **** --- 1036,1045 ---- break; case MVPW_KEY_REPLAY: + audio_stop = 1; + pthread_kill(audio_thread, SIGURG); + while (audio_playing && audio_stop) { + audio_play(NULL); + usleep(1000); + } audio_clear(); video_clear(); *************** *** 1035,1042 **** break; case MVPW_KEY_STOP: ! audio_clear(); ! video_clear(); ! av_reset(); ! playlist_stop(); break; case MVPW_KEY_PAUSE: --- 1048,1052 ---- break; case MVPW_KEY_STOP: ! fb_exit(); break; case MVPW_KEY_PAUSE: Index: audio.c =================================================================== RCS file: /cvsroot/mvpmc/mvpmc/src/audio.c,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** audio.c 20 Sep 2005 02:05:23 -0000 1.15 --- audio.c 23 Sep 2005 03:24:40 -0000 1.16 *************** *** 34,37 **** --- 34,39 ---- #include <assert.h> #include <sys/time.h> + #include <pthread.h> + #include <signal.h> #include <mvp_widget.h> *************** *** 65,68 **** --- 67,72 ---- static volatile int ac3_head = 0, ac3_tail = AC3_SIZE - 1; + pthread_cond_t audio_cond = PTHREAD_COND_INITIALIZER; + typedef enum { AUDIO_FILE_UNKNOWN, *************** *** 78,82 **** void audio_play(mvp_widget_t *widget); ! static void wav_play(int, int, unsigned short, unsigned short, unsigned short); static unsigned long quantised_next_input_sample = 0; --- 82,86 ---- void audio_play(mvp_widget_t *widget); ! static int wav_play(int, int, unsigned short, unsigned short, unsigned short); static unsigned long quantised_next_input_sample = 0; *************** *** 98,101 **** --- 102,108 ---- av_passthru_t audio_output_mode = AUD_OUTPUT_STEREO; + volatile int audio_playing = 0; + volatile int audio_stop = 0; + #ifdef DEBUG_LOG_SOUND static inline void logwrite (char *fn, int result, int fd, int size, unsigned char *data) *************** *** 174,178 **** } ! static void ogg_play(int afd) { --- 181,185 ---- } ! static int ogg_play(int afd) { *************** *** 185,189 **** len = 0; do_read = 1; ! return; } --- 192,196 ---- len = 0; do_read = 1; ! return -1; } *************** *** 220,239 **** * so keep processing the file until we're forced to block. */ ! goto retry; full: do_read = 0; ! ! mvpw_set_idle(NULL); ! mvpw_set_timer(root, audio_play, 100); ! ! return; next: ! audio_clear(); ! if(playlist) ! playlist_next(); ! else ! fd = -2; } --- 227,239 ---- * so keep processing the file until we're forced to block. */ ! return 0; full: do_read = 0; ! usleep(1000); ! return 0; next: ! return -1; } *************** *** 243,247 **** ****************************************** */ ! static void ac3_play(int afd) { --- 243,247 ---- ****************************************** */ ! static int ac3_play(int afd) { *************** *** 255,259 **** ac3len = 0; printf("playing AC3 file\n"); ! return; } --- 255,259 ---- ac3len = 0; printf("playing AC3 file\n"); ! return -1; } *************** *** 271,285 **** if (ac3more != 0) { ! mvpw_set_idle(NULL); ! mvpw_set_timer(root, audio_play, 100); } else if(ac3len==0){ /* fprintf(stderr,"ac3 file finished\n"); */ ! mvpw_set_idle(NULL); ! audio_clear(); ! if(playlist){ ! playlist_next(); ! } } } --- 271,283 ---- if (ac3more != 0) { ! usleep(1000); ! return 0; } else if(ac3len==0){ /* fprintf(stderr,"ac3 file finished\n"); */ ! return -1; } + + return 0; } *************** *** 289,293 **** ****************************************** */ ! static void ac3_spdif_play(int afd) { --- 287,291 ---- ****************************************** */ ! static int ac3_spdif_play(int afd) { *************** *** 300,304 **** n = 0; nput = 0; ! return; } --- 298,302 ---- n = 0; nput = 0; ! return -1; } *************** *** 307,321 **** if(n==0 && nput==0){ /* fprintf(stderr,"ac3 file finished\n"); */ ! mvpw_set_idle(NULL); ! audio_clear(); ! if(playlist){ ! playlist_next(); ! } ! return; } if ((tot=write(afd, buf+nput, n-nput)) == 0) { ! mvpw_set_idle(NULL); ! mvpw_set_timer(root, audio_play, 100); ! return; } nput += tot; --- 305,313 ---- if(n==0 && nput==0){ /* fprintf(stderr,"ac3 file finished\n"); */ ! return -1; } if ((tot=write(afd, buf+nput, n-nput)) == 0) { ! usleep(1000); ! return 0; } nput += tot; *************** *** 325,331 **** nput = 0; } } ! static void mp3_play(int afd) { --- 317,325 ---- nput = 0; } + + return 0; } ! static int mp3_play(int afd) { *************** *** 337,358 **** n = 0; nput = 0; ! return; } ! len = read(fd, buf+n, BSIZE-n); n += len; if(n==0 && nput==0){ /* fprintf(stderr,"mp3 file finished\n"); */ ! mvpw_set_idle(NULL); ! audio_clear(); ! if(playlist){ ! playlist_next(); ! } ! return; } if ((tot=write(afd, buf+nput, n-nput)) == 0) { ! mvpw_set_idle(NULL); ! mvpw_set_timer(root, audio_play, 100); ! return; } nput += tot; --- 331,350 ---- n = 0; nput = 0; ! return -1; } ! if ((len=read(fd, buf+n, BSIZE-n)) == 0) { ! usleep(1000); ! } ! if (len < 0) ! return -1; n += len; if(n==0 && nput==0){ /* fprintf(stderr,"mp3 file finished\n"); */ ! return -1; } if ((tot=write(afd, buf+nput, n-nput)) == 0) { ! usleep(1000); ! return 0; } nput += tot; *************** *** 362,409 **** nput = 0; } } static int ! audio_player(int reset) { ! static int n = 0, nput = 0, afd = 0; ! ! if (reset) { ! n = 0; ! nput = 0; ! ! switch (audio_type) { ! case AUDIO_FILE_WAV: ! empty_ac3(); ! quantised_next_input_sample = 0; ! last_sample_in_buffer = 0; ! next_output_sample = 0; ! next_input_sample = 0; ! break; ! case AUDIO_FILE_AC3: ! if (audio_output_mode == AUD_OUTPUT_STEREO) { ! /* ! * downmixing from 5.1 to 2 channels ! */ ! ac3_play(-1); ! } else { ! /* ! * AC3 pass through out the SPDIF / TOSLINK ! */ ! ac3_spdif_play(-1); ! } ! break; ! case AUDIO_FILE_OGG: ! ogg_play(-1); ! break; ! case AUDIO_FILE_MP3: ! mp3_play(-1); ! break; ! default: ! break; ! } ! ! afd = av_audio_fd(); ! } switch (audio_type) { --- 354,365 ---- nput = 0; } + + return 0; } static int ! audio_player(int reset, int afd) { ! int ret = -1; switch (audio_type) { *************** *** 413,439 **** * downmixing from 5.1 to 2 channels */ ! ac3_play(afd); } else { /* * AC3 pass through out the SPDIF / TOSLINK */ ! ac3_spdif_play(afd); } break; case AUDIO_FILE_WAV: ! wav_play(fd, afd, align, channels, bps); break; case AUDIO_FILE_MP3: ! mp3_play(afd); break; case AUDIO_FILE_OGG: ! ogg_play(afd); break; default: - mvpw_set_idle(NULL); break; } ! return 0; } --- 369,394 ---- * downmixing from 5.1 to 2 channels */ ! ret = ac3_play(afd); } else { /* * AC3 pass through out the SPDIF / TOSLINK */ ! ret = ac3_spdif_play(afd); } break; case AUDIO_FILE_WAV: ! ret = wav_play(fd, afd, align, channels, bps); break; case AUDIO_FILE_MP3: ! ret = mp3_play(afd); break; case AUDIO_FILE_OGG: ! ret = ogg_play(afd); break; default: break; } ! return ret; } *************** *** 528,601 **** } - static void - audio_idle(void) - { - int reset = 0; - - if (fd == -2) { - mvpw_set_idle(NULL); - return; - } - - if (fd == -1) { - if ((fd=open(current, O_RDONLY|O_LARGEFILE|O_NDELAY)) < 0) - return; - - switch ((audio_type=get_audio_type(current))) { - case AUDIO_FILE_MP3: - av_set_audio_output(AV_AUDIO_MPEG); - av_set_audio_type(0); - break; - case AUDIO_FILE_OGG: - if (ogg_setup() < 0) - goto fail; - break; - case AUDIO_FILE_AC3: - if (audio_output_mode == AUD_OUTPUT_STEREO) { - /* - * downmixing from 5.1 to 2 channels - */ - av_set_audio_output(AV_AUDIO_PCM); - } else { - /* - * AC3 pass through out the SPDIF / TOSLINK - */ - if (av_set_audio_output(AV_AUDIO_AC3) < 0) { - /* revert to downmixing */ - av_set_audio_output(AV_AUDIO_PCM); - audio_output_mode = AUD_OUTPUT_STEREO; - } - } - break; - case AUDIO_FILE_WAV: - if (wav_setup() < 0) - goto fail; - break; - case AUDIO_FILE_UNKNOWN: - mvpw_set_idle(NULL); - return; - break; - } - - av_play(); - - reset = 1; - } - - if (audio_player(reset) < 0) - mvpw_set_idle(NULL); - - return; - - fail: - close(fd); - fd = -2; - } - void audio_play(mvp_widget_t *widget) { ! mvpw_set_idle(audio_idle); ! mvpw_set_timer(root, NULL, 0); } --- 483,490 ---- } void audio_play(mvp_widget_t *widget) { ! pthread_cond_signal(&audio_cond); } *************** *** 744,748 **** } ! static void wav_play(int fd, int afd, unsigned short align, unsigned short channels, unsigned short bps) --- 633,637 ---- } ! static int wav_play(int fd, int afd, unsigned short align, unsigned short channels, unsigned short bps) *************** *** 754,764 **** int iloop; int sample_value = 0; ! ac3_flush(); if (ac3_freespace() < (BUFFSIZE*align)) { ! mvpw_set_idle(NULL); ! mvpw_set_timer(root, audio_play, 100); ! return; } --- 643,654 ---- int iloop; int sample_value = 0; + int empty = 0; ! if (ac3_flush() == 0) ! empty = 1; if (ac3_freespace() < (BUFFSIZE*align)) { ! usleep(1000); ! return 0; } *************** *** 766,769 **** --- 656,662 ---- n = read(fd, wav_buffer, min((align * BUFFSIZE), chunk_size)); + if ((n == 0) && empty) + return 1; + /* * while we have data in the buffer *************** *** 815,818 **** --- 708,713 ---- ac3_flush(); + + return 0; } *************** *** 920,921 **** --- 815,961 ---- return 0; } + + static void + sighandler(int sig) + { + } + + static int + audio_init(void) + { + if ((fd=open(current, O_RDONLY|O_LARGEFILE|O_NDELAY)) < 0) + goto fail; + + switch ((audio_type=get_audio_type(current))) { + case AUDIO_FILE_MP3: + av_set_audio_output(AV_AUDIO_MPEG); + av_set_audio_type(0); + break; + case AUDIO_FILE_OGG: + if (ogg_setup() < 0) + goto fail; + break; + case AUDIO_FILE_AC3: + if (audio_output_mode == AUD_OUTPUT_STEREO) { + /* + * downmixing from 5.1 to 2 channels + */ + av_set_audio_output(AV_AUDIO_PCM); + } else { + /* + * AC3 pass through out the SPDIF / TOSLINK + */ + if (av_set_audio_output(AV_AUDIO_AC3) < 0) { + /* revert to downmixing */ + av_set_audio_output(AV_AUDIO_PCM); + audio_output_mode = AUD_OUTPUT_STEREO; + } + } + break; + case AUDIO_FILE_WAV: + if (wav_setup() < 0) + goto fail; + break; + case AUDIO_FILE_UNKNOWN: + goto fail; + break; + } + + av_play(); + + switch (audio_type) { + case AUDIO_FILE_WAV: + empty_ac3(); + quantised_next_input_sample = 0; + last_sample_in_buffer = 0; + next_output_sample = 0; + next_input_sample = 0; + break; + case AUDIO_FILE_AC3: + if (audio_output_mode == AUD_OUTPUT_STEREO) { + /* + * downmixing from 5.1 to 2 channels + */ + ac3_play(-1); + } else { + /* + * AC3 pass through out the SPDIF / TOSLINK + */ + ac3_spdif_play(-1); + } + break; + case AUDIO_FILE_OGG: + ogg_play(-1); + break; + case AUDIO_FILE_MP3: + mp3_play(-1); + break; + default: + break; + } + + return 0; + + fail: + return -1; + } + + /* + * audio_start() - audio playback thread + */ + void* + audio_start(void *arg) + { + sigset_t sigs; + pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + int afd; + int done; + + signal(SIGURG, sighandler); + sigemptyset(&sigs); + sigaddset(&sigs, SIGURG); + pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); + + printf("audio thread started (pid %d)\n", getpid()); + + pthread_mutex_lock(&mutex); + + while (1) { + audio_playing = 0; + audio_stop = 0; + + pthread_cond_wait(&audio_cond, &mutex); + + repeat: + printf("Starting to play audio file '%s'\n", current); + + if (audio_init() != 0) + goto fail; + + afd = av_audio_fd(); + + audio_playing = 1; + audio_stop = 0; + + while (((done=audio_player(0, afd)) == 0) && + current && !audio_stop) + ; + + if (!audio_stop && playlist) { + close(fd); + playlist_next(); + if (playlist) { + printf("next song on playlist\n"); + goto repeat; + } + } + + fail: + printf("Done with audio file\n"); + + close(fd); + audio_clear(); + } + + return NULL; + } Index: playlist.c =================================================================== RCS file: /cvsroot/mvpmc/mvpmc/src/playlist.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** playlist.c 3 Jul 2005 16:12:54 -0000 1.7 --- playlist.c 23 Sep 2005 03:24:40 -0000 1.8 *************** *** 27,30 **** --- 27,31 ---- #include <string.h> #include <pthread.h> + #include <signal.h> #include <mvp_widget.h> *************** *** 64,71 **** --- 65,78 ---- while (pl) { if (pl->key == key) { + audio_stop = 1; + pthread_kill(audio_thread, SIGURG); + while (audio_playing) + usleep(1000); audio_clear(); video_clear(); av_reset(); playlist_change(pl); + audio_play(NULL); + mvpw_show(fb_progress); break; } *************** *** 315,319 **** break; case PLAYLIST_FILE_UNKNOWN: - mvpw_set_idle(NULL); return; break; --- 322,325 ---- *************** *** 358,363 **** playlist_play(mvp_widget_t *widget) { ! mvpw_set_idle(playlist_idle); ! mvpw_set_timer(root, NULL, 0); } --- 364,368 ---- playlist_play(mvp_widget_t *widget) { ! playlist_idle(); } *************** *** 367,371 **** return; } - if (current){ playlist = next; --- 372,375 ---- *************** *** 378,381 **** --- 382,386 ---- snprintf(display_message,DISPLAY_MESG_SIZE,"File:%s \n", playlist->filename); } + if(current) free(current); current=NULL; *************** *** 383,389 **** return; } ! } ! printf("playlist: play item '%s', file '%s'\n", ! playlist->name, playlist->filename); /* --- 388,393 ---- return; } ! printf("playlist: play item '%s', file '%s' key %d\n", ! playlist->name, playlist->filename, (int)playlist->key); /* *************** *** 437,441 **** mvpw_set_timer(root, video_play, 50); } else if (is_audio(current)) { ! mvpw_set_timer(root, audio_play, 50); } else if (is_image(current)) { mvpw_set_image(iw, current); --- 441,445 ---- mvpw_set_timer(root, video_play, 50); } else if (is_audio(current)) { ! audio_play(NULL); } else if (is_image(current)) { mvpw_set_image(iw, current); Index: main.c =================================================================== RCS file: /cvsroot/mvpmc/mvpmc/src/main.c,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** main.c 20 Sep 2005 02:05:23 -0000 1.36 --- main.c 23 Sep 2005 03:24:40 -0000 1.37 *************** *** 67,70 **** --- 67,71 ---- pthread_t video_write_thread; pthread_t audio_write_thread; + pthread_t audio_thread; pthread_attr_t thread_attr, thread_attr_small; *************** *** 418,421 **** --- 419,423 ---- if ((config=(config_t*)shmat(shmid, NULL, 0)) == (config_t*)-1) { perror("shmat()"); + exit(1); } *************** *** 639,642 **** --- 641,646 ---- pthread_create(&video_write_thread, &thread_attr_small, video_write_start, NULL); + pthread_create(&audio_thread, &thread_attr_small, + audio_start, NULL); if (gui_init(mythtv_server, replaytv_server) < 0) { Index: fb.c =================================================================== RCS file: /cvsroot/mvpmc/mvpmc/src/fb.c,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** fb.c 20 Sep 2005 04:41:07 -0000 1.20 --- fb.c 23 Sep 2005 03:24:40 -0000 1.21 *************** *** 30,33 **** --- 30,35 ---- #include <string.h> #include <time.h> + #include <signal.h> + #include <pthread.h> #include <mvp_widget.h> *************** *** 200,203 **** --- 202,212 ---- if (current) free(current); + current = NULL; + audio_stop = 1; + pthread_kill(audio_thread, SIGURG); + + while (audio_playing) + usleep(1000); + current = strdup(path); *************** *** 405,418 **** fb_exit(void) { if (current) { free(current); current = NULL; } - mvpw_set_idle(NULL); - mvpw_set_timer(root, NULL, 0); mvpw_hide(fb_progress); - playlist_clear(); audio_clear(); video_clear(); } --- 414,428 ---- fb_exit(void) { + audio_stop = 1; + pthread_kill(audio_thread, SIGURG); + if (current) { free(current); current = NULL; } mvpw_hide(fb_progress); audio_clear(); video_clear(); + av_stop(); } |