Clients are now notified of changes in the selected channels.
throw runtime_error("No stream");
}
+int Client::convert_channel(const string &arg)
+{
+ if(arg=="off")
+ return XineStream::OFF;
+ else
+ return lexical_cast<unsigned>(arg);
+}
+
void Client::process_command(const string &cmd)
{
string::size_type space = cmd.find(' ');
else if(keyword=="stop")
get_stream().stop();
else if(keyword=="select_audio")
- set_audio_channel(args);
+ get_stream().select_audio_channel(convert_channel(args));
else if(keyword=="select_spu")
- set_spu_channel(args);
+ get_stream().select_spu_channel(convert_channel(args));
else
throw runtime_error("Invalid command");
}
else
send_reply("file "+*i);
}
-}
-
-void Client::set_audio_channel(const string &arg)
-{
- XineStream &stream = get_stream();
- if(arg=="off")
- stream.set_audio_off();
- else
- stream.set_audio_channel(lexical_cast<unsigned>(arg));
-}
-void Client::set_spu_channel(const string &arg)
-{
- XineStream &stream = get_stream();
- if(arg=="off")
- stream.set_spu_off();
- else
- stream.set_spu_channel(lexical_cast<unsigned>(arg));
}
void Client::stream_created(XineStream &stream)
stream.signal_duration_changed.connect(sigc::mem_fun(this, &Client::stream_duration_changed));
stream.signal_position_changed.connect(sigc::mem_fun(this, &Client::stream_position_changed));
stream.signal_channels_changed.connect(sigc::mem_fun(this, &Client::stream_channels_changed));
+ stream.signal_current_audio_channel_changed.connect(sigc::mem_fun(this, &Client::stream_audio_channel_changed));
+ stream.signal_current_spu_channel_changed.connect(sigc::mem_fun(this, &Client::stream_spu_channel_changed));
MutexLock lock(stream.get_mutex());
stream_state_changed(stream.get_state());
stream_duration_changed(dur);
stream_channels_changed();
+ stream_audio_channel_changed(stream.get_current_audio_channel());
+ stream_spu_channel_changed(stream.get_current_spu_channel());
}
void Client::stream_destroyed()
send_reply("channels_end");
}
+
+void Client::stream_audio_channel_changed(int chan)
+{
+ if(chan==XineStream::OFF)
+ send_reply("current_audio off");
+ else
+ send_reply(format("current_audio %d", chan));
+}
+
+void Client::stream_spu_channel_changed(int chan)
+{
+ if(chan==XineStream::OFF)
+ send_reply("current_spu off");
+ else
+ send_reply(format("current_spu %d", chan));
+}
void end_of_stream();
XineStream &get_stream() const;
+ int convert_channel(const std::string &);
void process_command(const std::string &);
void send_reply(const std::string &);
void list_directory(const Msp::FS::Path &);
- void set_audio_channel(const std::string &);
- void set_spu_channel(const std::string &);
void stream_created(XineStream &);
void stream_destroyed();
void stream_duration_changed(const Msp::Time::TimeDelta &);
void stream_position_changed(const Msp::Time::TimeDelta &);
void stream_channels_changed();
+ void stream_audio_channel_changed(int);
+ void stream_spu_channel_changed(int);
};
#endif
XineStream::XineStream(XineEngine &e, const string &mrl):
engine(e),
state(STOPPED),
+ current_audio(0),
+ current_spu(OFF),
channels_changed(false)
{
stream = xine_stream_new(engine.get_engine(), engine.get_audio_driver(), engine.get_video_driver());
queue = xine_event_new_queue(stream);
- update_info();
update_channels();
+ update_info();
engine.add_stream(*this);
}
xine_dispose(stream);
}
-void XineStream::set_audio_channel(unsigned i)
+void XineStream::select_audio_channel(int i)
{
- if(i>=audio_channels.size())
+ if(i>=0 && static_cast<unsigned>(i)>=audio_channels.size())
throw out_of_range("XineStream::set_audio_channel");
- xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, i);
-}
-
-void XineStream::set_audio_off()
-{
- xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, -2);
+ if(i<0)
+ i = OFF;
+ xine_set_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL, (i==OFF ? -2 : i));
}
-void XineStream::set_spu_channel(unsigned i)
+void XineStream::select_spu_channel(int i)
{
- if(i>=spu_channels.size())
+ if(i>=0 && static_cast<unsigned>(i)>=spu_channels.size())
throw out_of_range("XineStream::set_spu_channel");
- xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, i);
-}
-
-void XineStream::set_spu_off()
-{
- xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, -2);
+ if(i<0)
+ i = OFF;
+ xine_set_param(stream, XINE_PARAM_SPU_CHANNEL, (i==OFF ? -2 : i));
}
void XineStream::play()
xine_event_free(event);
}
- update_info();
-
if(channels_changed)
{
channels_changed = false;
update_channels();
}
+
+ update_info();
}
void XineStream::update_info()
position = pos;
signal_position_changed.emit(position);
}
+
+ int audio = xine_get_param(stream, XINE_PARAM_AUDIO_CHANNEL_LOGICAL);
+ if(audio==-1 && !audio_channels.empty())
+ audio = 0;
+ else if(audio<0)
+ audio = OFF;
+ if(audio!=current_audio)
+ {
+ MutexLock lock(mutex);
+ current_audio = audio;
+ signal_current_audio_channel_changed.emit(current_audio);
+ }
+
+ int spu = xine_get_param(stream, XINE_PARAM_SPU_CHANNEL);
+ if(spu<0)
+ spu = OFF;
+ if(spu!=current_spu)
+ {
+ MutexLock lock(mutex);
+ current_spu = spu;
+ signal_current_spu_channel_changed.emit(current_spu);
+ }
}
void XineStream::update_channels()
PLAYING
};
+ enum
+ {
+ OFF = -1
+ };
+
sigc::signal<void, State> signal_state_changed;
sigc::signal<void, const std::string &> signal_title_changed;
sigc::signal<void, const Msp::Time::TimeDelta &> signal_duration_changed;
sigc::signal<void, const Msp::Time::TimeDelta &> signal_position_changed;
sigc::signal<void> signal_channels_changed;
+ sigc::signal<void, int> signal_current_audio_channel_changed;
+ sigc::signal<void, int> signal_current_spu_channel_changed;
sigc::signal<void> signal_finished;
private:
Msp::Time::TimeDelta position;
std::vector<std::string> audio_channels;
std::vector<std::string> spu_channels;
+ int current_audio;
+ int current_spu;
bool channels_changed;
public:
const std::string &get_title() const { return title; }
const std::vector<std::string> &get_audio_channels() const { return audio_channels; }
const std::vector<std::string> &get_spu_channels() const { return spu_channels; }
- void set_audio_channel(unsigned);
- void set_audio_off();
- void set_spu_channel(unsigned);
- void set_spu_off();
+ void select_audio_channel(int);
+ void select_spu_channel(int);
+ int get_current_audio_channel() const { return current_audio; }
+ int get_current_spu_channel() const { return current_spu; }
void play();
void seek(const Msp::Time::TimeDelta &);