예제 #1
0
파일: video.c 프로젝트: cgbarnwell/mvpmc
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;
	}
}
예제 #2
0
파일: fb.c 프로젝트: gettler/mvpmc
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);
		}
	}
}
예제 #3
0
파일: video.c 프로젝트: cgbarnwell/mvpmc
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;
	}
}
예제 #4
0
파일: video.c 프로젝트: cgbarnwell/mvpmc
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;
}