XineStream::XineStream(XineEngine &e, const string &mrl):
engine(e),
+ filename(mrl.substr(mrl.rfind('/')+1)),
state(STOPPED),
+ title(filename),
+ video_width(0),
+ video_height(0),
+ framerate(0.0f),
current_audio(0),
current_spu(OFF),
channels_changed(false)
engine.add_stream(*this);
}
+const string &XineStream::get_title() const
+{
+ return title.empty() ? filename : title;
+}
+
XineStream::~XineStream()
{
engine.remove_stream(*this);
xine_dispose(stream);
}
-void XineStream::select_audio_channel(int i)
-{
- if(i>=0 && static_cast<unsigned>(i)>=audio_channels.size())
- throw out_of_range("XineStream::set_audio_channel");
-
- if(i<0)
- i = OFF;
- xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (i==OFF ? -2 : i));
-}
-
-void XineStream::select_spu_channel(int i)
-{
- if(i>=0 && static_cast<unsigned>(i)>=spu_channels.size())
- throw out_of_range("XineStream::set_spu_channel");
-
- if(i<0)
- i = OFF;
- xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, (i==OFF ? -2 : i));
-}
-
void XineStream::play()
{
if(state==STOPPED)
signal_state_changed.emit(state);
}
+void XineStream::select_audio_channel(int i)
+{
+ if(i>=0 && static_cast<unsigned>(i)>=audio_channels.size())
+ throw out_of_range("XineStream::set_audio_channel");
+
+ if(i<0)
+ i = OFF;
+ xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (i==OFF ? -2 : i));
+}
+
+void XineStream::select_spu_channel(int i)
+{
+ if(i>=0 && static_cast<unsigned>(i)>=spu_channels.size())
+ throw out_of_range("XineStream::set_spu_channel");
+
+ if(i<0)
+ i = OFF;
+ xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, (i==OFF ? -2 : i));
+}
+
void XineStream::tick()
{
while(xine_event_t *event = xine_event_get(queue))
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((xt && title.compare(xt)) || (!xt && !title.empty()))
+ if(!equals(title, xt))
{
MutexLock lock(mutex);
title = (xt ? xt : string());
- signal_title_changed.emit(title);
+ 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);
+ }
+
+ float fps = 90000.0f/xine_get_stream_info(stream, XINE_STREAM_INFO_FRAME_DURATION);
+ 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;
audio_channels.resize(n_audio);
for(unsigned i=0; i<n_audio; ++i)
{
- xine_get_audio_lang(stream, i, langbuf);
- audio_channels[i].assign(langbuf);
+ 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)
{
- xine_get_spu_lang(stream, i, langbuf);
- spu_channels[i].assign(langbuf);
+ if(xine_get_spu_lang(stream, i, langbuf))
+ spu_channels[i].assign(langbuf);
+ else
+ spu_channels[i].assign("unknown");
}
signal_channels_changed.emit();