]> git.tdb.fi Git - xinema.git/blobdiff - source/xinestream.cpp
Treat zero frame duration as zero fps rather than infinity
[xinema.git] / source / xinestream.cpp
index 1d7433e5e5807eacfe5ae799f3d12fb84c02ec32..416902a3d7b835907ddc39ef0384a2a3369f7c85 100644 (file)
@@ -7,7 +7,12 @@ using namespace Msp;
 
 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)
@@ -22,6 +27,11 @@ XineStream::XineStream(XineEngine &e, const string &mrl):
        engine.add_stream(*this);
 }
 
+const string &XineStream::get_title() const
+{
+       return title.empty() ? filename : title;
+}
+
 XineStream::~XineStream()
 {
        engine.remove_stream(*this);
@@ -31,26 +41,6 @@ XineStream::~XineStream()
        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)
@@ -96,6 +86,26 @@ void XineStream::set_state(State s)
        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))
@@ -113,14 +123,50 @@ void XineStream::tick()
        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);
+       }
+
+       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;
@@ -172,16 +218,20 @@ void XineStream::update_channels()
        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();