+
+ if(channels_changed)
+ {
+ channels_changed = false;
+ update_channels();
+ }
+
+ update_info();
+}
+
+bool XineStream::equals(const string &s1, const char *s2)
+{
+ if(!s2)
+ return s1.empty();
+ return !s1.compare(s2);
+}
+
+void XineStream::update_info()
+{
+ const char *xt = xine_get_meta_info(stream, XINE_META_INFO_TITLE);
+ if(!equals(title, xt))
+ {
+ MutexLock lock(mutex);
+ title = (xt ? xt : string());
+ signal_title_changed.emit(get_title());
+ }
+
+ unsigned w = xine_get_stream_info(stream, XINE_STREAM_INFO_VIDEO_WIDTH);
+ unsigned h = xine_get_stream_info(stream, XINE_STREAM_INFO_VIDEO_HEIGHT);
+ if(w!=video_width || h!=video_height)
+ {
+ MutexLock lock(mutex);
+ video_width = w;
+ video_height = h;
+ signal_video_size_changed.emit(video_width, video_height);
+ }
+
+ unsigned frame_dur = xine_get_stream_info(stream, XINE_STREAM_INFO_FRAME_DURATION);
+ float fps = (frame_dur ? 90000.0f/frame_dur : 0.0f);
+ if(fps!=framerate)
+ {
+ MutexLock lock(mutex);
+ framerate = fps;
+ signal_framerate_changed.emit(framerate);
+ }
+
+ const char *xvc = xine_get_meta_info(stream, XINE_META_INFO_VIDEOCODEC);
+ const char *xac = xine_get_meta_info(stream, XINE_META_INFO_AUDIOCODEC);
+ if(!equals(video_codec, xvc) || !equals(audio_codec, xac))
+ {
+ MutexLock lock(mutex);
+ video_codec = (xvc ? xvc : string());
+ audio_codec = (xac ? xac : string());
+ signal_codecs_changed.emit(video_codec, audio_codec);
+ }
+
+ int dur_msec, pos_msec;
+ xine_get_pos_length(stream, 0, &pos_msec, &dur_msec);
+ Time::TimeDelta dur = dur_msec*Time::msec;
+ Time::TimeDelta pos = pos_msec*Time::msec;
+ if(dur!=duration)
+ {
+ MutexLock lock(mutex);
+ duration = dur;
+ signal_duration_changed.emit(duration);
+ }
+ if(pos!=position)
+ {
+ MutexLock lock(mutex);
+ position = pos;
+ signal_position_changed.emit(position);
+ }
+
+ int audio = xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
+ if(audio==-1 && !audio_channels.empty())
+ audio = 0;
+ else if(audio<0)
+ audio = OFF;
+ if(audio!=current_audio)
+ {
+ MutexLock lock(mutex);
+ current_audio = audio;
+ signal_current_audio_channel_changed.emit(current_audio);
+ }
+
+ int spu = xine_get_param(stream, XINE_PARAM_SPU_CHANNEL);
+ if(spu<0)
+ spu = OFF;
+ if(spu!=current_spu)
+ {
+ MutexLock lock(mutex);
+ current_spu = spu;
+ signal_current_spu_channel_changed.emit(current_spu);
+ }
+}
+
+void XineStream::update_channels()
+{
+ MutexLock lock(mutex);
+ char langbuf[XINE_LANG_MAX];
+
+ unsigned n_audio = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
+ audio_channels.resize(n_audio);
+ for(unsigned i=0; i<n_audio; ++i)
+ {
+ if(xine_get_audio_lang(stream, i, langbuf))
+ audio_channels[i].assign(langbuf);
+ else
+ audio_channels[i].assign("unknown");
+ }
+
+ unsigned n_spu = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
+ spu_channels.resize(n_spu);
+ for(unsigned i=0; i<n_spu; ++i)
+ {
+ if(xine_get_spu_lang(stream, i, langbuf))
+ spu_channels[i].assign(langbuf);
+ else
+ spu_channels[i].assign("unknown");
+ }
+
+ signal_channels_changed.emit();