void display_bookmark_status_osd(int function) { display_on_alt = 1; set_osd_callback(OSD_PROGRESS, video_progress); set_osd_callback(OSD_TIMECODE, video_timecode); switch (function) { case 0: //seek to bookmark set_osd_callback(OSD_PROGRAM, goto_bookmark_status); break; case 1: // set bookmark set_osd_callback(OSD_PROGRAM, set_bookmark_status); break; case 2: // doing a commskip seek set_osd_callback(OSD_PROGRAM, set_commbreak_status); break; case 3: // doing a normal seek set_osd_callback(OSD_PROGRAM, set_seek_status); break; case 4: // set bookmark failed set_osd_callback(OSD_PROGRAM, set_bookmark_status_fail); break; } mvpw_set_timer(mythtv_osd_description, seek_disable_osd , 5000); mvpw_set_timer(mythtv_osd_program, seek_disable_osd , 5000); }
void video_play(mvp_widget_t *widget) { demux_attr_t *attr; video_info_t *vi; TRC("%s\n", __FUNCTION__); mvpw_set_idle(NULL); if (demux_spu_get_id(handle) < 0) mvpw_set_timer(root, video_subtitle_check, 1000); else mvpw_set_timer(root, video_subtitle_display, 250); video_set_root(); av_set_tv_aspect(config->av_tv_aspect); attr = demux_get_attr(handle); vi = &attr->video.stats.info.video; video_change_aspect(vi->aspect,vi->afd); /*Force video demux code to detect and trigger an aspect event for any *new AFD or aspect ratio: */ vi->aspect = -1; vi->afd = -1; paused = 0; video_reopen = 1; video_playing = 1; pthread_cond_broadcast(&video_cond); }
void video_subtitle_check(mvp_widget_t *widget) { extern mvp_widget_t *main_menu; if (demux_spu_get_id(handle) >= 0) mvpw_set_timer(root, video_subtitle_display, 250); else mvpw_set_timer(root, video_subtitle_check, 1000); if (gui_state == MVPMC_STATE_EMULATE ) { return; } if (! (mvpw_visible(file_browser) || mvpw_visible(playlist_widget) || mvpw_visible(mythtv_browser) || mvpw_visible(main_menu) || mvpw_visible(settings) || mvpw_visible(ct_text_box) || mvpw_visible(mythtv_menu))) { if(showing_guide == 0) { video_thumbnail(AV_THUMBNAIL_OFF,0); } } }
static void video_unpause_timer_callback(mvp_widget_t * widget) { if(!paused) av_play(); mvpw_set_timer(widget,NULL,0); }
void fb_shuffle(int shuffle) { char **item, *tmp; int i, j, k, n; if (shuffle) mvpw_set_menu_title(playlist_widget, "Shuffle Play"); else mvpw_set_menu_title(playlist_widget, "Play All"); item = alloca(sizeof(char*) * MAX_PLAYLIST_ENTRIES); // Recurse from the current directory and find all // audio files n = 0; recurse_find_audio(cwd, item, &n); if (n == 0) { gui_error("No audio files exist in this directory or its subdirectories"); return; } if (shuffle && (n > 1)) { for (i=0; i < MAX_PLAYLIST_ENTRIES; i++) { j = rand() % n; k = rand() % n; tmp = item[k]; item[k] = item[j]; item[j] = tmp; } } printf("created playlist of %d songs\n", n); switch_hw_state(MVPMC_STATE_FILEBROWSER); video_functions = &file_functions; playlist_clear(); mvpw_show(playlist_widget); mvpw_focus(playlist_widget); playlist_create(item, n); // Release the list of items for (i = 0; i < n; i++) free(item[i]); if (shuffle) mvpw_set_text_str(fb_name, "Shuffle Play"); else mvpw_set_text_str(fb_name, "Play All"); mvpw_show(fb_progress); mvpw_set_timer(fb_progress, fb_osd_update, 500); playlist_play(NULL); }
void timed_osd(int timeout) { if ((timeout == 0) || display_on) return; display_on_alt = 1; enable_osd(); mvpw_set_timer(root, seek_disable_osd, timeout); }
static void select_callback(mvp_widget_t *widget, char *item, void *key) { char path[1024], *ptr; struct stat64 sb; sprintf(path, "%s/%s", cwd, item); if (stat64(path, &sb)!=0) { printf("Could not stat %s error %d\n",item,errno); if (strcmp(item,"../")==0 ) { // probably lost network put you back in root strcpy(cwd,"/"); strcpy(path,"/"); stat64(path, &sb); } } if (current_pl && !is_playlist(item)) { free(current_pl); current_pl = NULL; } if (current_pl && (playlist == NULL)) { free(current_pl); current_pl = NULL; } printf("%s(): path '%s'\n", __FUNCTION__, path); if (current && (strcmp(path, current) == 0)) { printf("selected current item\n"); if (is_video(item) || (is_streaming(item) > 100)) { mvpw_hide(widget); mvpw_hide(fb_progress); av_move(0, 0, 0); screensaver_disable(); return; } } if (current_pl && (strcmp(path, current_pl) == 0)) { if (is_playlist(item)) { mvpw_show(fb_progress); mvpw_set_timer(fb_progress, fb_osd_update, 500); mvpw_hide(widget); printf("Show playlist menu\n"); mvpw_show(playlist_widget); mvpw_focus(playlist_widget); return; } } if (S_ISDIR(sb.st_mode)) { if (strcmp(item, "../") == 0) { strcpy(path, cwd); if (path[strlen(path)-1] == '/') path[strlen(path)-1] = '\0'; if ((ptr=strrchr(path, '/')) != NULL) *ptr = '\0'; if (path[0] == '\0') sprintf(path, "/"); } else { if ((ptr=strrchr(path, '/')) != NULL) *ptr = '\0'; } if (strstr(path,"/uPnP")!=NULL && strstr(cwd,"/uPnP")==NULL ){ mount_djmount(path); } else if (strstr(path,"/uPnP")==NULL && strstr(cwd,"/uPnP")!=NULL ) { unmount_djmount(); } strncpy(cwd, path, sizeof(cwd)); while ((cwd[0] == '/') && (cwd[1] == '/')) memmove(cwd, cwd+1, strlen(cwd)); mvpw_clear_menu(widget); mvpw_set_menu_title(widget, cwd); busy_start(); add_dirs(widget); add_files(widget); busy_end(); mvpw_expose(widget); } else { switch_hw_state(MVPMC_STATE_FILEBROWSER); if (current) free(current); current = NULL; audio_stop = 1; pthread_kill(audio_thread, SIGURG); while (audio_playing) usleep(1000); current = strdup(path); if (is_streaming(item) > 100) { // Use VLC callbacks for streaming items video_functions = &vlc_functions; // Allow broadcast messages to be sent so // we can tell VLC to start the stream vlc_broadcast_enabled = 1; } else { video_functions = &file_functions; } add_osd_widget(fb_program_widget, OSD_PROGRAM, osd_settings.program, NULL); mvpw_set_text_str(fb_name, item); /* * This code sends the currently playing file name to the display. */ snprintf(display_message, sizeof(display_message), "File:%s\n", item); display_send(display_message); audio_clear(); video_clear(); playlist_clear(); if (is_video(item)) { if (key != NULL) { mvpw_hide(widget); mvpw_hide(fb_progress); av_move(0, 0, 0); } else { mvpw_show(fb_progress); } mvpw_set_timer(fb_progress, fb_osd_update, 500); video_play(NULL); mvpw_show(root); mvpw_expose(root); mvpw_focus(root); } else if (is_audio(item) || is_streaming(item)>=0 ) { mvpw_show(fb_progress); mvpw_set_timer(fb_progress, fb_osd_update, 500); audio_play(NULL); } else if (is_image(item)) { mvpw_hide(widget); printf("Displaying image '%s'\n", path); if (mvpw_load_image_jpeg(iw, path) == 0) { mvpw_show_image_jpeg(iw); av_wss_update_aspect(WSS_ASPECT_UNKNOWN); } else { mvpw_set_image(iw, path); } mvpw_show(iw); mvpw_focus(iw); loaded_offset = 0; loaded_status = 0; fb_next_image(1); } else if (is_playlist(item)) { if (current_pl) free(current_pl); current_pl = strdup(path); mvpw_show(fb_progress); mvpw_set_timer(fb_progress, fb_osd_update, 500); mvpw_hide(widget); printf("Show playlist menu\n"); mvpw_show(playlist_widget); mvpw_focus(playlist_widget); playlist_clear(); playlist_play(NULL); } } }
void video_callback(mvp_widget_t *widget, char key) { int jump; long long offset, size; pts_sync_data_t async, vsync; av_state_t state; /* printf("**SSDEBUG: In video_callback and got key %d \n",key); */ if (!video_playing) return; if(showing_guide) { if(mvp_tvguide_callback(widget, key) == 1) return; } if ( video_functions->key != NULL ) { if ( video_functions->key(key) == 1 ) { return; } } switch (key) { case MVPW_KEY_GO: case MVPW_KEY_GUIDE: if(showing_guide == 0 && showing_guide == 0) { printf("In %s showing guide %d \n",__FUNCTION__, key); showing_guide = 1; mvp_tvguide_video_topright(1); mvp_tvguide_show(mythtv_livetv_program_list, mythtv_livetv_description, mythtv_livetv_clock); break; } /* if the guide button is pressed while guide is active fall through to go back to remove guide and return to TV */ case MVPW_KEY_TV: if(showing_guide == 1) { printf("In %s hiding guide %d \n", __FUNCTION__, key); showing_guide = 0; mvp_tvguide_video_topright(0); mvp_tvguide_hide(mythtv_livetv_program_list, mythtv_livetv_description, mythtv_livetv_clock); } break; case MVPW_KEY_STOP: case MVPW_KEY_EXIT: back_to_guide_menu(); new_live_tv = 0; break; case MVPW_KEY_PAUSE: if (av_pause()) { mvpw_show(pause_widget); mvpw_hide(ffwd_widget); paused = 1; if (pause_osd && !display_on && (display_on_alt < 2)) { display_on_alt = 2; enable_osd(); } screensaver_enable(); } else { if (pause_osd && !display_on && (display_on_alt == 2)) { display_on_alt = 0; disable_osd(); mvpw_expose(root); } av_get_state(&state); if (state.mute) mvpw_show(mute_widget); else mvpw_hide(mute_widget); mvpw_hide(pause_widget); paused = 0; screensaver_disable(); } break; case MVPW_KEY_PLAY: if ( paused ) { /* * play key can be used to un-pause */ av_pause(); if (pause_osd && !display_on && (display_on_alt == 2)) { display_on_alt = 0; disable_osd(); mvpw_expose(root); } mvpw_hide(pause_widget); mvpw_hide(mute_widget); paused = 0; screensaver_disable(); } break; case MVPW_KEY_REPLAY: seek_by(-30); timed_osd(seek_osd_timeout*1000); break; case MVPW_KEY_REWIND: seek_by(-10); timed_osd(seek_osd_timeout*1000); break; case MVPW_KEY_SKIP: if (mythtv_seek_amount == 0 ) { seek_by(30); } else if (mythtv_seek_amount == 1 ) { seek_by(60); } else { seek_by(30); } timed_osd(seek_osd_timeout*1000); break; case MVPW_KEY_FFWD: if (av_ffwd() == 0) { demux_flush(handle); demux_seek(handle); av_get_state(&state); av_stop(); av_reset(); if (state.mute) { av_set_mute(1); } av_play(); mvpw_hide(ffwd_widget); } else { av_get_state(&state); mvpw_show(ffwd_widget); mvpw_hide(pause_widget); screensaver_disable(); } timed_osd(seek_osd_timeout*1000); break; case MVPW_KEY_LEFT: if (video_functions->seek) { size = video_functions->size(); jump_target = -1; jumping = 1; if (video_write_thread) { pthread_kill(video_write_thread, SIGURG); } if (audio_write_thread) { pthread_kill(audio_write_thread, SIGURG); } offset = video_functions->seek(0, SEEK_CUR); jump_target = ((-size / 100.0) + offset); pthread_cond_broadcast(&video_cond); } break; case MVPW_KEY_RIGHT: if (video_functions->seek) { size = video_functions->size(); jump_target = -1; jumping = 1; if (video_write_thread) { pthread_kill(video_write_thread, SIGURG); } if (audio_write_thread) { pthread_kill(audio_write_thread, SIGURG); } offset = video_functions->seek(0, SEEK_CUR); jump_target = ((size / 100.0) + offset); pthread_cond_broadcast(&video_cond); timed_osd(seek_osd_timeout*1000); } break; case MVPW_KEY_ZERO ... MVPW_KEY_NINE: if(new_live_tv) { printf("In %s showing guide %d \n",__FUNCTION__, key); showing_guide = 1; mvp_tvguide_video_topright(1); mvp_tvguide_show(mythtv_livetv_program_list, mythtv_livetv_description, mythtv_livetv_clock); mvp_tvguide_callback(widget, key); } else if (mythtv_livetv) { back_to_guide_menu(); mythtv_key_callback(mythtv_browser, key); } else { size = video_functions->size(); jump_target = -1; jumping = 1; if (video_write_thread) { pthread_kill(video_write_thread, SIGURG); } if (audio_write_thread) { pthread_kill(audio_write_thread, SIGURG); } jump = key; jump_target = size * (jump / 10.0); pthread_cond_broadcast(&video_cond); timed_osd(seek_osd_timeout*1000); } break; case MVPW_KEY_MENU: mvpw_show(popup_menu); mvpw_focus(popup_menu); break; case MVPW_KEY_MUTE: if (mvpw_visible(ffwd_widget)) { mvpw_hide(mute_widget); break; } if (av_mute() == 1) { mvpw_show(mute_widget); } else { mvpw_hide(mute_widget); } break; case MVPW_KEY_BLANK: case MVPW_KEY_OK: if (display_on || display_on_alt) { disable_osd(); mvpw_expose(root); display_on = 1; display_on_alt = 0; } else { enable_osd(); } display_on = !display_on; break; case MVPW_KEY_FULL: case MVPW_KEY_PREV_CHAN: if(IS_4x3(av_get_tv_aspect())) { if(av_get_tv_aspect() == AV_TV_ASPECT_4x3_CCO) av_set_tv_aspect(AV_TV_ASPECT_4x3); else av_set_tv_aspect(AV_TV_ASPECT_4x3_CCO); } break; case MVPW_KEY_CHAN_UP: case MVPW_KEY_UP: if (mythtv_livetv) mythtv_channel_up(); break; case MVPW_KEY_CHAN_DOWN: case MVPW_KEY_DOWN: if (mythtv_livetv) mythtv_channel_down(); break; case MVPW_KEY_RECORD: /* * XXX: This is a temporary hack until we figure out how * to tell when the audio and video are out of sync, * and correct it automatically. */ av_get_audio_sync(&async); av_get_video_sync(&vsync); printf("PRE SYNC: a 0x%"PRIx64" 0x%"PRIx64" v 0x%"PRIx64" 0x%"PRIx64"\n", async.stc, async.pts, vsync.stc, vsync.pts); av_delay_video(1000); av_get_audio_sync(&async); av_get_video_sync(&vsync); printf("POST SYNC: a 0x%"PRIx64" 0x%"PRIx64" v 0x%"PRIx64" 0x%"PRIx64"\n", async.stc, async.pts, vsync.stc, vsync.pts); break; case MVPW_KEY_VOL_UP: case MVPW_KEY_VOL_DOWN: volume_key_callback(volume_dialog, key); mvpw_show(volume_dialog); mvpw_set_timer(volume_dialog, timer_hide, 3000); break; default: PRINTF("button %d\n", key); break; } }
void back_to_guide_menu() { disable_osd(); if ( !running_replaytv ) { video_thumbnail(AV_THUMBNAIL_EIGTH,VID_THUMB_BOTTOM_RIGHT); } if (spu_widget) { mvpw_hide(spu_widget); mvpw_expose(root); mvpw_destroy(spu_widget); spu_widget = NULL; mvpw_set_timer(root, NULL, 0); } mvpw_hide(osd_widget); mvpw_hide(mute_widget); mvpw_hide(pause_widget); mvpw_hide(ffwd_widget); mvpw_hide(zoom_widget); display_on = 0; zoomed = 0; switch (gui_state) { case MVPMC_STATE_NONE: case MVPMC_STATE_EMULATE: case MVPMC_STATE_EMULATE_SHUTDOWN: case MVPMC_STATE_WEATHER: /* * XXX: redisplay the main menu? */ break; case MVPMC_STATE_MYTHTV: case MVPMC_STATE_MYTHTV_SHUTDOWN: printf("%s(): %d\n", __FUNCTION__, __LINE__); if (mythtv_livetv == 1) { if (mythtv_state == MYTHTV_STATE_LIVETV) { if (mvpw_visible(mythtv_browser) || new_live_tv) { mythtv_livetv_stop(); mythtv_livetv = 0; running_mythtv = 0; if(new_live_tv) { switch_gui_state(MVPMC_STATE_MYTHTV); mvpw_show(mythtv_logo); mvpw_show(mythtv_menu); mvpw_focus(mythtv_menu); } } else { mvpw_show(mythtv_channel); mvpw_show(mythtv_date); mvpw_show(mythtv_description); mvpw_show(mythtv_logo); mvpw_show(mythtv_browser); mvpw_focus(mythtv_browser); video_thumbnail(AV_THUMBNAIL_EIGTH,VID_THUMB_BOTTOM_RIGHT); } } else if (mythtv_state == MYTHTV_STATE_MAIN) { mvpw_show(mythtv_logo); mvpw_show(mythtv_menu); } else { mythtv_show_widgets(); } } else if (mythtv_main_menu) { mvpw_show(mythtv_logo); mvpw_show(mythtv_menu); mvpw_focus(mythtv_menu); } else if (running_mythtv) { printf("%s(): %d\n", __FUNCTION__, __LINE__); mythtv_show_widgets(); mvpw_focus(mythtv_browser); } break; case MVPMC_STATE_REPLAYTV: case MVPMC_STATE_REPLAYTV_SHUTDOWN: video_playing = 0; replaytv_back_from_video(); break; case MVPMC_STATE_FILEBROWSER: case MVPMC_STATE_FILEBROWSER_SHUTDOWN: case MVPMC_STATE_HTTP: case MVPMC_STATE_HTTP_SHUTDOWN: if (playlist) { mvpw_show(fb_progress); mvpw_show(playlist_widget); mvpw_focus(playlist_widget); } else { mvpw_show(fb_progress); mvpw_show(file_browser); mvpw_focus(file_browser); } break; case MVPMC_STATE_MCLIENT: case MVPMC_STATE_MCLIENT_SHUTDOWN: /* * No code is necessary here because: * - The key is already trapped / processed in gui.c/mclient_key_callback. * - And the mclient show / focus is in gui.c/main_select_callback. */ break; } mvpw_expose(root); }
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; }