예제 #1
0
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;
}
예제 #2
0
eServiceXine::eServiceXine(const char *filename): m_filename(filename), m_pump(eApp, 1)
{
	m_state = stError;
	stream = 0;
	event_queue = 0;
	ao_port = 0;
	vo_port = 0;


//	if ((vo_port = xine_open_video_driver(xine, "fb", XINE_VISUAL_TYPE_FB, NULL)) == NULL)
	if ((vo_port = xine_open_video_driver(xine, "none", XINE_VISUAL_TYPE_NONE, NULL)) == NULL)
	{
		eWarning("cannot open xine video driver");
	}

	if ((ao_port = xine_open_audio_driver(xine , "alsa", NULL)) == NULL)
	{
		eWarning("cannot open xine audio driver");
	}
	stream = xine_stream_new(xine, ao_port, vo_port);
	event_queue = xine_event_new_queue(stream);
	xine_event_create_listener_thread(event_queue, eventListenerWrap, this);

//	CONNECT(m_pump.recv_msg, eServiceXine::gstPoll);
	m_state = stIdle;
}
gint
event_init (void *ptr_media, void (*media_event_cb)(gint event)) {
	
	RfMediaXine     *media = RF_MEDIA_XINE(ptr_media);

	xine_event_create_listener_thread (xine_event_new_queue (media->stream), xine_event_cb, media_event_cb);
	
	return 0;

}
예제 #4
0
static int v4l2_input_open(input_plugin_t *this_gen) {
    v4l2_input_plugin_t *this = (v4l2_input_plugin_t*) this_gen;
    int ret;
    lprintf("Opening %s\n", this->mrl);
	this->fd = v4l2_open(this->mrl, O_RDWR);
	if (this->fd) {
        /* TODO: Clean up this mess */
        this->events = xine_event_new_queue(this->stream);
	ret = v4l2_ioctl(this->fd, VIDIOC_QUERYCAP, &(this->cap));
	if (ret < 0)
	{
	  xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
		   LOG_MODULE": capability query failed: %s\n", strerror (-ret));
	  return 0;
	}
        if (this->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
            this->video = malloc(sizeof(v4l2_video_t));
            this->video->headerSent = 0;
            this->video->bufcount = 0;
        }
        if (this->cap.capabilities & V4L2_CAP_STREAMING) {
            lprintf("Supports streaming. Allocating buffers...\n");
            if (this->cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) {
                if (v4l2_input_setup_video_streaming(this)) {
                    lprintf("Video streaming ready.\n");
                    return 1;
                } else {
                    /* TODO: Fallbacks */
		    xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
			     LOG_MODULE": video streaming setup failed\n");
                    return 0;
                }
            } else {
                /* TODO: Radio streaming */
		xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
			 LOG_MODULE": sorry, only video is supported for now\n");
                return 0;
            }
        } else {
	    xprintf (this->stream->xine, XINE_VERBOSITY_LOG,
		     LOG_MODULE": device doesn't support streaming - prod the author to support the other methods\n");
            return 0;
        }
    } else {
        return 0;
    }
}
예제 #5
0
	bool XinePlay(long ms = 0)
	{
		wxASSERT( m_stream == NULL && m_event_queue == NULL );
		if( m_stream || m_event_queue ) {
			wxLogError(wxT("xine_play() already called."));
			return false;
		}

		wxASSERT( m_impl->m_xine && m_impl->m_ao_port );
		if( m_impl->m_xine==NULL || m_impl->m_ao_port==NULL ) {
			wxLogError(wxT("xine not initialized."));
			return false;
		}

		// create a new stream
		m_stream = xine_stream_new(m_impl->m_xine, m_impl->m_ao_port, NULL);
		if( m_stream == NULL ) {
			wxLogError(wxT("xine_stream_new() failed."));
			return false;
		}

		// add event listener to stream
		m_event_queue = xine_event_new_queue(m_stream);
		if( m_event_queue == NULL ) {
			cleanup();
			wxLogError(wxT("xine_event_new_queue() failed."));
			return false;
		}
		xine_event_create_listener_thread(m_event_queue, xine_event_listener_cb, (void*)this);

		// open a URL for the stream
		if( !xine_open(m_stream, static_cast<const char*>(m_url.mb_str(wxConvUTF8))) ) {
			cleanup();
			wxLogError(wxT("xine_open() failed."));
			return false;
		}

		// finally, play
		if( !xine_play(m_stream, 0, ms) ) {
			cleanup();
			wxLogError(wxT("GotoAbsPos()/xine_play() failed."));
			return false;
		}

		return true;
	}
예제 #6
0
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;
}
예제 #7
0
파일: music.c 프로젝트: hsgg/quark
void
music_init ()
{
    char *configfile;

    if (!xine_check_version (XINE_MAJOR_VERSION, XINE_MINOR_VERSION,
                             XINE_SUB_VERSION)) {
        g_critical (_("Incompatible version of Xine-lib found."));
        exit (EXIT_FAILURE);
    }

    xine = xine_new ();

    configfile = g_build_filename (g_get_home_dir (), ".xine", "config", NULL);
    xine_config_load (xine, configfile);
    g_free (configfile);

    xine_init (xine);

    if (!(ao = xine_open_audio_driver (xine, NULL, NULL))) {
        g_critical (_("Unable to open audio driver from Xine."));
        exit (EXIT_FAILURE);
    }

    if (!(vo = xine_open_video_driver (xine, NULL, XINE_VISUAL_TYPE_NONE,
                                       NULL))) {
        g_critical (_("Unable to open video driver from Xine."));
        exit (EXIT_FAILURE);
    }

    if (!(stream = xine_stream_new (xine, ao, vo))) {
        g_critical (_("Unable to open a Xine stream."));
        exit (EXIT_FAILURE);
    }

    events = xine_event_new_queue (stream);
    xine_event_create_listener_thread (events, music_events, NULL);
}
예제 #8
0
        bool open(xine_t* xine, const std::string& filename)
        {
            if (filename==getFileName()) return true;

            _xine = xine;

            // create visual
            rgbout_visual_info_t* visual = new rgbout_visual_info_t;
            visual->levels = PXLEVEL_ALL;
            visual->format = PX_RGB32;
            visual->user_data = this;
            visual->callback = my_render_frame;

            // set up video driver
            _vo = xine_open_video_driver(_xine, "rgb", XINE_VISUAL_TYPE_RGBOUT, (void*)visual);

            // set up audio driver
            char* audio_driver = getenv("OSG_XINE_AUDIO_DRIVER");
            _ao = audio_driver ? xine_open_audio_driver(_xine, audio_driver, NULL) : xine_open_audio_driver(_xine, "auto", NULL);

            if (!_vo)
            {
                OSG_NOTICE<<"XineImageStream::open() : Failed to create video driver"<<std::endl;
                return false;
            }


            // set up stream
            _stream = xine_stream_new(_xine, _ao, _vo);

            if (_stream)
            {
                if (_volume < 0.0)
                {
                    _volume = static_cast<float>(xine_get_param(_stream, XINE_PARAM_AUDIO_VOLUME))/100.0f;
                }
                else
                {
                    setVolume(_volume);
                }
            }

            _event_queue = xine_event_new_queue(_stream);
            xine_event_create_listener_thread(_event_queue, event_listener, this);

            int result = xine_open(_stream, filename.c_str());

            if (result==0)
            {
                OSG_INFO<<"XineImageStream::open() : Could not ready movie file."<<std::endl;
                close();
                return false;
            }


            _ready = false;

            int width = xine_get_stream_info(_stream,XINE_STREAM_INFO_VIDEO_WIDTH);
            int height = xine_get_stream_info(_stream,XINE_STREAM_INFO_VIDEO_HEIGHT);
            allocateImage(width,height,1,GL_RGB,GL_UNSIGNED_BYTE,1);

            OSG_INFO<<"XineImageStream::open() size "<<width<<" "<<height<<std::endl;

            // play();

            return true;

        }
예제 #9
0
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;
}
예제 #10
0
/* 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;
}
예제 #11
0
	bool XinePlay(long ms = 0)
	{
		wxASSERT( m_stream == NULL && m_event_queue == NULL );
		if( m_stream || m_event_queue ) {
			wxLogError(wxT("xine_play() already called."));
			return false;
		}

		wxASSERT( m_impl->m_xine && m_impl->m_ao_port );
		if( m_impl->m_xine==NULL || m_impl->m_ao_port==NULL ) {
			wxLogError(wxT("xine not initialized."));
			return false;
		}

		// create a new stream
		m_stream = xine_stream_new(m_impl->m_xine, m_impl->m_ao_port, NULL);
		if( m_stream == NULL ) {
			wxLogError(wxT("xine_stream_new() failed."));
			return false;
		}

		// add event listener to stream
		m_event_queue = xine_event_new_queue(m_stream);
		if( m_event_queue == NULL ) {
			cleanup();
			wxLogError(wxT("xine_event_new_queue() failed."));
			return false;
		}
		xine_event_create_listener_thread(m_event_queue, xine_event_listener_cb, (void*)this);

		// open a URL for the stream
		if( !xine_open(m_stream, static_cast<const char*>(m_url.mb_str(wxConvUTF8))) )
		{
			// failed, as xine is compatible to file:-URLs, this URL may be http, ZIP or sth. like that.
			// try over by copying the URL to a local file
			bool failed = true;
			wxFileSystem fs;
			wxFSFile* fsFile = fs.OpenFile(m_url, wxFS_READ);
			if( fsFile )
			{
				wxString tempFileName = g_tools->m_cache.AddToManagedTemp(SjTools::GetExt(m_url), SJ_TEMP_PROTECT_TIL_EXIT);
				wxFile tempFile(tempFileName, wxFile::write);
				if( SjTools::CopyStreamToFile(*(fsFile->GetStream()), tempFile) )
				{
					if( xine_open(m_stream, static_cast<const char*>(tempFileName.mb_str(wxConvUTF8))) )
					{
						failed = false;
					}
				}
				delete fsFile;
			}

			if( failed )
			{
				cleanup();
				wxLogError(wxT("xine_open() failed."));
				return false;
			}
		}

		// finally, play
		if( !xine_play(m_stream, 0, ms) ) {
			cleanup();
			wxLogError(wxT("GotoAbsPos()/xine_play() failed."));
			return false;
		}

		m_startingTime = wxDateTime::Now().GetAsDOS();

		return true;
	}