Пример #1
0
void SjPlayer::DoGetTime(long& totalMs, long& elapsedMs)
{
	if( m_impl->m_currStream )
	{
		totalMs = -1; // if there is a stream, the pos/length may be unknown
		elapsedMs = -1;
		int pos_stream = -1, pos_time_ms = -1, length_time_ms = -1;
		if( xine_get_pos_length(m_impl->m_currStream->GetXineStream(), &pos_stream, &pos_time_ms, &length_time_ms) )
		{
			// for HTTP-streams, xine sometimes returns bad values as 1083696000 or 285440000 for the length,
			// so, do not allow length > 1 day
			if( length_time_ms >= 0 && length_time_ms < (24*60*60*1000) )
			{
				totalMs = length_time_ms;
			}

			if( pos_time_ms >= 0 ) {
				elapsedMs = pos_time_ms;
			}
		}
	}
	else
	{
		totalMs = 0; // "no stream" has a length of "0"
		elapsedMs = 0;
	}
}
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);
	
}
Пример #3
0
static void xine_open_and_play(char * file)
{
  int tmp;
  if(file == NULL){
    return;
  }
  char * tmp3 = malloc(((sizeof(char) * strlen(file) * 3)) + 1);
  char * tmp2 = malloc(((sizeof(char) * strlen(file) * 3)) + 7);
  if(file[0] == '/'){
    url_encode(file, tmp3);
    sprintf(tmp2, "file:/%s", tmp3);
  }else{
    sprintf(tmp2, "%s", file);
  }
  xine_close ( stream );
  log_debug(tmp2);
  free(tmp3);
  if(!xine_open ( stream, tmp2)){
    return;
  }
  free(tmp2);
  if(!xine_play ( stream, 0, 0 )){
    return;
  }
  int count = 0;
  while ( !xine_get_pos_length ( stream, &tmp, &tmp, &length ) ) // The header file states: "probably because it's not known yet... try again later"
  {
	sleepTS.tv_sec = 0;
	sleepTS.tv_nsec = 10000000;
	nanosleep(&sleepTS,NULL); //Just try until you get some usefull info
	count++;
	if(count>5) break;
    //log_debug("Sleeping");
  }
}
Пример #4
0
static void engine_fwd(int mill, int expFactor, char forward)
{
  if ( engine_state == engine_playing )
  {
    int pos_stream, pos_time;
    int speedUp = 5;
    sleepTS.tv_sec = 0;
    sleepTS.tv_nsec = 20000000;
    time_t currentWind;
    time(&currentWind);
    int count = 0;
    while( !xine_get_pos_length ( stream, &pos_stream , &pos_time , &length ) ) {
      nanosleep(&sleepTS,NULL);
      count++;
      if(count>5) return;
      if(engine_state != engine_playing) return;
    }
    if ( difftime(currentWind,previousWind) < 2) {
      windFactor *= (1 + (float) expFactor/1000);
    } else {
      windFactor = 1;
    }
    time(&previousWind);
    speedUp = speedUp * (int) windFactor;
    if(forward){
      xine_play( stream , 0 , pos_time + ( mill * speedUp) );
    }else{
      xine_play( stream , 0 , pos_time - ( mill * speedUp) );
    }
    nanosleep(&sleepTS,NULL);
  }
}
Пример #5
0
int engine_get_remaining ( void )
{
	int a, b;
    if ( !xine_get_pos_length ( stream, &a, &b, &length ) && !length)
	{
		return 0;
	}
	return ( length - b ) / 1000;
}
Пример #6
0
int engine_get_elapsed ( void )
{
	int a, b;
    if ( !xine_get_pos_length ( stream, &a, &b, &length ) )
	{
		return 0;
	}
	return b / 1000;
}
Пример #7
0
static int icvSeekRatioAVI_XINE( CvCaptureAVI_XINE* capture, double ratio )
{
#ifndef NDEBUG
    fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... start\n" );
#endif

    OPENCV_ASSERT ( capture,
                        "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture");
    OPENCV_ASSERT ( capture->stream,
                        "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture->stream");
    OPENCV_ASSERT ( capture->vo_port,
                        "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture->vo_port");

// not needed tnx to asserts...
    // we need a valid capture context and it's stream to seek through
//	if ( !capture || !capture->stream ) return 0;

    /// ratio must be [0..1]
    if ( ratio > 1 || ratio < 0 ) return 0;

    if ( capture->seekable )
    {
    // TODO: FIX IT, DOESN'T WORK PROPERLY, YET...!
        int pos_t, pos_l, length;
        xine_get_pos_length( capture->stream, &pos_l, &pos_t, &length );
        fprintf( stderr, "ratio on GetProperty(): %d\n", pos_l );

        /// use xinelib's seek functionality
        if ( xine_play( capture->stream, (int)(ratio*(float)length), 0 ) )
        {
            capture->frame_number = ( int ) ( ratio*length / capture->frame_duration );
        }
        else
        {
#ifndef NDEBUG
            fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... failed!\n" );
#endif
            return 0;
        }
    }
    else
    {
        /// TODO: fill it !
        fprintf( stderr, "icvSeekRatioAVI_XINE(): Seek not supported by stream !\n" );
        fprintf( stderr, "icvSeekRatioAVI_XINE(): (seek in stream with NO seek support NOT implemented...yet!)\n" );
#ifndef NDEBUG
        fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... failed!\n" );
#endif
        return 0;
    }

#ifndef NDEBUG
    fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... end!\n" );
#endif
    return 1;
}
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);
	
}
gint 
get_position (MediaModule *module, gint *pos_stream, gint *pos_time, gint *time) {
	
	RfMediaXine      *media = RF_MEDIA_XINE (module->widget);
	gint              ptime, ttime, w;
	
	w = xine_get_pos_length (media->stream, pos_stream, &ptime, &ttime);
	
	*pos_time = ptime / 1000;
	*time = ttime / 1000;
	
	return w;
	
}
Пример #10
0
void Xine::gather_info_internal(){
  if (quitting)
    return;
  if (!validate_stream())
    return;
  if (file.type == "media-track"){
    _title = "";
    _artist = "";
    _album = "";
  }
  else{
    const char *meta_info = xine_get_meta_info(stream, XINE_META_INFO_TITLE);
    _title = (meta_info) ? meta_info : "";
    meta_info = xine_get_meta_info(stream, XINE_META_INFO_ARTIST);
    _artist = (meta_info) ? meta_info : "";
    meta_info = xine_get_meta_info(stream, XINE_META_INFO_ALBUM);
    _album = (meta_info) ? meta_info : "";
    meta_info = xine_get_meta_info(stream, XINE_META_INFO_INPUT_PLUGIN);
    if (meta_info) /* If it is not a local file, _artist = _album, so that mms doesn't just show the filename */
      if (strcasecmp(meta_info, "pluginfile") != 0){
	_artist = _album;
	_album = "";
      }
  }


  int position_, length_ = 0;
  for (int t = 0; t < 5; t++){ /* sometimes xine doesn't return a valid position, especially after a seek
                                while playing an audio CD (it sucks) */
    xine_get_pos_length(stream, 0, &position_, &length_);
    if (position_ > 0)
      break;
    mmsUsleep(50000);
  }

  if (position_ > 0){
    _cur_time = position_/1000;
    _total_time = length_/1000;
  }
/*
  else
  {
    _title = "";
    _artist ="";
    _album = "Buffering...";
  }
*/ 
  //fprintf(stderr, "Gather info internal (position %d)\n", _cur_time);
}
Пример #11
0
Файл: music.c Проект: hsgg/quark
void
music_pause ()
{
    int state;

    state = xine_get_status (stream);
    if (state != XINE_STATUS_IDLE) {
        int pos, time, length;
        /* length = 0 for streams */
        if (!(xine_get_pos_length (stream, &pos, &time, &length) && length))
            pos = 0;
        stream_pos = pos;
        g_message ("stream_pos: %d", pos);
        xine_close (stream);
    }
    music_playing = FALSE;
    music_notify_paused ();
}
Пример #12
0
RESULT eServiceXine::getPlayPosition(pts_t &pts)
{
	pts = -1;
	if (m_state == stError)
		return 1;
	ASSERT(stream);

	int pos_stream, pos_time, length_time;

	if (!xine_get_pos_length(stream, &pos_stream, &pos_time, &length_time))
		return 1;

	eDebug("pos_time: %d", pos_time);
	pts = pos_time * 90;

		// GET POSITION
	return 0;
}
Пример #13
0
static void xine_open_and_play(char * file)
{
	if(file == NULL)
	{
		return;
	}

	char * file_uri = malloc(((sizeof(char) * strlen(file) * 3)) + 7);

	if(file[0] == '/')
	{
 		char * file_encoded =  malloc(((sizeof(char) * strlen(file) * 3)) + 1);
		url_encode(file, file_encoded);
		sprintf(file_uri, "file:/%s", file_encoded);
		free(file_encoded);
	}
	else
	{
		sprintf(file_uri, "%s", file);
	}
	xine_close ( stream );
	log_debug_format("engine: %s\n", file_uri);

	if(!xine_open ( stream, file_uri)){
		return;
	}
	free(file_uri);

	if(!xine_play ( stream, 0, 0 )){
		return;
	}

	int count = 0;
	int dummy1, dummy2;
	// The header file states: "probably because it's not known yet... try again later"
	while ( !xine_get_pos_length ( stream, &dummy1, &dummy2, &length ) )
	{
		sleepTS.tv_sec = 0;
		sleepTS.tv_nsec = 10000000;
		nanosleep(&sleepTS,NULL); //Just try until you get some usefull info
		count++;
		if(count>5) break;
	}
}
Пример #14
0
RESULT eServiceXine::getLength(pts_t &pts)
{
	pts = -1;
	if (m_state == stError)
		return 1;
	ASSERT(stream);

	int pos_stream, pos_time, length_time;

	if (!xine_get_pos_length(stream, &pos_stream, &pos_time, &length_time))
	{
		eDebug("xine_get_pos_length failed!");
		return 1;
	}

	eDebug("length: %d ms", length_time);

	pts = length_time * 90;

	return 0;
}
Пример #15
0
int framecatcher::open(const std::string& fileName){

	int errorCode = 0;


	/* ensure resources used previous stream have been released */
	if(stream != NULL)
		close();


	stream = xine_stream_new(xine,NULL,vo_port);

	if(stream == NULL)
		return 0;


	// open stream
	if(!xine_open(stream,fileName.c_str())){
		errorCode= xine_get_error(stream);
		return errorCode;
	}

	// get length of video file stream is attached to
	if(!xine_get_pos_length(stream,0,0,&length)){
		errorCode = xine_get_error(stream);
		return errorCode;
	}

	xine_play(stream,0,0);
	const char* temp_codec=xine_get_meta_info(stream, XINE_META_INFO_VIDEOCODEC);

	if(temp_codec == NULL)
		return 0;

	codec = temp_codec;
	return 1;
}
Пример #16
0
void SjPlayer::DoGetTime(long& totalMs, long& elapsedMs)
{
	if( m_impl->m_currStream )
	{
		totalMs = -1; // if there is a stream, the pos/length may be unknown
		elapsedMs = -1;
		int pos_stream, pos_time_ms, length_time_ms;
		if( xine_get_pos_length(m_impl->m_currStream->GetXineStream(), &pos_stream, &pos_time_ms, &length_time_ms) )
		{
			if( length_time_ms >= 0 ) {
				totalMs = length_time_ms;
			}

			if( pos_time_ms >= 0 ) {
				elapsedMs = pos_time_ms;
			}
		}
	}
	else
	{
		totalMs = 0; // "no stream" has a length of "0"
		elapsedMs = 0;
	}
}
Пример #17
0
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 */
}
Пример #18
0
static double icvGetPropertyAVI_XINE( CvCaptureAVI_XINE* capture, int property_id )
{
#ifndef NDEBUG
    fprintf( stderr, "(DEBUG) icvGetPropertyAVI_XINE ... start\n" );
#endif

    OPENCV_ASSERT ( capture,
                        "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture");
    OPENCV_ASSERT ( capture->stream,
                        "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream");
    OPENCV_ASSERT ( capture->vo_port,
                        "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port");
    OPENCV_ASSERT ( capture->xine,
                        "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->xine");
    OPENCV_ASSERT ( capture->bgr_frame,
                        "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->bgr_frame");

// not needed tnx to asserts...
    // we need a valid capture context and it's stream to seek through
//	if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0

    int pos_t, pos_l, length;
    xine_get_pos_length( capture->stream, &pos_l, &pos_t, &length );
    fprintf( stderr, "ratio on GetProperty(): %i\n", pos_l );

    switch ( property_id )
    {
            /// return actual position in msec
            case CV_CAP_PROP_POS_MSEC:
            if ( !capture->seekable )
            {
                fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_MSEC:\n" );
                fprintf( stderr, "	Stream is NOT seekable, so position info may NOT be valid !!\n" );
            }
            return pos_t;

            /// return actual frame number
            case CV_CAP_PROP_POS_FRAMES:
            /// we insist the capture->frame_number to be remain updated !!!!
            return capture->frame_number;

            /// return actual position ratio in the range [0..1] depending on
            /// the total length of the stream and the actual position
            case CV_CAP_PROP_POS_AVI_RATIO:
            if ( !capture->seekable )
            {
                fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_AVI_RATIO:\n" );
                fprintf( stderr, "	Stream is NOT seekable, so ratio info may NOT be valid !!\n" );
            }
            if ( length == 0 ) break;
            else return pos_l / 65535;


            /// return width of image source
            case CV_CAP_PROP_FRAME_WIDTH:
            return capture->size.width;

            /// return height of image source
            case CV_CAP_PROP_FRAME_HEIGHT:
            return capture->size.height;

            /// return framerate of stream
            case CV_CAP_PROP_FPS:
            if ( !capture->seekable )
            {
                fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_FPS:\n" );
                fprintf( stderr, "	Stream is NOT seekable, so FPS info may NOT be valid !!\n" );
            }
            return capture->frame_rate;

            /// return four-character-code (FOURCC) of source's codec
            case CV_CAP_PROP_FOURCC:
            return ( double ) xine_get_stream_info( capture->stream, XINE_STREAM_INFO_VIDEO_FOURCC );
    }

#ifndef NDEBUG
    fprintf( stderr, "(DEBUG) icvGetPropertyAVI_XINE ... failed!\n" );
#endif

    return 0;
}
Пример #19
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;
}
Пример #20
0
static Epsilon_Image *
epsilon_generate_thumb (Epsilon * e)
{
  int ret = XINE_THUMB_SUCCESS;
  Epsilon_Image *img = NULL;
  unsigned char *buf = NULL;
  int cnt, attempts = 0, length = -1, pos_perc, pos_time, new_perc, new_time,
  req_perc = 500, req_time = 500;
  static int old_length = -1;
  char cfg[PATH_MAX];
  epsilon_xine_param *param;

  param = calloc (1, sizeof (epsilon_xine_param));
  if (!(param->xine = xine_new ()))
    {
      return NULL;
    }
  snprintf (cfg, PATH_MAX, "%s%s", xine_get_homedir (), ".xine/config");
  xine_config_load (param->xine, cfg);
  xine_init (param->xine);

  /* opening xine output ports */
  if (!
      (param->vo_port =
       xine_open_video_driver (param->xine, "none", XINE_VISUAL_TYPE_NONE,
			       (void *) NULL)))
    {
      goto done;
    }

  param->ao_port = xine_open_audio_driver (param->xine, "none", NULL);

  /* open a xine stream connected to these ports */
  if (!
      (param->stream =
       xine_stream_new (param->xine, param->ao_port, param->vo_port)))
    {
      goto done;
    }


  if (!xine_open (param->stream, e->src))
    {
      ret = XINE_THUMB_FAIL;
      goto done;
    }

    if (XINE_THUMBNAILER_DEBUG) printf("Starting xine thumbnail process..\n");

try_get_chance:
  new_perc = -1;
  new_time = req_time;

  if (!xine_play (param->stream, 0, new_time))
    {
      new_time = -1;
      new_perc = req_perc;	/* 0..65535 */
      if (!xine_play (param->stream, new_perc, 0))
	{
	  ret = XINE_THUMB_FAIL;
	  if (XINE_THUMBNAILER_DEBUG) printf("Coudln't play video %s..\n", e->src);
	  goto close_stream;
	}
    }

  /* get position */
  for (cnt = 0; ((cnt < 50) &&
		 (!xine_get_pos_length
		  (param->stream, &pos_perc, &pos_time, &length)
		  || (length == old_length))); cnt++)
    usleep (1000);

  if (length < 0)
    {
      if (XINE_THUMBNAILER_DEBUG) printf("Video is 0 length!..\n");
      ret = XINE_THUMB_FAIL;
      goto close_stream;
    }

  /* wait till position changes */
  for (cnt = 0;
       (cnt < 50) &&
       (!xine_get_pos_length (param->stream, &new_perc, &new_time, &length) ||
	((new_perc == pos_perc) && (new_time == pos_time))); cnt++)
    {
      usleep (1000);
    }

  /* get snapshot */
  int w, h, ratio, format;

  old_length = length;

  /* ask what size a snapshot would be (if we can make one) */
  if (!xine_get_current_frame (param->stream, &w, &h, &ratio, &format, NULL))
    {
      attempts++;
      if (attempts < 10)
	{
	  if (req_time < 10000)
	    req_time += 1000;
	  if (req_perc < 10000)
	    req_perc += 1000;
	  goto try_get_chance;

	}
      else
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Exhausted attempts to thumbnail..\n");
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}
    }
  else if ((w <= 0) || (h <= 0))
    {
      if (XINE_THUMBNAILER_DEBUG) printf("Width/Height of video invalid: %d:%d..\n", w,h);
      ret = XINE_THUMB_FAIL;
      goto close_stream;
    }
  else
    {
      /* know we know the size, get a buffer for the snapshot */
      if (!(buf = malloc (w * h * 2)))
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Couldn't allocate memory for thumbnail buffer..\n");
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}

      /* make a snapshot! */
      if (!xine_get_current_frame
	  (param->stream, &w, &h, &ratio, &format, buf))
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Couldn't retrieve current video frame..\n");
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}

      else if ((w <= 0) || (h <= 0))
	{
	  if (XINE_THUMBNAILER_DEBUG) printf("Width/height of video invalid: %d:%d..\n",w,h);
	  ret = XINE_THUMB_FAIL;
	  goto close_stream;
	}

      if (format == XINE_IMGFMT_YUY2)
	{
	  unsigned char *buf2 = malloc (w * h * 2);
	  unsigned char *tmp = buf;
	  i_yuy2_to_yv12 (buf, buf2, w, h);

	  buf = buf2;
	  free (tmp);

	  format = XINE_IMGFMT_YV12;
	}

      if (format == XINE_IMGFMT_YV12)
	{
	  ret = yv12_to_rgb (e->src, w, h, &buf, &img);

	  if (ret != XINE_THUMB_SUCCESS)
	    {
	      if (img)
		{
		  if (++attempts > 10)
		    goto close_stream;
		  free(img->data);
		  free(img);
		  img = NULL;
		  if (ret == XINE_THUMB_RETRY)
		    {
		      if (buf)
			{
			  free (buf);
			  buf = NULL;
			  if ((req_perc += (attempts * 1000)) > 65535)
			    req_perc = 1000;
			  if ((req_time += (attempts * 2500)) > length)
			    req_time = 3000;
			  goto try_get_chance;
			}

	              if (XINE_THUMBNAILER_DEBUG) printf("Exhausted attempts to thumbnail pos 2..\n");
		      ret = XINE_THUMB_FAIL;
		      goto close_stream;
		    }
		}

	      else
		{
		  if (XINE_THUMBNAILER_DEBUG) printf("Couldn't complete yv12_to_rgb..\n");
		  ret = XINE_THUMB_FAIL;
		  goto close_stream;
		}
	    }
	}

      ret = XINE_THUMB_SUCCESS;

    close_stream:
      if (buf)
	{
	  free (buf);
	  buf = NULL;
	}
      xine_close (param->stream);

    done:
      if (ret != XINE_THUMB_SUCCESS)
	{
	  if (img)
	    {
	      free(img->data);
	      free(img);
	      img = NULL;
	    }
	}

      if (param->stream)
	{
	  xine_dispose (param->stream);
	  param->stream = NULL;
	}
      if (param->ao_port)
	{
	  xine_close_audio_driver (param->xine, param->ao_port);
	  param->ao_port = NULL;
	}
      if (param->vo_port)
	{
	  xine_close_video_driver (param->xine, param->vo_port);
	  param->vo_port = NULL;
	}

      free (param);

      return img;
    }
   return NULL;
}