int audio_switch_stream(mvp_widget_t *widget, long stream) { demux_attr_t *attr; attr = demux_get_attr(handle); if (attr->audio.current != stream) { stream_type_t type; long old, ret; old = attr->audio.current; if ((ret=demux_set_audio_stream(handle, stream)) < 0) return -1; type = (stream_type_t)ret; if (widget) { mvpw_check_menu_item(widget, (void*)old, 0); mvpw_check_menu_item(widget, (void*)stream, 1); } if (type == STREAM_MPEG) av_set_audio_output(AV_AUDIO_MPEG); else av_set_audio_output(AV_AUDIO_AC3); fd_audio = av_get_audio_fd(); printf("switched from audio stream 0x%lx to 0x%lx\n", old, stream); if (type != audio_output) { printf("switching audio output types\n"); audio_output = type; } } return 0; }
int mount_djmount(char *mycwd) { int rc=-1; if (strstr(mycwd,"/uPnP")!=NULL ) { set_route(1448*4); printf("Mounting %s\n",mycwd); av_set_audio_output(AV_AUDIO_CLOSE); if (fork()==0) { if (display_attr.utf8 == 1 ) { rc = execlp("/bin/djmount","djmount","-o", "iocharset=utf8","/uPnP",(char*)0); } else { rc = execlp("/bin/djmount","djmount","/uPnP",(char *)0); } } busy_start(); usleep(2500000); busy_end(); mvpw_expose(file_browser); av_set_audio_output(AV_AUDIO_MPEG); } return rc; }
void* audio_write_start(void *arg) { int idle = 1; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int len; sigset_t sigs; demux_attr_t *attr; video_info_t *vi; signal(SIGURG, sighandler); sigemptyset(&sigs); sigaddset(&sigs, SIGURG); pthread_sigmask(SIG_UNBLOCK, &sigs, NULL); pthread_mutex_lock(&mutex); printf("audio write thread started (pid %d)\n", getpid()); pthread_cond_wait(&video_cond, &mutex); while (1) { while (seeking || jumping) pthread_cond_wait(&video_cond, &mutex); while (!video_playing) { pcm_decoded = 0; empty_ac3(); if ( !(idle) ) { sem_post(&write_threads_idle_sem); idle = 1; printf("audio write thread sleeping...\n"); } pthread_cond_wait(&video_cond, &mutex); } if ( idle ) { sem_wait(&write_threads_idle_sem); idle = 0; printf("audio write thread running\n"); } if (running_replaytv) { attr = demux_get_attr(handle); vi = &attr->video.stats.info.video; if (attr->audio.type != audio_type) { // JBH: FIX ME: This code never gets hit audio_type = attr->audio.type; switch (audio_type) { case AUDIO_MODE_AC3: case AUDIO_MODE_PCM: audio_output = AV_AUDIO_PCM; printf("switch to PCM audio\n"); break; default: av_set_audio_type(audio_type); audio_output = AV_AUDIO_MPEG; printf("switch to MPEG audio\n"); break; } av_set_audio_output(audio_output); } } switch (audio_type) { case AUDIO_MODE_MPEG1_PES: case AUDIO_MODE_MPEG2_PES: case AUDIO_MODE_ES: if (jit_mode == 0) { if ((len=DEMUX_WRITE_AUDIO(handle, fd_audio)) > 0) pthread_cond_broadcast(&video_cond); else pthread_cond_wait(&video_cond, &mutex); } else { int flags, duration; len=DEMUX_JIT_WRITE_AUDIO(handle, fd_audio, get_cur_vid_stc(),jit_mode, &flags,&duration); if(flags & 4) { /*4 is the same as 1 followed by 2*/ flags = (flags | 1 | 2) & ~4; } if(flags & 1) { av_pause_video(); } if((flags & 2) && !paused) { if(duration <= 10) video_unpause_timer_callback(pause_widget); else mvpw_set_timer(pause_widget, video_unpause_timer_callback, duration); } if(flags & 8) { usleep(duration*1000); } if(len > 0) pthread_cond_broadcast(&video_cond); else if(!(flags & 8)) pthread_cond_wait(&video_cond, &mutex); } break; case AUDIO_MODE_PCM: /* * XXX: PCM audio does not work yet */ pthread_cond_wait(&video_cond, &mutex); break; case AUDIO_MODE_AC3: if (audio_output_mode == AUD_OUTPUT_PASSTHRU ) { if ((len=DEMUX_WRITE_AUDIO(handle, fd_audio)) > 0) pthread_cond_broadcast(&video_cond); else pthread_cond_wait(&video_cond, &mutex); break; } if (ac3more == -1) ac3more = a52_decode_data(NULL, NULL, pcm_decoded); if (ac3more == 1) { ac3more = a52_decode_data(ac3buf, ac3buf + ac3len, pcm_decoded); if (ac3more == 1) { pthread_cond_wait(&video_cond, &mutex); break; } } if (ac3more == 0) { ac3len = demux_get_audio(handle, ac3buf, sizeof(ac3buf)); ac3more = 1; } if (ac3more == 0) pthread_cond_wait(&video_cond, &mutex); else pthread_cond_broadcast(&video_cond); pcm_decoded = 1; break; } } return NULL; }
void* video_read_start(void *arg) { pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; int ret; int n = 0, len = 0, reset = 1; int sent_idle_notify; demux_attr_t *attr; video_info_t *vi; int set_aspect = 1; char *inbuf = inbuf_static; char *tsbuf; int tslen; int tsmode = TS_MODE_UNKNOWN; av_state_t state; pthread_mutex_lock(&mutex); printf("mpeg read thread started (pid %d)\n", getpid()); pthread_cond_wait(&video_cond, &mutex); while (1) { sent_idle_notify = 0; while (!video_playing) { demux_reset(handle); ts_demux_reset(tshandle); demux_seek(handle); vid_event_discontinuity_possible(); if ( !(sent_idle_notify) ) { if ( video_functions != NULL && video_functions->notify != NULL ) { video_functions->notify(MVP_READ_THREAD_IDLE); } printf("mpeg read thread sleeping...\n"); sent_idle_notify = 1; } pthread_cond_wait(&video_cond, &mutex); TRC("%s: past pthread_cond_wait(&video_cond, &mutex)\n", __FUNCTION__); } #ifdef STREAM_TEST if ( stream_test_started == 0 ) { stream_test_started = 1; //Get start time gettimeofday(&start_tv, NULL); } #endif if (video_reopen) { vid_event_clear(); if (video_functions->open() == 0) { /* Jump to the start of the new file */ jump_target = 0; jumping = 1; video_reopen = 0; tsmode = TS_MODE_UNKNOWN; } else { fprintf(stderr, "video open failed!\n"); video_playing = 0; continue; } len = 0; reset = 1; set_aspect = 1; } if ((seeking && reset) || jumping) { demux_reset(handle); ts_demux_reset(tshandle); demux_seek(handle); av_get_state(&state); av_reset(); av_reset_stc(); vid_event_discontinuity_possible(); if (seeking) reset = 0; if (state.mute) av_set_mute(1); if (paused) { av_play(); paused = 0; mvpw_hide(pause_widget); screensaver_disable(); } pcm_decoded = 0; ac3len = 0; len = 0; if (jumping) { while (jump_target < 0) usleep(1000); video_functions->seek(jump_target, SEEK_SET); } jumping = 0; } if ( !video_playing ) { continue; } if (len == 0) { if ( video_functions->read_dynb != NULL ){ tslen = video_functions->read_dynb(&tsbuf, 1024 * 256); } else { tsbuf = tsbuf_static; do { tslen = video_functions->read(tsbuf, sizeof(tsbuf_static)); } while ( tslen==-1 && errno==EAGAIN); } thruput_count += tslen; inbuf = inbuf_static; if (tsmode == TS_MODE_UNKNOWN) { if (tslen > 0) { tsmode = ts_demux_is_ts(tshandle, tsbuf, tslen); printf("auto detection transport stream returned %d\n", tsmode); if (tsmode == TS_MODE_NO) len = tslen; } } else if (tsmode == TS_MODE_NO) { len = tslen; } else { len = ts_demux_transform(tshandle, tsbuf, tslen, inbuf, sizeof(inbuf_static)); int resyncs = ts_demux_resync_count(tshandle); if (resyncs > 50) { printf("resync count = %d, switch back to unknown mode\n", resyncs); tsmode = TS_MODE_UNKNOWN; ts_demux_reset(tshandle); } } n = 0; if (len == 0 && playlist ) { video_reopen = 2; playlist_next(); } } if ( !video_playing ) { continue; } #ifdef STREAM_TEST stream_test_cnt += len; len = 0; if ( stream_test_cnt > 1024*1024*20 ) { unsigned int delta_ms; gettimeofday(&done_tv, NULL); if ( done_tv.tv_usec < start_tv.tv_usec ) { done_tv.tv_usec += 1000000; done_tv.tv_sec -= 1; } delta_ms = (done_tv.tv_sec - start_tv.tv_sec) * 1000; delta_ms += (done_tv.tv_usec - start_tv.tv_usec) / 1000; printf("Test Done\n"); printf("Bytes transferred: %u\n", stream_test_cnt); printf("Elapsed time %u mS\n", delta_ms); while ( 1 ) { sleep(10); printf("Test Done....\n"); } } continue; #else if (tsmode == TS_MODE_YES) ret = DEMUX_PUT(handle, inbuf+n, len-n); else ret = DEMUX_PUT(handle, tsbuf+n, len-n); #endif if ((ret <= 0) && (!seeking)) { pthread_cond_broadcast(&video_cond); usleep(1000); continue; } if (seeking) { if (do_seek()) { len = 0; continue; } else { reset = 1; } } n += ret; if (n == len) len = 0; pthread_cond_broadcast(&video_cond); attr = demux_get_attr(handle); vi = &attr->video.stats.info.video; if (attr->audio.type != audio_type) { audio_type = attr->audio.type; switch (audio_type) { case AUDIO_MODE_AC3: if (audio_output_mode == AUD_OUTPUT_PASSTHRU ) { if (av_set_audio_output(AV_AUDIO_AC3) < 0) { /* revert to downmixing */ audio_output_mode = AUD_OUTPUT_STEREO; // fall through to PCM } else { // don't set audio_type audio_output = AV_AUDIO_AC3; printf("switch to AC3 Passthru\n"); break; } } case AUDIO_MODE_PCM: audio_output = AV_AUDIO_PCM; printf("switch to PCM audio output device\n"); break; default: av_set_audio_type(audio_type); audio_output = AV_AUDIO_MPEG; printf("switch to MPEG audio output device\n"); break; } av_set_audio_output(audio_output); } else { if (audio_type==AUDIO_MODE_AC3){ sync_ac3_audio(); } } } //while return NULL; }
int file_open(void) { seeking = 1; audio_selected = 0; audio_checks = 0; if ( http_playing == HTTP_FILE_CLOSED ) { if (video_reopen == 1) audio_clear(); close(fd); fd = -1; } if (video_write_thread) { pthread_kill(video_write_thread, SIGURG); } if (audio_write_thread) { pthread_kill(audio_write_thread, SIGURG); } if ( http_playing == HTTP_FILE_CLOSED ) { if (gui_state != MVPMC_STATE_EMULATE) { fd=open(current, O_RDONLY|O_LARGEFILE); } else { fd = open("/tmp/FIFO", O_RDONLY); } if (fd < 0) { printf("Open failed errno %d file %s\n", errno, current); video_reopen = 0; return -1; } printf("opened %s\n", current); } else { printf("http opened %s\n", current); } if (video_reopen == 1) { av_set_audio_output(AV_AUDIO_MPEG); fd_audio = av_get_audio_fd(); av_play(); demux_reset(handle); ts_demux_reset(tshandle); demux_attr_reset(handle); demux_seek(handle); vid_event_discontinuity_possible(); if (gui_state == MVPMC_STATE_EMULATE || http_playing == HTTP_VIDEO_FILE_MPG) { video_thumbnail(AV_THUMBNAIL_OFF, 0); } else { video_thumbnail(AV_THUMBNAIL_EIGTH, 0); } av_play(); } zoomed = 0; display_on = 0; seeking = 0; jumping = 0; audio_type = 0; pcm_decoded = 0; ac3len = 0; video_reopen = 0; pthread_cond_broadcast(&video_cond); printf("write threads released\n"); return 0; }