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 xine_open(stream, mrl.c_str());
18 queue = xine_event_new_queue(stream);
23 engine.add_stream(*this);
26 XineStream::~XineStream()
28 engine.remove_stream(*this);
31 xine_event_dispose_queue(queue);
35 void XineStream::select_audio_channel(int i)
37 if(i>=0 && static_cast<unsigned>(i)>=audio_channels.size())
38 throw out_of_range("XineStream::set_audio_channel");
42 xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (i==OFF ? -2 : i));
45 void XineStream::select_spu_channel(int i)
47 if(i>=0 && static_cast<unsigned>(i)>=spu_channels.size())
48 throw out_of_range("XineStream::set_spu_channel");
52 xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, (i==OFF ? -2 : i));
55 void XineStream::play()
58 xine_play(stream, 0, 0);
59 else if(state==PAUSED)
60 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_NORMAL);
65 void XineStream::seek(const Time::TimeDelta &time)
67 xine_play(stream, 0, time/Time::msec);
70 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
75 void XineStream::pause()
79 xine_set_param(stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
84 void XineStream::stop()
90 void XineStream::set_state(State s)
95 MutexLock lock(mutex);
97 signal_state_changed.emit(state);
100 void XineStream::tick()
102 while(xine_event_t *event = xine_event_get(queue))
104 handle_event(*event);
105 xine_event_free(event);
110 channels_changed = false;
117 void XineStream::update_info()
119 const char *xt = xine_get_meta_info(stream, XINE_META_INFO_TITLE);
120 if((xt && title.compare(xt)) || (!xt && !title.empty()))
122 MutexLock lock(mutex);
123 title = (xt ? xt : string());
124 signal_title_changed.emit(title);
127 int dur_msec, pos_msec;
128 xine_get_pos_length(stream, 0, &pos_msec, &dur_msec);
129 Time::TimeDelta dur = dur_msec*Time::msec;
130 Time::TimeDelta pos = pos_msec*Time::msec;
133 MutexLock lock(mutex);
135 signal_duration_changed.emit(duration);
139 MutexLock lock(mutex);
141 signal_position_changed.emit(position);
144 int audio = xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
145 if(audio==-1 && !audio_channels.empty())
149 if(audio!=current_audio)
151 MutexLock lock(mutex);
152 current_audio = audio;
153 signal_current_audio_channel_changed.emit(current_audio);
156 int spu = xine_get_param(stream, XINE_PARAM_SPU_CHANNEL);
161 MutexLock lock(mutex);
163 signal_current_spu_channel_changed.emit(current_spu);
167 void XineStream::update_channels()
169 MutexLock lock(mutex);
170 char langbuf[XINE_LANG_MAX];
172 unsigned n_audio = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_AUDIO_CHANNEL);
173 audio_channels.resize(n_audio);
174 for(unsigned i=0; i<n_audio; ++i)
176 xine_get_audio_lang(stream, i, langbuf);
177 audio_channels[i].assign(langbuf);
180 unsigned n_spu = xine_get_stream_info(stream, XINE_STREAM_INFO_MAX_SPU_CHANNEL);
181 spu_channels.resize(n_spu);
182 for(unsigned i=0; i<n_spu; ++i)
184 xine_get_spu_lang(stream, i, langbuf);
185 spu_channels[i].assign(langbuf);
188 signal_channels_changed.emit();
191 void XineStream::handle_event(const xine_event_t &event)
195 case XINE_EVENT_UI_PLAYBACK_FINISHED:
197 signal_finished.emit();
199 case XINE_EVENT_UI_CHANNELS_CHANGED:
200 channels_changed = true;
206 void operator<<(LexicalConverter &conv, XineStream::State state)
210 case XineStream::STOPPED: conv.result("STOPPED"); return;
211 case XineStream::PAUSED: conv.result("PAUSED"); return;
212 case XineStream::PLAYING: conv.result("PLAYING"); return;
213 default: conv.result(format("State(%d)", static_cast<int>(state))); return;
217 void operator>>(const LexicalConverter &conv, XineStream::State &state)
219 const string &str = conv.get();
221 state = XineStream::STOPPED;
222 else if(str=="PAUSED")
223 state = XineStream::PAUSED;
224 else if(str=="PLAYING")
225 state = XineStream::PLAYING;
227 throw lexical_error(format("Conversion of '%s' to XineStream::State", str));