Adding a buffer probe
This commit is contained in:
parent
887f8a636c
commit
03f7eace83
|
@ -1,7 +1,7 @@
|
|||
playlist:
|
||||
# path: ./CMakeLists.txt
|
||||
# path: playlist.txt
|
||||
path: playlist2.txt
|
||||
path: playlist.txt
|
||||
# path: playlist2.txt
|
||||
# path: /home/karolyi/Music/epic-allchill.m3u
|
||||
path_reload_when_touched: .
|
||||
icecast_server:
|
||||
|
@ -9,7 +9,6 @@ icecast_server:
|
|||
port: 8000
|
||||
username: source
|
||||
password: testpassword
|
||||
tls: false
|
||||
stream:
|
||||
mountpoint: test-mount
|
||||
bitrate: 192
|
||||
|
|
|
@ -65,10 +65,6 @@ inline void check_structure() {
|
|||
throw IceGStreamer::Exceptions::ConfigOptionMissingException(
|
||||
"icecast_server.address");
|
||||
}
|
||||
if (!yaml_config["icecast_server"]["tls"].IsScalar()) {
|
||||
throw IceGStreamer::Exceptions::ConfigOptionMissingException(
|
||||
"icecast_server.tls");
|
||||
}
|
||||
if (!yaml_config["icecast_server"]["port"].IsScalar()) {
|
||||
throw IceGStreamer::Exceptions::ConfigOptionMissingException(
|
||||
"icecast_server.port");
|
||||
|
@ -128,7 +124,6 @@ inline void fill_contents(_config &config) {
|
|||
// icecast_server section
|
||||
config.icecast_server.address =
|
||||
yaml_config["icecast_server"]["address"].as<std::string>();
|
||||
config.icecast_server.tls = yaml_config["icecast_server"]["tls"].as<bool>();
|
||||
config.icecast_server.port =
|
||||
yaml_config["icecast_server"]["port"].as<uint16_t>();
|
||||
config.icecast_server.username =
|
||||
|
|
|
@ -11,7 +11,6 @@ struct _config_playlist {
|
|||
|
||||
struct _config_icecastserver {
|
||||
std::string address{"127.0.0.1"};
|
||||
bool tls{false};
|
||||
uint16_t port{8000};
|
||||
std::string username{"source"};
|
||||
std::string password{"password"};
|
||||
|
|
|
@ -83,6 +83,7 @@ private:
|
|||
GMainLoop *main_loop;
|
||||
const char *decodebin_name_{"icegstreamer-decodebin"};
|
||||
const char *MSG_STREAMTITLE_CHANGE_{"icegstreamer-msg-streamtitle-change"};
|
||||
const char *MSG_FIRST_BUFFER_SENT_{"icegstreamer-first-buffer-sent"};
|
||||
const char *MSG_CHG_TO_NEXT_TRACK_{"icegstreamer-msg-next-track-please"};
|
||||
typedef enum {
|
||||
INT_STATUS_UNKNOWN_FILETYPE = std::uint16_t(1 << 0),
|
||||
|
@ -91,9 +92,11 @@ private:
|
|||
std::uint16_t internal_status_{0};
|
||||
std::string current_title{""};
|
||||
static StreamerInternals *my_instance;
|
||||
Config::_config &config;
|
||||
gulong id_srcpad_probe_event{0};
|
||||
gulong id_srcpad_probe_firstbuffer{0};
|
||||
|
||||
public:
|
||||
Config::_config &config;
|
||||
StreamerInternals(Config::_config &config)
|
||||
: config(config), playlist_handler(config.playlist) {}
|
||||
|
||||
|
@ -106,18 +109,29 @@ public:
|
|||
gst_bus_post(instance.bus, msg);
|
||||
}
|
||||
|
||||
inline void set_current_title_from_taglist(const GstTagList *tag_list) {
|
||||
inline void
|
||||
set_current_title_from_taglist(GstPad *pad, const GstTagList *tag_list) {
|
||||
if (!tag_list)
|
||||
return;
|
||||
gchar *title{nullptr}, *artist{nullptr};
|
||||
if (gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &title) &&
|
||||
gst_tag_list_get_string(tag_list, GST_TAG_ARTIST, &artist)) {
|
||||
// std::cout << GST_TAG_ARTIST << ": " << (artist ? artist : "unknown ")
|
||||
// << std::endl;
|
||||
// std::cout << GST_TAG_TITLE << ": " << (title ? title : "unknown ")
|
||||
// << std::endl;
|
||||
const std::string new_title =
|
||||
std::move(std::string(artist) + " - " + std::string(title));
|
||||
gst_tag_list_get_string(tag_list, GST_TAG_TITLE, &title);
|
||||
gst_tag_list_get_string(tag_list, GST_TAG_ARTIST, &artist);
|
||||
std::string new_title{""};
|
||||
if (artist) {
|
||||
new_title += std::string(artist);
|
||||
if (title)
|
||||
new_title += " - ";
|
||||
}
|
||||
if (title)
|
||||
new_title += std::string(title);
|
||||
if (!new_title.empty()) {
|
||||
if (id_srcpad_probe_event) {
|
||||
// Deregister probe for events
|
||||
std::cout << "DEREGISTERING PAD PROBE WITH ID: "
|
||||
<< id_srcpad_probe_event << std::endl;
|
||||
gst_pad_remove_probe(pad, id_srcpad_probe_event);
|
||||
id_srcpad_probe_event = 0;
|
||||
}
|
||||
send_busmsg_update_title(new_title);
|
||||
}
|
||||
g_free(artist);
|
||||
|
@ -134,18 +148,29 @@ public:
|
|||
return true;
|
||||
GstTagList *tag_list{nullptr};
|
||||
gst_event_parse_tag(*event, &tag_list);
|
||||
instance.set_current_title_from_taglist(tag_list);
|
||||
instance.set_current_title_from_taglist(pad, tag_list);
|
||||
// Stop further iteration when a tag event is found
|
||||
return false;
|
||||
}
|
||||
|
||||
inline static GstPadProbeReturn srcpad_probe_callback(
|
||||
inline static GstPadProbeReturn srcpad_probecallback_event(
|
||||
GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
|
||||
// std::cout << "pad_probe_callback called" << std::endl;
|
||||
std::cout << "srcpad_probecallback_event called" << std::endl;
|
||||
gst_pad_sticky_events_foreach(pad, look_for_tag_event, user_data);
|
||||
return GST_PAD_PROBE_OK;
|
||||
}
|
||||
|
||||
inline static GstPadProbeReturn srcpad_probecallback_firstbuffer(
|
||||
GstPad *pad, GstPadProbeInfo *info, gpointer user_data) {
|
||||
std::cout << "srcpad_probecallback_firstbuffer called" << std::endl;
|
||||
StreamerInternals &instance = *static_cast<StreamerInternals *>(user_data);
|
||||
GstStructure *gst_struct =
|
||||
gst_structure_new_empty(instance.MSG_FIRST_BUFFER_SENT_);
|
||||
GstMessage *msg = gst_message_new_application(nullptr, gst_struct);
|
||||
gst_bus_post(instance.bus, msg);
|
||||
return GST_PAD_PROBE_REMOVE;
|
||||
}
|
||||
|
||||
inline bool is_pad_linkable(GstPad &pad) const {
|
||||
GstCaps *caps = gst_pad_get_current_caps(&pad);
|
||||
if (caps == nullptr)
|
||||
|
@ -163,8 +188,7 @@ public:
|
|||
}
|
||||
|
||||
static void cb_decodebin_pad_added(
|
||||
const GstElement &object, GstPad *src_pad,
|
||||
const StreamerInternals &instance) {
|
||||
const GstElement &object, GstPad *src_pad, StreamerInternals &instance) {
|
||||
// std::cout << "cb_decodebin_pad_added: " << GST_OBJECT_NAME(src_pad)
|
||||
// << std::endl;
|
||||
if (gst_pad_is_linked(src_pad) || !instance.is_pad_linkable(*src_pad))
|
||||
|
@ -173,12 +197,19 @@ public:
|
|||
gst_element_get_static_pad(instance.convert, "sink");
|
||||
const GstPadLinkReturn link_return =
|
||||
gst_pad_link(src_pad, convert_pad_sink_);
|
||||
if (link_return == GST_PAD_LINK_OK)
|
||||
gst_pad_add_probe(
|
||||
if (link_return == GST_PAD_LINK_OK) {
|
||||
instance.id_srcpad_probe_event = gst_pad_add_probe(
|
||||
src_pad,
|
||||
static_cast<GstPadProbeType>(
|
||||
GST_PAD_PROBE_TYPE_EVENT_UPSTREAM | GST_PAD_PROBE_TYPE_PUSH),
|
||||
instance.srcpad_probe_callback, (void *)&instance, nullptr);
|
||||
instance.srcpad_probecallback_event, (void *)&instance, nullptr);
|
||||
instance.id_srcpad_probe_firstbuffer = gst_pad_add_probe(
|
||||
src_pad,
|
||||
static_cast<GstPadProbeType>(
|
||||
GST_PAD_PROBE_TYPE_BUFFER | GST_PAD_PROBE_TYPE_EVENT_DOWNSTREAM),
|
||||
instance.srcpad_probecallback_firstbuffer, (void *)&instance,
|
||||
nullptr);
|
||||
}
|
||||
// std::cout << "cb_decodebin_pad_added->link_return: " << link_return
|
||||
// << std::endl;
|
||||
gst_object_unref(convert_pad_sink_);
|
||||
|
@ -255,6 +286,7 @@ public:
|
|||
change_streamtitle("");
|
||||
GstStateChangeReturn ret;
|
||||
ret = gst_element_set_state(pipeline, GST_STATE_NULL);
|
||||
id_srcpad_probe_event = 0;
|
||||
playlist_handler.load_next_track();
|
||||
g_object_set(
|
||||
filesrc, "location", playlist_handler.current_track.c_str(), nullptr);
|
||||
|
@ -274,13 +306,17 @@ public:
|
|||
gst_bus_post(bus, msg);
|
||||
}
|
||||
|
||||
void change_streamtitle(const std::string &title) {
|
||||
std::cout << "change_streamtitle: " << title << std::endl;
|
||||
inline void change_streamtitle(const std::string &title) {
|
||||
if (current_title == title)
|
||||
return;
|
||||
std::cout << "change_streamtitle: " << title << std::endl;
|
||||
current_title = std::move(title);
|
||||
}
|
||||
|
||||
inline void check_if_streamtitle_changed() {
|
||||
std::cout << "check_if_streamtitle_changed" << std::endl;
|
||||
}
|
||||
|
||||
void process_busmsg_app(const GstStructure &msg_struct) {
|
||||
const std::string signal_name(
|
||||
std::move(gst_structure_get_name(&msg_struct)));
|
||||
|
@ -291,6 +327,8 @@ public:
|
|||
change_streamtitle(new_title);
|
||||
} else if (signal_name == MSG_CHG_TO_NEXT_TRACK_)
|
||||
change_to_next_track();
|
||||
else if (signal_name == MSG_FIRST_BUFFER_SENT_)
|
||||
check_if_streamtitle_changed();
|
||||
}
|
||||
|
||||
void process_buserror_unknown_type() {
|
||||
|
|
Loading…
Reference in New Issue