Adding a buffer probe

This commit is contained in:
László Károlyi 2022-01-29 14:57:11 +01:00
parent 887f8a636c
commit 03f7eace83
Signed by: karolyi
GPG Key ID: 2DCAF25E55735BFE
4 changed files with 60 additions and 29 deletions

View File

@ -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

View File

@ -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 =

View File

@ -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"};

View File

@ -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() {