1 #include <msp/strings/format.h>
2 #include "xineengine.h"
3 #include "xinestream.h"
8 XineStream::XineStream(XineEngine &e, const string &mrl):
11 channels_changed(false)
13 stream = xine_stream_new(engine.get_engine(), engine.get_audio_driver(), engine.get_video_driver());
14 xine_open(stream, mrl.c_str());
16 queue = xine_event_new_queue(stream);
21 engine.add_stream(*this);
24 XineStream::~XineStream()
26 engine.remove_stream(*this);
29 xine_event_dispose_queue(queue);
33 void XineStream::set_audio_channel(unsigned i)
35 if(i>=audio_channels.size())
36 throw out_of_range("XineStream::set_audio_channel");
38 xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, i);
41 void XineStream::set_audio_off()
43 xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -2);
46 void XineStream::set_spu_channel(unsigned i)
48 if(i>=spu_channels.size())
49 throw out_of_range("XineStream::set_spu_channel");
51 xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, i);
54 void XineStream::set_spu_off()
56 xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, -2);
59 void XineStream::play()
62 xine_play(stream, 0, 0);
63 else if(state==PAUSED)
64 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
69 void XineStream::seek(const Time::TimeDelta &time)
71 xine_play(stream, 0, time/Time::msec);
74 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
79 void XineStream::pause()
83 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
88 void XineStream::stop()
94 void XineStream::set_state(State s)
99 MutexLock lock(mutex);
101 signal_state_changed.emit(state);
104 void XineStream::tick()
106 while(xine_event_t *event = xine_event_get(queue))
108 handle_event(*event);
109 xine_event_free(event);
116 channels_changed = false;
121 void XineStream::update_info()
123 const char *xt = xine_get_meta_info(stream, XINE_META_INFO_TITLE);
124 if((xt && title.compare(xt)) || (!xt && !title.empty()))
126 MutexLock lock(mutex);
127 title = (xt ? xt : string());
128 signal_title_changed.emit(title);
131 int dur_msec, pos_msec;
132 xine_get_pos_length(stream, 0, &pos_msec, &dur_msec);
133 Time::TimeDelta dur = dur_msec*Time::msec;
134 Time::TimeDelta pos = pos_msec*Time::msec;
137 MutexLock lock(mutex);
139 signal_duration_changed.emit(duration);
143 MutexLock lock(mutex);
145 signal_position_changed.emit(position);
149 void XineStream::update_channels()
151 MutexLock lock(mutex);
152 char langbuf[XINE_LANG_MAX];
154 unsigned n_audio = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
155 audio_channels.resize(n_audio);
156 for(unsigned i=0; i<n_audio; ++i)
158 xine_get_audio_lang(stream, i, langbuf);
159 audio_channels[i].assign(langbuf);
162 unsigned n_spu = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
163 spu_channels.resize(n_spu);
164 for(unsigned i=0; i<n_spu; ++i)
166 xine_get_spu_lang(stream, i, langbuf);
167 spu_channels[i].assign(langbuf);
170 signal_channels_changed.emit();
173 void XineStream::handle_event(const xine_event_t &event)
177 case XINE_EVENT_UI_PLAYBACK_FINISHED:
179 signal_finished.emit();
181 case XINE_EVENT_UI_CHANNELS_CHANGED:
182 channels_changed = true;
188 void operator<<(LexicalConverter &conv, XineStream::State state)
192 case XineStream::STOPPED: conv.result("STOPPED"); return;
193 case XineStream::PAUSED: conv.result("PAUSED"); return;
194 case XineStream::PLAYING: conv.result("PLAYING"); return;
195 default: conv.result(format("State(%d)", static_cast<int>(state))); return;
199 void operator>>(const LexicalConverter &conv, XineStream::State &state)
201 const string &str = conv.get();
203 state = XineStream::STOPPED;
204 else if(str=="PAUSED")
205 state = XineStream::PAUSED;
206 else if(str=="PLAYING")
207 state = XineStream::PLAYING;
209 throw lexical_error(format("Conversion of '%s' to XineStream::State", str));