view liboggplayer-src/src/play.cpp @ 60:9c63b355c82b

Remove the audio code completely.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 06 Aug 2013 23:45:05 +0300
parents 3eacedd172ab
children
line wrap: on
line source

#include "imp.hpp"

bool OggPlayer::Imp::ready() {
	return true;
}
// similar to decode_audio
bool OggPlayer::Imp::decode_video() {
	bool was_ready=videobuf_ready;
	boost::unique_lock<boost::mutex> lock(video_mut, boost::defer_lock);
	ogg_int64_t videobuf_granulepos = -1;
	if (!videobuf_ready){
		if(!lock.try_lock())
			return false;
	}
	while (!videobuf_ready) {
		// theora is one in, one out...
		if (ogg_stream_packetout(&o_tsstate, &o_packet) > 0) {

			if(pp_inc){
				pp_level+=pp_inc;
				theora_control(&t_state,TH_DECCTL_SET_PPLEVEL,&pp_level,sizeof(pp_level));
				pp_inc=0;
			}
			if (o_packet.granulepos >= 0) {
				theora_control(&t_state, TH_DECCTL_SET_GRANPOS,
					&o_packet.granulepos, sizeof(o_packet.granulepos));
			}
			if (theora_decode_packetin(&t_state, &o_packet) == 0) {
				videobuf_granulepos = t_state.granulepos;
				videobuf_time = theora_granule_time(&t_state,	videobuf_granulepos);

				if (videobuf_time >= get_time()){
					videobuf_ready = true;
					frame++;
				}
				else {
					// If we are too slow, reduce the pp level.
					pp_inc=pp_level>0?-1:0;
				}
			}

		} else
			break;
	}
	lock.unlock();
	if(videobuf_ready!=was_ready)
		video_ready_cond.notify_one();

	return !videobuf_ready;
}

void OggPlayer::Imp::play_loop() {
	if(!file_in.is_open()) return;
	bool video_need_data = theora_p;
	timer.restart();
	// buffer_data() will close the file on eof
	while ((file_in.is_open() || !video_need_data) && playing) {
		if (theora_p && !videobuf_ready) {
			video_need_data = decode_video();
		}

		// are we at or past time for this video frame?
		if (videobuf_ready && videobuf_time <= get_time()) {
			videobuf_ready = false;
		}
		// if no data yet for somebody, grab another page
		if (file_in.is_open() && (video_need_data)) {
			// buffer_data() can handle eof itself
			buffer_data();
			while (ogg_sync_pageout(&o_sync, &o_page) > 0) {
				queue_page(&o_page);
			}
			video_need_data = false;
		}
	}
	playing = false;

	// do not risk a lock
	video_ready_cond.notify_one();

	// cleanup
	close();
}

void OggPlayer::Imp::play() {
	playing = true;
	play_thread = boost::thread(boost::bind(&OggPlayer::Imp::play_loop, this));
}