Use spectrum plugin for moodbar
This commit is contained in:
parent
fa96cdfaea
commit
7e0231cb77
|
@ -22,6 +22,9 @@
|
|||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QByteArray>
|
||||
|
||||
|
@ -61,6 +64,29 @@ void MoodbarBuilder::Init(const int bands, const int rate_hz) {
|
|||
|
||||
}
|
||||
|
||||
void MoodbarBuilder::AddFrame(const GValue *magnitudes, const int size) {
|
||||
|
||||
if (size > barkband_table_.length()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate total magnitudes for different bark bands.
|
||||
double bands[sBarkBandCount]{};
|
||||
for (int i = 0; i < size; ++i) {
|
||||
const GValue *magnitude = gst_value_list_get_value(magnitudes, i);
|
||||
bands[barkband_table_[i]] += g_value_get_float(magnitude);
|
||||
}
|
||||
|
||||
// Now divide the bark bands into thirds and compute their total amplitudes.
|
||||
double rgb[] = { 0, 0, 0 };
|
||||
for (int i = 0; i < sBarkBandCount; ++i) {
|
||||
rgb[(i * 3) / sBarkBandCount] += bands[i] * bands[i];
|
||||
}
|
||||
|
||||
frames_.append(Rgb(sqrt(rgb[0]), sqrt(rgb[1]), sqrt(rgb[2])));
|
||||
|
||||
}
|
||||
|
||||
void MoodbarBuilder::AddFrame(const double *magnitudes, const int size) {
|
||||
|
||||
if (size > barkband_table_.length()) {
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#ifndef MOODBARBUILDER_H
|
||||
#define MOODBARBUILDER_H
|
||||
|
||||
#include <glib-object.h>
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QList>
|
||||
#include <QByteArray>
|
||||
|
@ -31,6 +33,7 @@ class MoodbarBuilder {
|
|||
explicit MoodbarBuilder();
|
||||
|
||||
void Init(const int bands, const int rate_hz);
|
||||
void AddFrame(const GValue *magnitudes, const int size);
|
||||
void AddFrame(const double *magnitudes, const int size);
|
||||
QByteArray Finish(const int width);
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ void MoodbarPipeline::Start() {
|
|||
|
||||
GstElement *decodebin = CreateElement(QStringLiteral("uridecodebin"));
|
||||
convert_element_ = CreateElement(QStringLiteral("audioconvert"));
|
||||
GstElement *spectrum = CreateElement(QStringLiteral("fastspectrum"));
|
||||
GstElement *spectrum = CreateElement(QStringLiteral("spectrum"));
|
||||
GstElement *fakesink = CreateElement(QStringLiteral("fakesink"));
|
||||
|
||||
if (!decodebin || !convert_element_ || !spectrum || !fakesink) {
|
||||
|
@ -118,7 +118,7 @@ void MoodbarPipeline::Start() {
|
|||
return;
|
||||
}
|
||||
|
||||
builder_ = make_unique<MoodbarBuilder>();
|
||||
//builder_ = make_unique<MoodbarBuilder>();
|
||||
|
||||
// Set properties
|
||||
|
||||
|
@ -126,8 +126,16 @@ void MoodbarPipeline::Start() {
|
|||
g_object_set(decodebin, "uri", gst_url.constData(), nullptr);
|
||||
g_object_set(spectrum, "bands", kBands, nullptr);
|
||||
|
||||
GstStrawberryFastSpectrum *fastspectrum = reinterpret_cast<GstStrawberryFastSpectrum*>(spectrum);
|
||||
fastspectrum->output_callback = [this](double *magnitudes, const int size) { builder_->AddFrame(magnitudes, size); };
|
||||
//GstStrawberryFastSpectrum *fastspectrum = reinterpret_cast<GstStrawberryFastSpectrum*>(spectrum);
|
||||
//fastspectrum->output_callback = [this](double *magnitudes, const int size) { builder_->AddFrame(magnitudes, size); };
|
||||
|
||||
{
|
||||
GstPad *pad = gst_element_get_static_pad(fakesink, "src");
|
||||
if (pad) {
|
||||
buffer_probe_cb_id_ = gst_pad_add_probe(pad, GST_PAD_PROBE_TYPE_BUFFER, BufferProbeCallback, this, nullptr);
|
||||
gst_object_unref(pad);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect signals
|
||||
CHECKED_GCONNECT(decodebin, "pad-added", &NewPadCallback, this);
|
||||
|
@ -206,6 +214,20 @@ GstBusSyncReply MoodbarPipeline::BusCallbackSync(GstBus *bus, GstMessage *messag
|
|||
MoodbarPipeline *instance = reinterpret_cast<MoodbarPipeline*>(self);
|
||||
|
||||
switch (GST_MESSAGE_TYPE(message)) {
|
||||
#if 0
|
||||
case GST_MESSAGE_ELEMENT:{
|
||||
const GstStructure *structure = gst_message_get_structure(message);
|
||||
const gchar *name = gst_structure_get_name(structure);
|
||||
if (strcmp(name, "spectrum") == 0) {
|
||||
const GValue *magnitudes = gst_structure_get_value(structure, "magnitude");
|
||||
if (instance->builder_) {
|
||||
instance->builder_->AddFrame(magnitudes, kBands);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case GST_MESSAGE_EOS:
|
||||
instance->Stop(true);
|
||||
break;
|
||||
|
@ -223,6 +245,24 @@ GstBusSyncReply MoodbarPipeline::BusCallbackSync(GstBus *bus, GstMessage *messag
|
|||
|
||||
}
|
||||
|
||||
GstPadProbeReturn MoodbarPipeline::BufferProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer self) {
|
||||
|
||||
Q_UNUSED(pad)
|
||||
|
||||
MoodbarPipeline *instance = reinterpret_cast<MoodbarPipeline*>(self);
|
||||
|
||||
GstBuffer *buffer = gst_pad_probe_info_get_buffer(info);
|
||||
|
||||
GstMapInfo map;
|
||||
gst_buffer_map(buffer, &map, GST_MAP_READ);
|
||||
instance->data_.append(reinterpret_cast<const char*>(map.data), map.size);
|
||||
gst_buffer_unmap(buffer, &map);
|
||||
gst_buffer_unref(buffer);
|
||||
|
||||
return GST_PAD_PROBE_OK;
|
||||
|
||||
}
|
||||
|
||||
void MoodbarPipeline::Stop(const bool success) {
|
||||
|
||||
success_ = success;
|
||||
|
|
|
@ -62,6 +62,7 @@ class MoodbarPipeline : public QObject {
|
|||
|
||||
static void NewPadCallback(GstElement *element, GstPad *pad, gpointer self);
|
||||
static GstBusSyncReply BusCallbackSync(GstBus *bus, GstMessage *message, gpointer self);
|
||||
static GstPadProbeReturn BufferProbeCallback(GstPad *pad, GstPadProbeInfo *info, gpointer self);
|
||||
|
||||
private:
|
||||
QUrl url_;
|
||||
|
@ -73,6 +74,7 @@ class MoodbarPipeline : public QObject {
|
|||
bool success_;
|
||||
bool running_;
|
||||
QByteArray data_;
|
||||
gint buffer_probe_cb_id_;
|
||||
};
|
||||
|
||||
#endif // MOODBARPIPELINE_H
|
||||
|
|
Loading…
Reference in New Issue