1 #include <msp/strings/format.h>
2 #include "xineengine.h"
3 #include "xinestream.h"
8 XineStream::XineStream(XineEngine &e, const string &mrl):
13 channels_changed(false)
15 stream = xine_stream_new(engine.get_engine(), engine.get_audio_driver(), engine.get_video_driver());
16 queue = xine_event_new_queue(stream);
17 xine_open(stream, mrl.c_str());
22 engine.add_stream(*this);
25 XineStream::~XineStream()
27 engine.remove_stream(*this);
30 xine_event_dispose_queue(queue);
34 void XineStream::select_audio_channel(int i)
36 if(i>=0 && static_cast<unsigned>(i)>=audio_channels.size())
37 throw out_of_range("XineStream::set_audio_channel");
41 xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (i==OFF ? -2 : i));
44 void XineStream::select_spu_channel(int i)
46 if(i>=0 && static_cast<unsigned>(i)>=spu_channels.size())
47 throw out_of_range("XineStream::set_spu_channel");
51 xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, (i==OFF ? -2 : i));
54 void XineStream::play()
57 xine_play(stream, 0, 0);
58 else if(state==PAUSED)
59 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
64 void XineStream::seek(const Time::TimeDelta &time)
66 xine_play(stream, 0, time/Time::msec);
69 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
74 void XineStream::pause()
78 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
83 void XineStream::stop()
89 void XineStream::set_state(State s)
94 MutexLock lock(mutex);
96 signal_state_changed.emit(state);
99 void XineStream::tick()
101 while(xine_event_t *event = xine_event_get(queue))
103 handle_event(*event);
104 xine_event_free(event);
109 channels_changed = false;
116 void XineStream::update_info()
118 const char *xt = xine_get_meta_info(stream, XINE_META_INFO_TITLE);
119 if((xt && title.compare(xt)) || (!xt && !title.empty()))
121 MutexLock lock(mutex);
122 title = (xt ? xt : string());
123 signal_title_changed.emit(title);
126 int dur_msec, pos_msec;
127 xine_get_pos_length(stream, 0, &pos_msec, &dur_msec);
128 Time::TimeDelta dur = dur_msec*Time::msec;
129 Time::TimeDelta pos = pos_msec*Time::msec;
132 MutexLock lock(mutex);
134 signal_duration_changed.emit(duration);
138 MutexLock lock(mutex);
140 signal_position_changed.emit(position);
143 int audio = xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
144 if(audio==-1 && !audio_channels.empty())
148 if(audio!=current_audio)
150 MutexLock lock(mutex);
151 current_audio = audio;
152 signal_current_audio_channel_changed.emit(current_audio);
155 int spu = xine_get_param(stream, XINE_PARAM_SPU_CHANNEL);
160 MutexLock lock(mutex);
162 signal_current_spu_channel_changed.emit(current_spu);
166 void XineStream::update_channels()
168 MutexLock lock(mutex);
169 char langbuf[XINE_LANG_MAX];
171 unsigned n_audio = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
172 audio_channels.resize(n_audio);
173 for(unsigned i=0; i<n_audio; ++i)
175 xine_get_audio_lang(stream, i, langbuf);
176 audio_channels[i].assign(langbuf);
179 unsigned n_spu = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
180 spu_channels.resize(n_spu);
181 for(unsigned i=0; i<n_spu; ++i)
183 xine_get_spu_lang(stream, i, langbuf);
184 spu_channels[i].assign(langbuf);
187 signal_channels_changed.emit();
190 void XineStream::handle_event(const xine_event_t &event)
194 case XINE_EVENT_UI_PLAYBACK_FINISHED:
196 signal_finished.emit();
198 case XINE_EVENT_UI_CHANNELS_CHANGED:
199 channels_changed = true;
205 void operator<<(LexicalConverter &conv, XineStream::State state)
209 case XineStream::STOPPED: conv.result("STOPPED"); return;
210 case XineStream::PAUSED: conv.result("PAUSED"); return;
211 case XineStream::PLAYING: conv.result("PLAYING"); return;
212 default: conv.result(format("State(%d)", static_cast<int>(state))); return;
216 void operator>>(const LexicalConverter &conv, XineStream::State &state)
218 const string &str = conv.get();
220 state = XineStream::STOPPED;
221 else if(str=="PAUSED")
222 state = XineStream::PAUSED;
223 else if(str=="PLAYING")
224 state = XineStream::PLAYING;
226 throw lexical_error(format("Conversion of '%s' to XineStream::State", str));