int ReadMedia::decodeAudio( gavl_audio_frame_t * af ) {
	lockState();
	if (m_state != STATE_READY || m_audio_stream_count < 1 || m_fifoaudio == NULL ) {
		unlockState();
		return -1;
	}

	if ( !m_fifoaudio->Get( af )  ) {
		if ( m_aeof ) {
			m_pcm_seek = SEEK_NOTHING;
			unlockState();
			signalA();
			return 0;
		} else {
			printf("Couldn't get an audio frame, audiofifo is %f full.\n", m_fifoaudio->getSizePercentage()); // this can only happen if the fifo is empty
			unlockState();
			signalA();
			return -1;
		}
	}

	//m_atime = af->timestamp / (double)m_audio_format.samplerate;
	unlockState();
	signalA();
	return 1 ;
}
bool ReadMedia::rewind() {
	// NOTE!! Always check for stream count before setting aeof or veof
	lockState();
	if ( m_state == STATE_READY && m_file != NULL) {
		//printf("ReadMedia::rewind(), valid_samples=%d\n", m_audio_frame->valid_samples);
		m_pcm_seek = SEEK_REWIND;	
		if(m_audio_stream_count) m_aeof = false;
		//m_atime = 0;
		m_frame_seek=SEEK_REWIND;
		if (m_video_stream_count) m_veof = false;
		//m_vtime=0;

		unlockState();
		if (m_audio_stream_count) {
			signalA();  // only signal one or the other here
			//printf("ReadMedia::rewind(), signaled audio\n");
			// we are gong to flush here even though it is flushed
			// during the audio or video thread.  This will ensure our fifo 
			// is clean and empty.  Otherwise, the audio thread may be waiting
			// at the bottom of its loop and not make it to the flush part even 
			// though we signalled it.
			if (m_fifoaudio)
				m_fifoaudio->Flush();
		}
		else if (m_video_stream_count) {
			signalV();
			if (m_fifovideo)
				m_fifovideo->Flush();
		}

		return true;
	}
	unlockState();
	return false;
}
int ReadMedia::decodeVideo( gavl_video_frame_t * vf ) {

	// check state first, if state is ready, we can check the other vars without locking
	lockState();
	if (m_state != STATE_READY || m_video_stream_count < 1 || m_fifovideo == NULL ) {
		unlockState();
		return -1;
	}

	if (!m_fifovideo->Get( vf )  ) {
		if ( m_veof ) {
			m_frame_seek = SEEK_NOTHING;
			unlockState();
			signalV();
			return 0;
		} else {
			//printf("Couldn't get a video frame, videofifo is %f full\n", m_fifovideo->getSizePercentage()); // this can only happen if the fifo is empty
			unlockState();
			signalV();
			return -1; // return with error
		}
	}

	//m_vtime = 	vf->timestamp / (double)m_video_format.timescale;
	unlockState();
	signalV();
	return 1 ;
}
bool ReadMedia::pcmSeek( int64_t samples ) {
	lockState();
	if (m_state == STATE_READY && m_file && bgav_can_seek( m_file) && samples >= 0 && samples < m_num_samples ) {
		m_pcm_seek = samples;	
		unlockState();
		signalAV();
		return true;
	} else {
		m_pcm_seek = SEEK_NOTHING;
		unlockState();
		return false;
	}
}
int64_t ReadMedia::getLengthInVideoFrames() {
	int64_t frames = 0;
	lockState();
	frames = m_num_frames;
	unlockState();
	return frames;
}
int64_t ReadMedia::getLengthInAudioSamples() {
	int64_t samples = 0;
	lockState();
	samples = m_num_samples;
	unlockState();
	return samples;
}
double ReadMedia::getLengthInSeconds() {
	double secs = 0.0;
	lockState();
	secs = m_length_in_seconds;
	unlockState();
	return secs;
}
gavl_time_t ReadMedia::getLengthInGavlTime() {
	gavl_time_t time = 0;
	lockState();
	time = m_length_in_gavltime;
	unlockState();
	return time;
}
int ReadMedia::getVideoTimescale() { 
	int t=0;
	lockState();	
	t = m_video_format.timescale;
	unlockState();
	return t;
}
// NOT PUBLIC
bool ReadMedia::getVEOF() { 
	bool tmp = false;
	lockState();
	tmp =  m_veof;
	unlockState();
	return tmp;
}
int ReadMedia::getSamplesPerFrame() { 
	int spf=0;
	lockState();
	spf = m_audio_format.samples_per_frame;
	unlockState();
	return spf;
}
int ReadMedia::getVideoStreamCount() {
	int vsc=0;
	lockState();
	vsc = m_video_stream_count;
	unlockState();
	return vsc;
}
// NOT PUBLIC
int ReadMedia::getCommand() {
	int cmd= CMD_NULL;
	lockState();
	cmd = m_cmd;
	unlockState();	
	return cmd;
}
int ReadMedia::getState() { 
	int s=STATE_EMPTY;
	lockState();
	s = m_state;
	unlockState();
	return s;
}
// NOT PUBLIC
// killAVThreads is only called from the opener thread
// and from the destructor
// THIS IS NOT REALLY A PUBLIC function
void ReadMedia::killAVThreads() {

	lockState();
	m_state = STATE_EMPTY;
	quit_av_threads = true;
	unlockState();

	signalAV();
	signalAV();

	// FIRST need to join the threads that exist and are running
	if (m_audio_thread_ret == 0) {
		pthread_join( m_thread_fillaudiofifo, NULL);
		//pthread_detach( m_thread_fillaudiofifo);
	}
	if (m_video_thread_ret == 0){
		pthread_join( m_thread_fillvideofifo, NULL);
		//pthread_detach( m_thread_fillvideofifo);
	}
	m_audio_thread_ret = -1;
	m_video_thread_ret = -1;

	// no need to lock here 	
	quit_av_threads = false;

}
bool ReadMedia::quitAVThreads() {
	bool b =false;
	lockState();
	b = quit_av_threads;
	unlockState();
	return b;
}
int ReadMedia::getAudioStreamCount() {
	int asc=0;
	lockState();
	asc = m_audio_stream_count;
	unlockState();
	return asc;
} 
// NOT PUBLIC
void ReadMedia::setVideoStreamCount(int s){
	lockState();
	m_video_stream_count=s; 
	if (s==0) // if there are no video streams, video is at eof
		m_veof = true; 
	else m_veof =false;
	unlockState();
}
// NOT PUBLIC
int64_t ReadMedia::frameSeek() {
	int64_t tmp=SEEK_NOTHING;
	lockState();
	tmp = m_frame_seek;	
	m_frame_seek = SEEK_NOTHING;
	unlockState();
	return tmp;
}
int ReadMedia::getAudioChannelCount() { 
	int ch=0;
	lockState();	
	//if (m_state == STATE_READY )
		ch = m_audio_format.num_channels;
	unlockState();
	return ch;
}
int ReadMedia::getAudioSamplerate() { 
	int sr=0;  
	lockState();
	//if (m_state == STATE_READY )
		sr = m_audio_format.samplerate;
	unlockState();
	return sr;
}
float ReadMedia::getAudioFifoSizePercentage() { 
	float f=0.0;
	lockState();
	if (m_fifoaudio)	
		f = m_fifoaudio->getSizePercentage();
	unlockState();
	return f;
}
// NOT PUBLIC
void ReadMedia::setAudioStreamCount(int s){
	lockState();
	m_audio_stream_count=s;
	if (s == 0) // no audio streams, we are already at audio eof
		m_aeof = true;
	else m_aeof = false;
	unlockState();
}
// NOT PUBLIC
int64_t ReadMedia::pcmSeek() {
	int64_t tmp=SEEK_NOTHING;
	lockState();
	tmp = m_pcm_seek;	
	m_pcm_seek = SEEK_NOTHING;
	unlockState();
	return tmp;
}
bool ReadMedia::getEOF() { 
	bool tmp = true;
	lockState();
	if (m_state == STATE_READY)
		tmp = (m_aeof && m_veof);
	unlockState();
	//printf("ReadMedia:getEOF=%d, aeof=%d, veof=%d\n", tmp, m_aeof, m_veof);
	return tmp;
}
void ReadMedia::setBufferCallback(bgav_buffer_callback bc, void *v ) { 
	lockState();
	m_buffer_callback = bc; 
	m_buffer_callback_data = v;  
	// set up callbacks.
	if (m_buffer_callback) {
		bgav_options_set_buffer_callback( m_opt, m_buffer_callback, m_buffer_callback_data);
	}
	unlockState();
};
bool ReadMedia::getLoop() {
	bool tmp = true;
	lockState();
	if (m_file && bgav_can_seek( m_file) ) {
		tmp = m_loop;	
	} else {
		tmp = false; // we can't loop on file, return false 
		// but leave the loop var untouched
	}
	unlockState();
	return tmp;
}
bool ReadMedia::timeSeek(double seconds) {
	gavl_time_t gt = gavl_seconds_to_time(  seconds ) ;        

	lockState();
	if (m_state == STATE_READY && m_file && bgav_can_seek( m_file) && seconds >= 0.0 && seconds < m_length_in_seconds ) {
		if (m_audio_stream_count) {
			m_pcm_seek = gavl_time_to_samples(m_audio_format.samplerate, gt );
			if (m_pcm_seek >= m_num_samples || m_pcm_seek < 0) 
				m_pcm_seek = SEEK_NOTHING;
			unlockState();
			signalAV();
			return true;	
		} else if ( m_video_stream_count  && m_video_format.framerate_mode == GAVL_FRAMERATE_CONSTANT ) {
			m_frame_seek =	gavl_time_to_frames( m_video_format.timescale, m_video_format.frame_duration,  gt );
			if (m_frame_seek >= m_num_frames || m_frame_seek < 0 )
				m_frame_seek = SEEK_NOTHING;
			unlockState();
			signalAV();
			return true;
		}
	}
	unlockState();
	return false;
}
void ReadMedia::openFile( char * fn, int vsize, int asize, int spf) {
	lockState();
	/*
	if (  strcmp(m_filename, fn) == 0  && m_state == STATE_READY) {
		printf("%s is already open for action. \n", m_filename);
		unlockState();
		callOpenCallback();
		return;
	}
	*/
	// signal the dispatcher that we want an new file
	m_audio_format.samples_per_frame = spf ;
	m_afifosize = asize;
	m_vfifosize = vsize;
	sprintf(m_filename, "%s", fn);

	m_cmd = CMD_OPEN ;

	unlockState();
	signalDispatcher();
}
Exemple #30
0
void CState::clearState()
{
    unlockState();
    currentState_.clear();
}