void video_thumbnail(av_thumbnail_mode_t thumb_mode, vid_thumb_location_t loc) { static int enable = 1; if (thumb_mode != AV_THUMBNAIL_OFF) { int x,y; if((loc & 1) == 0) x = VIEWPORT_LEFT; else x = VIEWPORT_RIGHT - av_thumbnail_width(thumb_mode); if((loc & 2) == 0) y = VIEWPORT_TOP; else y = VIEWPORT_BOTTOM - av_thumbnail_height(thumb_mode); av_move(x, y, thumb_mode); screensaver_enable(); enable = 1; } else { av_wss_redraw(); if (gui_state != MVPMC_STATE_EMULATE) { av_move(0, 0, 0); } if (enable) screensaver_disable(); enable = 0; } }
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* 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; }