gint go (MediaModule *module, gint pos_stream, gint pos_time, gboolean actual) { RfMediaXine *media = RF_MEDIA_XINE (module->widget); gint ps = 0, pt = 0; switch (actual) { case 0: xine_play (media->stream, pos_stream, pos_time); xine_set_param (media->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); xine_set_param (media->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); break; case 1: xine_get_pos_length (media->stream, &ps, &pt, NULL); if (pos_stream == 0) xine_play (media->stream, 0, pt+pos_time); else xine_play (media->stream, ps+pos_stream, 0); xine_set_param (media->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); break; } return (0); }
void engine_eq ( Equalizer * eq ) { xine_set_param ( stream, XINE_PARAM_EQ_30HZ, eq->eq_30 ); xine_set_param ( stream, XINE_PARAM_EQ_60HZ, eq->eq_60 ); xine_set_param ( stream, XINE_PARAM_EQ_125HZ, eq->eq_125 ); xine_set_param ( stream, XINE_PARAM_EQ_250HZ, eq->eq_250 ); xine_set_param ( stream, XINE_PARAM_EQ_500HZ, eq->eq_500 ); xine_set_param ( stream, XINE_PARAM_EQ_1000HZ, eq->eq_1000 ); xine_set_param ( stream, XINE_PARAM_EQ_2000HZ, eq->eq_2000 ); xine_set_param ( stream, XINE_PARAM_EQ_4000HZ, eq->eq_4000 ); xine_set_param ( stream, XINE_PARAM_EQ_8000HZ, eq->eq_8000 ); xine_set_param ( stream, XINE_PARAM_EQ_16000HZ, eq->eq_16000 ); }
void engine_init ( Config * init_conf) { conf = init_conf; // Create our libxine engine, and initialise it engine = xine_new(); xine_init ( engine ); // Automatically choose an audio driver ap = xine_open_audio_driver ( engine, NULL, NULL ); // Create a new stream object stream = xine_stream_new ( engine, ap, NULL ); meta_stream = xine_stream_new ( engine, NULL, NULL ); //TODO in CFG zetten?? xine_set_param ( stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1 ); queue = xine_event_new_queue ( stream ); xine_event_create_listener_thread ( queue, event_callback, NULL ); volume = xine_get_param ( stream, XINE_PARAM_AUDIO_VOLUME ); engine_state = engine_stoped; }
static void event_callback ( void *user_data, const xine_event_t *event ) { if ( event->type == XINE_EVENT_UI_PLAYBACK_FINISHED && controller_has_next_song() ){ current_song = controller_process_to_next_song(); xine_set_param ( event->stream, XINE_PARAM_GAPLESS_SWITCH, 1 ); xine_open_and_play(current_song); }else if(event->type == XINE_EVENT_UI_PLAYBACK_FINISHED && !controller_has_next_song()){ engine_state = engine_stoped; }else if(event->type == XINE_EVENT_PROGRESS){ xine_progress_data_t * prog = event->data; if(prog->percent == 0){ gui_progress_start((char *)prog->description); }else if(prog->percent == 100){ gui_progress_stop(); }else{ int pcts = prog->percent; if(pcts < 0){ pcts = 0; }else if(pcts > 100){ pcts = 100; } gui_progress_animate(); gui_progress_value(pcts); } } }
//Rva 100 = 100% = no change 0<->200 void engine_rva ( int rva ) { if ( rva >= 0 && rva <= 200 ) { xine_set_param ( stream, XINE_PARAM_AUDIO_AMP_LEVEL, rva ); } }
/** * Calls MMSAV::open() with the queue_cb callback. */ void MMSSound::xineOpen() { MMSAV::xineOpen(queue_cb); // ignore video xine_set_param(this->stream, XINE_PARAM_IGNORE_VIDEO, true); }
virtual void play() { if (_status!=PLAYING && _stream) { if (_status==PAUSED) { xine_set_param (_stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); _status=PLAYING; } else { OSG_INFO<<"XineImageStream::play()"<<std::endl; if (xine_play(_stream, 0, 0)) { while (!_ready) { OSG_INFO<<" waiting..."<<std::endl; OpenThreads::Thread::microSleep(10000); } _status=PLAYING; } else { OSG_NOTICE<<"Error!!!"<<std::endl; } } } }
void engine_resume_playback(void){ if(engine_state == engine_paused && xine_get_param(stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE){ xine_set_param ( stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL ); engine_state = engine_playing; }else if(engine_state == engine_paused && xine_get_param(stream, XINE_PARAM_SPEED) == XINE_SPEED_NORMAL){ engine_state = engine_stoped; //TODO klopt deze aanname?? } }
void engine_pause_playback(void){ if(engine_state == engine_playing && xine_get_param(stream, XINE_PARAM_SPEED) == XINE_SPEED_NORMAL){ xine_set_param ( stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE ); engine_state = engine_paused; }else if(engine_state == engine_playing && xine_get_param(stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE){ engine_state = engine_paused; } }
//vol = 0 .. 100 void engine_volume ( int vol ) { if ( vol >= 0 && vol <= 100 ) { xine_set_param ( stream, XINE_PARAM_AUDIO_VOLUME, vol ); volume = vol; } }
void SjPlayer::DoPause(bool fadeToPause) { if( m_impl->m_currStream ) { xine_set_param(m_impl->m_currStream->GetXineStream(), XINE_PARAM_SPEED, XINE_SPEED_PAUSE); m_paused = true; } }
void setVolume(float volume) { _volume = osg::minimum(osg::maximum(volume,0.0f),1.0f); if (_stream) { xine_set_param(_stream, XINE_PARAM_AUDIO_VOLUME, static_cast<int>(_volume*100.0f)); OSG_NOTICE<<"Setting volume "<<_volume<<std::endl; } }
void Xine::mute(){ if (quitting) return; pthread_mutex_lock(&stream_mutex); if(!validate_stream()){ pthread_mutex_unlock(&stream_mutex); return; } is_muted = !is_muted; if (mixer_cap) xine_set_param(stream, XINE_PARAM_AUDIO_AMP_MUTE, is_muted); else xine_set_param(stream, XINE_PARAM_AUDIO_MUTE, is_muted); xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, (is_muted) ? 0 : volume); pthread_mutex_unlock(&stream_mutex); }
bool XineEngine::makeNewStream() { m_currentAudioPlugin = XineCfg::outputPlugin(); m_audioPort = xine_open_audio_driver( m_xine, XineCfg::outputPlugin().local8Bit(), NULL ); if( !m_audioPort ) { //TODO make engine method that is the same but parents the dialog for us KMessageBox::error( 0, i18n("xine was unable to initialize any audio drivers.") ); return false; } m_stream = xine_stream_new( m_xine, m_audioPort, NULL ); if( !m_stream ) { xine_close_audio_driver( m_xine, m_audioPort ); m_audioPort = NULL; KMessageBox::error( 0, i18n("Pana could not create a new xine stream.") ); return false; } if( m_eventQueue ) xine_event_dispose_queue( m_eventQueue ); xine_event_create_listener_thread( m_eventQueue = xine_event_new_queue( m_stream ), &XineEngine::XineEventListener, (void*)this ); #ifndef XINE_SAFE_MODE //implemented in xine-scope.h m_post = scope_plugin_new( m_xine, m_audioPort ); xine_set_param( m_stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); xine_set_param( m_stream, XINE_PARAM_IGNORE_VIDEO, 1 ); #endif #ifdef XINE_PARAM_EARLY_FINISHED_EVENT if ( xine_check_version(1,1,1) && !(m_xfadeLength > 0) ) { // enable gapless playback debug() << "gapless playback enabled." << endl; //xine_set_param(m_stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1 ); } #endif return true; }
gint rf_media_pause (MediaModule *module) { RfMediaXine *media = RF_MEDIA_XINE (module->widget); xine_set_param (media->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); return 0; }
void SjPlayer::DoSetMainVol() { if( m_impl->m_currStream ) { int v; v = (int)((double)100*m_mainGain); if( v < 0 ) v = 0; if( v > 100 ) v = 0; xine_set_param(m_impl->m_currStream->GetXineStream(), XINE_PARAM_AUDIO_VOLUME, v); // XINE_PARAM_AUDIO_VOLUME sets internally AO_PROP_MIXER_VOL, } }
void Xine::volup(){ if (quitting) return; pthread_mutex_lock(&stream_mutex); if(!validate_stream()){ pthread_mutex_unlock(&stream_mutex); return; } volume +=2; if (volume > 100) volume = 100; xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, volume); if (mixer_cap) xine_set_param(stream, XINE_PARAM_AUDIO_AMP_MUTE, 0); else xine_set_param(stream, XINE_PARAM_AUDIO_MUTE, 0); is_muted = 0; pthread_mutex_unlock(&stream_mutex); }
virtual void pause() { if (_status==PAUSED || _status==INVALID) return; _status=PAUSED; if (_stream) { xine_set_param (_stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); } }
void Xine::setvol(int vol){ if (quitting) return; pthread_mutex_lock(&stream_mutex); volume = vol; if(!validate_stream()){ pthread_mutex_unlock(&stream_mutex); return; } xine_set_param(stream, XINE_PARAM_AUDIO_VOLUME, vol); pthread_mutex_unlock(&stream_mutex); }
gint play (MediaModule *module) { RfMediaXine *media = RF_MEDIA_XINE (module->widget); gint ps=0; xine_get_pos_length (media->stream, &ps, NULL, NULL); xine_play (media->stream, ps, 0); xine_set_param (media->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); return (0); }
/** * Playback will be switched to fast forward. * * There are two different speed settings for fast forward. * Twice as fast and four times as fast. */ void MMSSound::ffwd() { if (this->backend == MMSMEDIA_BE_GST) { #ifdef __HAVE_GSTREAMER__ #endif } else { #ifdef __HAVE_XINE__ if(this->status != this->STATUS_NONE) { this->setStatus(this->STATUS_FFWD); xine_set_param(this->stream, XINE_PARAM_SPEED, XINE_SPEED_FAST_4); } #endif } }
void SjPlayer::DoPlay(long ms, bool fadeToPlay) // press on play { if( m_impl->m_currStream ) { if( m_paused ) { // just switch state from pause to play xine_set_param(m_impl->m_currStream->GetXineStream(), XINE_PARAM_SPEED, XINE_SPEED_NORMAL); m_paused = false; } } else { // if we're not playing, we're also not paused... m_paused = false; // open player and start the stream at the current position if( m_queue.GetCount()<=0 ) { return; // don't log any error } if( !m_impl->InitXine() ) { return; // error } // open xine output ports (currently audio only) if( m_impl->m_ao_port == NULL ) { m_impl->m_ao_port = xine_open_audio_driver(m_impl->m_xine , static_cast<const char*>(m_impl->m_iniDevice.mb_str(wxConvUTF8)), NULL); if( m_impl->m_ao_port == NULL ) { wxLogError(wxT("Play()/xine_open_audio_driver() failed.")); return; } } DoSetMainVol(); // create a stream bound to the output long queuePos = m_queue.GetCurrPos(); m_impl->m_currStream = new SjXineStream(m_impl, m_queue.GetUrlByPos(queuePos)); if( !m_impl->m_currStream->XinePlay(ms) ) { wxLogError(wxT("DoPlay() failed.")); // Xine stream is non-functional, don't touch delete m_impl->m_currStream; m_impl->m_currStream = NULL; } } }
XineEngine::~XineEngine() { // Wait until the fader thread is done if( s_fader ) { m_stopFader = true; s_fader->wait(); delete s_fader; } // NOTE The fadeout gets stuck when the EQ is active, so we skip it then if( !m_equalizerEnabled && m_stream && state() == Engine::Playing ) { const int volume = xine_get_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL ); const double D = 300000 * std::pow( (double)volume, -0.4951 ); debug() << "Sleeping: " << D << ", " << volume << endl; for( int v = volume - 1; v >= 1; v-- ) { xine_set_param( m_stream, XINE_PARAM_AUDIO_AMP_LEVEL, v ); const int sleep = int(D * (-log10( v + 1 ) + 2)); ::usleep( sleep ); } xine_stop( m_stream ); } if( m_xine ) xine_config_save( m_xine, configPath() ); if( m_stream ) xine_close( m_stream ); if( m_eventQueue ) xine_event_dispose_queue( m_eventQueue ); if( m_stream ) xine_dispose( m_stream ); if( m_audioPort ) xine_close_audio_driver( m_xine, m_audioPort ); if( m_post ) xine_post_dispose( m_xine, m_post ); if( m_xine ) xine_exit( m_xine ); debug() << "xine closed\n"; debug() << "Scope statistics:\n" << " Average list size: " << Log::bufferCount / Log::scopeCallCount << endl << " Buffer failure: " << double(Log::noSuitableBuffer*100) / Log::scopeCallCount << "%\n"; }
bool Xine::make_new_stream(){ if (stream) xine_dispose(stream); std::string ao_driver = "auto"; GlobalOptions * go = S_GlobalOptions::get_instance(); global_audio_device gad = go->get_audio_device_audio(); if (gad.dev_output != ""){ ao_driver = gad.dev_output; } if (ao_port) xine_close_audio_driver(xine, ao_port); /* fprintf(stderr, "Audio driver: %s (%d)\n", ao_driver.c_str(), gad.pos); */ ao_port = xine_open_audio_driver(xine, ao_driver.c_str(), NULL); if (ao_port == NULL){ DialogWaitPrint pdialog(4000); pdialog.add_line(dgettext("mms-audio-xine", "Audio device unavailable: ") + ao_driver); pdialog.print(); return false; } /* Xine uses its own config file for a lot of stuff */ xine_cfg_entry_t config; /* for some reason this doesn't work for someone if (!xine_config_lookup_entry(xine, "input.cdda_device", &config)) { fprintf(stderr, "Xine: Can't set cdda device\n"); } else{ std::string str = S_Cd::get_instance()->get_device(); config.str_value = const_cast<char*>(str.c_str()); xine_config_update_entry(xine, &config); } */ /* Disable CDDB, we have our own CDDB library */ if (xine_config_lookup_entry(xine, "media.audio_cd.use_cddb", &config)){ config.num_value = 0; xine_config_update_entry(xine, &config); } stream = xine_stream_new(xine, ao_port, NULL); if (stream == NULL){ xine_close_audio_driver(xine, ao_port); ao_port = NULL; return false; } /* xine_set_param(stream, XINE_PARAM_VERBOSITY, XINE_VERBOSITY_DEBUG); */ if (event_queue) xine_event_dispose_queue(event_queue); xine_set_param( stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); xine_set_param( stream, XINE_PARAM_IGNORE_VIDEO, 1 ); #ifdef XINE_PARAM_EARLY_FINISHED_EVENT #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)) xine_set_param(stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1); #ifdef XINE_PARAM_DELAY_FINISHED_EVENT xine_set_param(stream, XINE_PARAM_DELAY_FINISHED_EVENT, 0); #endif #endif #endif event_queue = xine_event_new_queue(stream); mixer_cap = false; is_muted = xine_get_param(stream, XINE_PARAM_AUDIO_MUTE); if (is_muted == -1){ is_muted = xine_get_param(stream, XINE_PARAM_AUDIO_AMP_MUTE); mixer_cap = true; } xine_event_create_listener_thread(event_queue, &Xine::event_listener, reinterpret_cast<void*>(this)); return true; }
void Xine::run(){ /* this is the main thread */ playing = false; seamless = false; pthread_mutex_lock(&stream_mutex); struct timespec ts = time_helper::compute_interval(5000); Audio_s *audio_state = S_Audio_s::get_instance(); volume = 0; if(validate_stream()) volume = xine_get_param(stream, XINE_PARAM_AUDIO_VOLUME); old_volume = volume; while(!quitting){ xine_request = _XINE_REQUEST_NONE; int ret = pthread_cond_timedwait(&stream_switch, &stream_mutex, &ts); if (!running || quitting){ ts = time_helper::compute_interval(5000); continue; } if (ret != ETIMEDOUT && xine_request == _XINE_REQUEST_NONE) continue; /* we're not done waiting */ /* if (xine_request != _XINE_REQUEST_NONE) fprintf (stderr, "Loop received event request (%d)\n", xine_request); */ switch(xine_request){ case _XINE_REQUEST_PLAY_AT: case _XINE_REQUEST_PLAY:{ retry_track = false; if(!validate_stream()) break; #ifdef XINE_PARAM_EARLY_FINISHED_EVENT if (seamless && xine_check_version(1,1,1) && oldfile.type != "web" && file.type != "web"){ xine_set_param(stream, XINE_PARAM_GAPLESS_SWITCH, 1); } // else{ // xine_close(stream); // } seamless = false; #endif oldfile = file; /* fprintf(stderr, "file.path %s\n", file.path.c_str()); */ std::string _str = file.path; if (file.type == "media-track"){ std::string _path = "cdda:/" + cd_device + "/"; _str = regex_tools::regex_replace(_str, _path.c_str(), "^cdda:/", false, false); /* fprintf(stderr, "%s\n", _str.c_str()); */ } else { vector<string> urls = PlaylistParser::resolve_playlist(_str); if (!urls.empty()) _str = urls[0]; /* TODO: Handle multiple playlist entries here */ } if(!xine_open(stream, _str.c_str())){ #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)) xine_set_param(stream, XINE_PARAM_GAPLESS_SWITCH, 0); #endif break; } int len = 0; off_t play_at = 0; const bool has_audio = xine_get_stream_info( stream, XINE_STREAM_INFO_HAS_AUDIO ); const bool audio_handled = xine_get_stream_info( stream, XINE_STREAM_INFO_AUDIO_HANDLED ); if (xine_request == _XINE_REQUEST_PLAY_AT){ xine_get_pos_length(stream, 0, 0, &len); play_at = len > 0 ? static_cast<double>(cur_time*65535)/(len/1000) : 0; } else cur_time = 0; _cur_time = cur_time; total_time = 0; _total_time = 0; if ((has_audio || file.type == "web") && audio_handled && xine_play(stream, play_at, cur_time * 1000)){ playing = true; //gather_info_internal(); audio_state->set_playing(true); buffering_state = 0; } else{ playing = false; audio_state->set_playing(false); xine_close(stream); } audio_state->get_audio()->update_playlist_view(); #ifdef XINE_PARAM_EARLY_FINISHED_EVENT #ifdef XINE_PARAM_GAPLESS_SWITCH if (xine_check_version(1,1,1)){ if (!audio_state->get_audio()->next_helper(false).path.empty()){ xine_set_param(stream, XINE_PARAM_EARLY_FINISHED_EVENT, 1); /* fprintf(stderr, "Not last track\n"); */ #ifdef XINE_PARAM_DELAY_FINISHED_EVENT xine_set_param(stream, XINE_PARAM_DELAY_FINISHED_EVENT, 0); #endif } else { /* If we don't disable XINE_PARAM_DELAY_FINISHED_EVENT for the last track in the playlist, * xine won't play the last couple of seconds of it */ xine_set_param(stream, XINE_PARAM_EARLY_FINISHED_EVENT, 0); /* fprintf(stderr, "Last track\n"); */ } } #endif #endif if (start_paused){ start_paused = false; audio_state->set_pause(true); } else audio_state->set_pause(false); break; } case _XINE_REQUEST_STOP: case _XINE_REQUEST_RELEASE_DEVICE: retry_track = false; seamless = false; if(stream){ xine_close(stream); xine_event_dispose_queue(event_queue); event_queue = NULL; xine_dispose(stream); stream = NULL; } playing = false; audio_state->set_playing(false); if (xine_request == _XINE_REQUEST_RELEASE_DEVICE){ xine_close_audio_driver(xine, ao_port); ao_port = NULL; } break; case _XINE_REQUEST_PAUSE: if(!validate_stream()||!playing) break; if(xine_get_param(stream, XINE_PARAM_SPEED) != XINE_SPEED_PAUSE) { xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); audio_state->set_pause(true); } else { xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); audio_state->set_pause(false); } break; case _XINE_REQUEST_FF:{ if(!playing || !validate_stream()) break; gather_info_internal(); if (_cur_time + 5 > _total_time) break; _cur_time +=5; off_t pos = _total_time > 0 ? static_cast<double>(_cur_time*65535)/_total_time : 0; xine_play(stream, pos, _cur_time*1000); audio_state->set_pause(false); break; } case _XINE_REQUEST_FB:{ if(!playing || !validate_stream()) break; gather_info_internal(); if (static_cast<int>(_cur_time) - 5 < 0) break; _cur_time -=5; off_t pos = _total_time > 0 ? static_cast<double>(_cur_time*65535)/_total_time : 0; xine_play(stream, pos, _cur_time*1000); audio_state->set_pause(false); break; } default: break; } if (ret == ETIMEDOUT && playing) gather_info_internal(); if (playing) ts = time_helper::compute_interval(500); else ts = time_helper::compute_interval(5000); } if(stream){ xine_close(stream); xine_event_dispose_queue(event_queue); event_queue = NULL; xine_dispose(stream); stream = NULL; } playing = false; if (ao_port) xine_close_audio_driver(xine, ao_port); ao_port = NULL; pthread_mutex_unlock(&stream_mutex); /* bye */ }
/* this is a slave controller thread for the xine module - libxine loves * to deadlock, internally stall and otherwise have unpredictable behavior * if we use the main process thread for many things - so a lot will be * farmed off to this slave. its job is to handle opening, closing, file * opening, recoder init etc. and all sorts of things can that often block. * anything this thread needs to return, it will return via the event pipe. */ static void * _em_slave(void *par) { Emotion_Xine_Video *ev; void *buf[2]; int len; ev = (Emotion_Xine_Video *)par; while ((len = read(ev->fd_slave_read, buf, sizeof(buf))) > 0) { if (len == sizeof(buf)) { Emotion_Xine_Event *eev; ev = buf[0]; eev = buf[1]; switch (eev->mtype) { case 0: /* noop */ break; case 1: /* init */ { ev->decoder = xine_new(); xine_init(ev->decoder); xine_register_plugins(ev->decoder, emotion_xine_plugin_info); if (1) { xine_cfg_entry_t cf; if (xine_config_lookup_entry(ev->decoder, "input.dvd_use_readahead", &cf)) { cf.num_value = 1; // 0 or 1 xine_config_update_entry(ev->decoder, &cf); } } DBG("OPEN VIDEO PLUGIN..."); if (!ev->opt_no_video) ev->video = xine_open_video_driver(ev->decoder, "emotion", XINE_VISUAL_TYPE_NONE, ev); DBG("RESULT: xine_open_video_driver() = %p", ev->video); // Let xine autodetect the best audio output driver if (!ev->opt_no_audio) ev->audio = xine_open_audio_driver(ev->decoder, NULL, ev); // ev->audio = xine_open_audio_driver(ev->decoder, "oss", ev); // dont use alsa - alsa has oss emulation. // ev->audio = xine_open_audio_driver(ev->decoder, "alsa", ev); // ev->audio = xine_open_audio_driver(ev->decoder, "arts", ev); // ev->audio = xine_open_audio_driver(ev->decoder, "esd", ev); ev->stream = xine_stream_new(ev->decoder, ev->audio, ev->video); ev->queue = xine_event_new_queue(ev->stream); xine_event_create_listener_thread(ev->queue, _em_event, ev); ev->opening = 0; ev->play_ok = 1; _em_module_event(ev, 1); /* event - open done */ } break; case 3: /* shutdown */ { _em_module_event(ev, 3); DBG("shutdown stop"); xine_stop(ev->stream); // pthread_mutex_lock(&(ev->get_pos_len_mutex)); if (!ev->get_pos_thread_deleted) { DBG("closing get_pos thread, %p", ev); pthread_mutex_lock(&(ev->get_pos_len_mutex)); pthread_cond_broadcast(&(ev->get_pos_len_cond)); pthread_mutex_unlock(&(ev->get_pos_len_mutex)); while (ev->get_poslen); } DBG("dispose %p", ev); xine_dispose(ev->stream); DBG("dispose evq %p", ev); xine_event_dispose_queue(ev->queue); DBG("close video drv %p", ev); if (ev->video) xine_close_video_driver(ev->decoder, ev->video); DBG("wait for vo to go"); while (ev->have_vo); DBG("vo gone"); DBG("close audio drv %p", ev); if (ev->audio) xine_close_audio_driver(ev->decoder, ev->audio); DBG("xine exit %p", ev); xine_exit(ev->decoder); DBG("DONE %p", ev); close(ev->fd_write); close(ev->fd_read); close(ev->fd_ev_write); close(ev->fd_ev_read); close(ev->fd_slave_write); close(ev->fd_slave_read); ev->closing = 0; if (eev->xine_event) free(eev->xine_event); free(eev); free(ev); return NULL; } break; case 2: /* file open */ { int pos_stream = 0; int pos_time = 0; int length_time = 0; uint32_t v; char *file; file = eev->xine_event; DBG("OPEN STREAM %s", file); if (xine_open(ev->stream, file)) { if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time)) { if (length_time == 0) { ev->pos = (double)pos_stream / 65535; ev->len = 1.0; ev->no_time = 1; } else { ev->pos = 0.0; ev->len = (double)length_time / 1000.0; } } else { ev->pos = 0.0; ev->len = 1.0; } v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_FRAME_DURATION); if (v > 0) ev->fps = 90000.0 / (double)v; v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_WIDTH); ev->w = v; v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_HEIGHT); ev->h = v; v = xine_get_stream_info(ev->stream, XINE_STREAM_INFO_VIDEO_RATIO); ev->ratio = (double)v / 10000.0; ev->just_loaded = 1; ev->get_poslen = 0; xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, ev->volume * 100); } _em_module_event(ev, 2); /* event - open done */ } break; case 11: /* file close */ { DBG("done %p", ev); em_frame_done(ev); DBG("stop %p", ev); xine_stop(ev->stream); DBG("close %p", ev); xine_close(ev->stream); DBG("close done %p", ev); _em_module_event(ev, 11); } break; case 4: /* play */ { double pos; int pos_stream, pos_time, length_time; pos = *((double *)eev->xine_event); if ((xine_get_param(ev->stream, XINE_PARAM_SPEED) == XINE_SPEED_PAUSE) && (pos == ev->pos) && (!ev->just_loaded)) { xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL); } else { if (ev->no_time) xine_play(ev->stream, pos * 65535, 0); else xine_play(ev->stream, 0, pos * 1000); } ev->just_loaded = 0; if (xine_get_pos_length(ev->stream, &pos_stream, &pos_time, &length_time)) { if (length_time == 0) { ev->pos = (double)pos_stream / 65535; ev->len = 1.0; ev->no_time = 1; } else { ev->pos = (double)pos_time / 1000.0; ev->len = (double)length_time / 1000.0; } } _em_module_event(ev, 4); } break; case 5: /* stop */ { xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); _em_module_event(ev, 5); } break; case 6: /* seek */ { double pos; pos = *((double *)eev->xine_event); if (ev->no_time) xine_play(ev->stream, pos * 65535, 0); else xine_play(ev->stream, 0, pos * 1000); if (!ev->play) xine_set_param(ev->stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE); _em_module_event(ev, 6); } break; case 7: /* eject */ { xine_eject(ev->stream); _em_module_event(ev, 7); } break; case 8: /* spu mute */ { xine_set_param(ev->stream, XINE_PARAM_IGNORE_SPU, ev->spu_mute); _em_module_event(ev, 8); } break; case 9: /* channel */ { xine_set_param(ev->stream, XINE_PARAM_SPU_CHANNEL, ev->spu_channel); _em_module_event(ev, 9); } break; case 10: /* vol */ { xine_set_param(ev->stream, XINE_PARAM_AUDIO_VOLUME, ev->volume * 100); _em_module_event(ev, 10); } break; case 12: /* audio mute */ { xine_set_param(ev->stream, XINE_PARAM_AUDIO_MUTE, ev->audio_mute); } break; case 13: /* audio mute */ { xine_set_param(ev->stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, ev->audio_channel); } break; case 14: /* audio mute */ { xine_set_param(ev->stream, XINE_PARAM_VIDEO_CHANNEL, ev->video_channel); } break; default: break; } if (eev->xine_event) free(eev->xine_event); free(eev); } } return NULL; }