-
Notifications
You must be signed in to change notification settings - Fork 689
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add dialog to display streams' audio details #5547
Changes from 1 commit
da80ea2
fd546b4
ff89e32
82f5f4b
e88725e
e8566b6
a5b2e54
0378036
86c6bec
48cb1d4
1fc2579
d1dde2f
b971377
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#include "streamdiscoverer.h" | ||
|
||
#include <gst/pbutils/pbutils.h> | ||
#include "core/logging.h" | ||
#include "core/signalchecker.h" | ||
|
||
#include <QEventLoop> | ||
|
||
const unsigned int StreamDiscoverer::kDiscoveryTimeoutS = 10; | ||
|
||
StreamDiscoverer::StreamDiscoverer() : QObject(nullptr) { | ||
// Setting up a discoverer: | ||
discoverer_ = gst_discoverer_new(kDiscoveryTimeoutS * GST_SECOND, NULL); | ||
if (discoverer_ == NULL) { | ||
qLog(Error) << "Error creating discoverer" << endl; | ||
return; | ||
} | ||
|
||
// Connecting its signals: | ||
CHECKED_GCONNECT(discoverer_, "discovered", &on_discovered_cb, this); | ||
CHECKED_GCONNECT(discoverer_, "finished", &on_finished_cb, this); | ||
|
||
// Starting the discoverer process: | ||
gst_discoverer_start(discoverer_); | ||
} | ||
|
||
StreamDiscoverer::~StreamDiscoverer() { | ||
gst_discoverer_stop(discoverer_); | ||
g_object_unref(discoverer_); | ||
} | ||
|
||
void StreamDiscoverer::discover(QString url) { | ||
// Adding the request to discover the url given as a parameter: | ||
qLog(Debug) << "Discover" << url; | ||
std::string url_std = url.toStdString(); | ||
const char* url_c = url_std.c_str(); | ||
if (!gst_discoverer_discover_uri_async(discoverer_, url_c)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inline |
||
qLog(Error) << "Failed to start discovering" << url | ||
<< endl; | ||
g_object_unref(discoverer_); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is done in the destructor anyway |
||
return; | ||
} | ||
|
||
// Creating a loop and setting it to run. That way we can wait for signals. | ||
QEventLoop loop; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
loop.connect(this, SIGNAL(DiscoverererFinished()), SLOT(quit())); | ||
loop.exec(); | ||
} | ||
|
||
void StreamDiscoverer::on_discovered_cb(GstDiscoverer* discoverer, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
GstDiscovererInfo* info, GError* err, | ||
gpointer self) { | ||
StreamDiscoverer* instance = reinterpret_cast<StreamDiscoverer*>(self); | ||
|
||
QString discovered_url(gst_discoverer_info_get_uri(info)); | ||
|
||
GstDiscovererResult result = gst_discoverer_info_get_result(info); | ||
if (result != GST_DISCOVERER_OK) { | ||
qLog(Error) << "Discovery failed:" << gstDiscovererErrorMessage(result) << endl; | ||
emit instance->Error(tr("Error discovering %1: %2").arg(discovered_url).arg( | ||
gstDiscovererErrorMessage(result))); | ||
return; | ||
} | ||
|
||
// Get audio streams (we will only care about the first one, which should be the only one). | ||
GList* audio_streams = gst_discoverer_info_get_audio_streams(info); | ||
|
||
if (audio_streams != NULL) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
qLog(Debug) << "Discovery successful" << endl; | ||
// We found a valid audio stream, extracting and saving its info: | ||
GstDiscovererStreamInfo* stream_audio_info = | ||
(GstDiscovererStreamInfo*)g_list_first(audio_streams)->data; | ||
|
||
StreamDetails stream_details; | ||
stream_details.url = discovered_url; | ||
stream_details.bitrate = gst_discoverer_audio_info_get_bitrate( | ||
GST_DISCOVERER_AUDIO_INFO(stream_audio_info)); | ||
stream_details.channels = gst_discoverer_audio_info_get_channels( | ||
GST_DISCOVERER_AUDIO_INFO(stream_audio_info)); | ||
stream_details.depth = gst_discoverer_audio_info_get_depth( | ||
GST_DISCOVERER_AUDIO_INFO(stream_audio_info)); | ||
stream_details.sample_rate = gst_discoverer_audio_info_get_sample_rate( | ||
GST_DISCOVERER_AUDIO_INFO(stream_audio_info)); | ||
|
||
// Human-readable codec name: | ||
GstCaps* stream_caps = | ||
gst_discoverer_stream_info_get_caps(stream_audio_info); | ||
gchar* decoder_description = | ||
gst_pb_utils_get_codec_description(stream_caps); | ||
stream_details.format = (decoder_description == NULL) | ||
? QString(tr("Unknown")) | ||
: QString(decoder_description); | ||
|
||
gst_caps_unref(stream_caps); | ||
g_free(decoder_description); | ||
|
||
emit instance->DataReady(stream_details); | ||
|
||
} else { | ||
emit instance->Error( | ||
tr("Could not detect an audio stream in %1").arg(discovered_url)); | ||
} | ||
|
||
gst_discoverer_stream_info_list_free(audio_streams); | ||
} | ||
|
||
void StreamDiscoverer::on_finished_cb(GstDiscoverer* discoverer, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
gpointer self) { | ||
// The discoverer doesn't have any more urls in its queue. Let the loop know | ||
// it can exit. | ||
StreamDiscoverer* instance = reinterpret_cast<StreamDiscoverer*>(self); | ||
emit instance->DiscoverererFinished(); | ||
} | ||
|
||
QString StreamDiscoverer::gstDiscovererErrorMessage( | ||
GstDiscovererResult result) { | ||
switch (result) { | ||
case (GST_DISCOVERER_URI_INVALID): | ||
return tr("Invalid URL"); | ||
case (GST_DISCOVERER_TIMEOUT): | ||
return tr("Connection timed out"); | ||
case (GST_DISCOVERER_BUSY): | ||
return tr("The discoverer is busy"); | ||
case (GST_DISCOVERER_MISSING_PLUGINS): | ||
return tr("Missing plugins"); | ||
case (GST_DISCOVERER_ERROR): | ||
default: | ||
return tr("Could not get details"); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
#ifndef STREAMDISCOVERER_H | ||
#define STREAMDISCOVERER_H | ||
|
||
#include <gst/pbutils/pbutils.h> | ||
|
||
#include <QMetaType> | ||
#include <QObject> | ||
#include <QString> | ||
|
||
struct StreamDetails { | ||
QString url; | ||
QString format; | ||
unsigned int bitrate; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
unsigned int depth; | ||
unsigned int channels; | ||
unsigned int sample_rate; | ||
}; | ||
Q_DECLARE_METATYPE(StreamDetails) | ||
|
||
class StreamDiscoverer : public QObject { | ||
Q_OBJECT | ||
|
||
public: | ||
StreamDiscoverer(); | ||
~StreamDiscoverer(); | ||
|
||
void discover(QString url); | ||
|
||
signals: | ||
void DiscoverererFinished(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
void DataReady(StreamDetails data); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
void Error(const QString& message); | ||
|
||
private: | ||
GstDiscoverer* discoverer_; | ||
|
||
static const unsigned int kDiscoveryTimeoutS; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. remove |
||
|
||
// GstDiscoverer callbacks: | ||
static void on_discovered_cb(GstDiscoverer* discoverer, | ||
GstDiscovererInfo* info, GError* err, | ||
gpointer instance); | ||
static void on_finished_cb(GstDiscoverer* discoverer, gpointer instance); | ||
|
||
// Helper to return descriptive error messages: | ||
static QString gstDiscovererErrorMessage(GstDiscovererResult result); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
}; | ||
|
||
#endif // STREAMDISCOVERER_H |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow the style guide: https://google.github.io/styleguide/cppguide.html
e.g.
Discover
notdiscover
and `const QString& url