Fixes to xine engine
This commit is contained in:
parent
505c1feb42
commit
fc66e2e2c7
@ -42,7 +42,7 @@ Engine::Base::Base()
|
|||||||
end_nanosec_(0),
|
end_nanosec_(0),
|
||||||
scope_(kScopeSize),
|
scope_(kScopeSize),
|
||||||
output_(""),
|
output_(""),
|
||||||
device_(QVariant("")),
|
device_(QVariant()),
|
||||||
rg_enabled_(false),
|
rg_enabled_(false),
|
||||||
rg_mode_(0),
|
rg_mode_(0),
|
||||||
rg_preamp_(0),
|
rg_preamp_(0),
|
||||||
|
@ -63,7 +63,7 @@ GstEnginePipeline::GstEnginePipeline(GstEngine *engine)
|
|||||||
id_(sId++),
|
id_(sId++),
|
||||||
valid_(false),
|
valid_(false),
|
||||||
output_(""),
|
output_(""),
|
||||||
device_(""),
|
device_(QVariant()),
|
||||||
eq_enabled_(false),
|
eq_enabled_(false),
|
||||||
eq_preamp_(0),
|
eq_preamp_(0),
|
||||||
stereo_balance_(0.0f),
|
stereo_balance_(0.0f),
|
||||||
|
@ -357,6 +357,7 @@ EngineBase::PluginDetailsList VLCEngine::GetPluginList() const {
|
|||||||
details.name = QString::fromUtf8(audio_output->psz_name);
|
details.name = QString::fromUtf8(audio_output->psz_name);
|
||||||
details.description = QString::fromUtf8(audio_output->psz_description);
|
details.description = QString::fromUtf8(audio_output->psz_description);
|
||||||
ret << details;
|
ret << details;
|
||||||
|
//GetDevicesList(audio_output->psz_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
libvlc_audio_output_list_release(audio_output_list);
|
libvlc_audio_output_list_release(audio_output_list);
|
||||||
|
@ -201,7 +201,8 @@ bool XineEngine::Load(const QUrl &url, Engine::TrackChangeFlags change, bool for
|
|||||||
|
|
||||||
xine_close(stream_);
|
xine_close(stream_);
|
||||||
|
|
||||||
int result = xine_open(stream_, url.path().toUtf8());
|
//int result = xine_open(stream_, url.path().toUtf8());
|
||||||
|
int result = xine_open(stream_, url.toString().toUtf8());
|
||||||
if (result) {
|
if (result) {
|
||||||
|
|
||||||
#ifndef XINE_SAFE_MODE
|
#ifndef XINE_SAFE_MODE
|
||||||
@ -370,7 +371,7 @@ EngineBase::OutputDetailsList XineEngine::GetOutputsList() const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool XineEngine::CustomDeviceSupport(const QString &name) {
|
bool XineEngine::CustomDeviceSupport(const QString &name) {
|
||||||
return (name == DefaultOutput() ? false : true);
|
return (name == "alsa" || name == "oss" || name == "jack" || name == "pulseaudio");
|
||||||
}
|
}
|
||||||
|
|
||||||
void XineEngine::ReloadSettings() {
|
void XineEngine::ReloadSettings() {
|
||||||
|
@ -2,17 +2,14 @@
|
|||||||
Copyright: See COPYING file that comes with this distribution
|
Copyright: See COPYING file that comes with this distribution
|
||||||
|
|
||||||
This has to be a c file or for some reason it won't link! (GCC 3.4.1)
|
This has to be a c file or for some reason it won't link! (GCC 3.4.1)
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* gcc doesn't like inline for me */
|
|
||||||
#define inline
|
|
||||||
/* need access to port_ticket */
|
/* need access to port_ticket */
|
||||||
#define XINE_ENGINE_INTERNAL
|
#define XINE_ENGINE_INTERNAL
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
#include "xinescope.h"
|
#include "xinescope.h"
|
||||||
#include <xine/post.h>
|
#include <xine/post.h>
|
||||||
#include <xine/xine_internal.h>
|
#include <xine/xine_internal.h>
|
||||||
@ -20,11 +17,11 @@
|
|||||||
typedef struct scope_plugin_s scope_plugin_t;
|
typedef struct scope_plugin_s scope_plugin_t;
|
||||||
|
|
||||||
struct scope_plugin_s {
|
struct scope_plugin_s {
|
||||||
post_plugin_t post;
|
post_plugin_t post;
|
||||||
|
|
||||||
metronom_t metronom;
|
metronom_t metronom;
|
||||||
int channels;
|
int channels;
|
||||||
MyNode *list;
|
MyNode *list;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
@ -33,91 +30,92 @@ struct scope_plugin_s {
|
|||||||
|
|
||||||
static int scope_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) {
|
static int scope_port_open(xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode) {
|
||||||
|
|
||||||
#define port ((post_audio_port_t*)port_gen)
|
#define port ((post_audio_port_t*)port_gen)
|
||||||
#define this ((scope_plugin_t*)((post_audio_port_t*)port_gen)->post)
|
#define this ((scope_plugin_t*)((post_audio_port_t*)port_gen)->post)
|
||||||
|
|
||||||
_x_post_rewire((post_plugin_t*)port->post);
|
_x_post_rewire((post_plugin_t*)port->post);
|
||||||
_x_post_inc_usage(port);
|
_x_post_inc_usage(port);
|
||||||
|
|
||||||
port->stream = stream;
|
port->stream = stream;
|
||||||
port->bits = bits;
|
port->bits = bits;
|
||||||
port->rate = rate;
|
port->rate = rate;
|
||||||
port->mode = mode;
|
port->mode = mode;
|
||||||
|
|
||||||
this->channels = _x_ao_mode2channels(mode);
|
this->channels = _x_ao_mode2channels(mode);
|
||||||
|
|
||||||
return port->original_port->open(port->original_port, stream, bits, rate, mode);
|
return port->original_port->open(port->original_port, stream, bits, rate, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scope_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream) {
|
static void scope_port_close(xine_audio_port_t *port_gen, xine_stream_t *stream) {
|
||||||
|
|
||||||
MyNode *node;
|
MyNode *node;
|
||||||
|
|
||||||
/* ensure the buffers are deleted during the next XineEngine::timerEvent() */
|
/* ensure the buffers are deleted during the next XineEngine::timerEvent() */
|
||||||
for(node = this->list->next; node != this->list; node = node->next)
|
for(node = this->list->next; node != this->list; node = node->next)
|
||||||
node->vpts = node->vpts_end = -1;
|
node->vpts = node->vpts_end = -1;
|
||||||
|
|
||||||
port->stream = NULL;
|
port->stream = NULL;
|
||||||
port->original_port->close(port->original_port, stream);
|
port->original_port->close(port->original_port, stream);
|
||||||
|
|
||||||
_x_post_dec_usage(port);
|
_x_post_dec_usage(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scope_port_put_buffer(xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) {
|
static void scope_port_put_buffer(xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream) {
|
||||||
/* FIXME With 8-bit samples the scope won't work correctly. For a special 8-bit code path, the sample size could be checked like this: if(port->bits == 8) */
|
/* FIXME With 8-bit samples the scope won't work correctly. For a special 8-bit code path, the sample size could be checked like this: if(port->bits == 8) */
|
||||||
|
|
||||||
const int num_samples = buf->num_frames * this->channels;
|
const int num_samples = buf->num_frames * this->channels;
|
||||||
metronom_t *myMetronom = &this->metronom;
|
metronom_t *myMetronom = &this->metronom;
|
||||||
MyNode *new_node;
|
MyNode *new_node;
|
||||||
|
|
||||||
/* I keep my own metronom because xine wouldn't for some reason */
|
/* I keep my own metronom because xine wouldn't for some reason */
|
||||||
memcpy(&this->metronom, stream->metronom, sizeof(metronom_t));
|
memcpy(&this->metronom, stream->metronom, sizeof(metronom_t));
|
||||||
|
|
||||||
new_node = malloc(sizeof(MyNode));
|
new_node = (MyNode *) malloc(sizeof(MyNode));
|
||||||
new_node->vpts = myMetronom->got_audio_samples(myMetronom, buf->vpts, buf->num_frames);
|
new_node->vpts = myMetronom->got_audio_samples(myMetronom, buf->vpts, buf->num_frames);
|
||||||
new_node->num_frames = buf->num_frames;
|
new_node->num_frames = buf->num_frames;
|
||||||
new_node->mem = malloc(num_samples * 2);
|
new_node->mem = (int16_t *) malloc(num_samples * 2);
|
||||||
memcpy(new_node->mem, buf->mem, num_samples * 2);
|
memcpy(new_node->mem, buf->mem, num_samples * 2);
|
||||||
|
|
||||||
{
|
{
|
||||||
int64_t
|
int64_t
|
||||||
K = myMetronom->pts_per_smpls; /*smpls = 1<<16 samples*/
|
K = myMetronom->pts_per_smpls; /*smpls = 1<<16 samples*/
|
||||||
K *= num_samples;
|
K *= num_samples;
|
||||||
K /= (1<<16);
|
K /= (1<<16);
|
||||||
K += new_node->vpts;
|
K += new_node->vpts;
|
||||||
|
|
||||||
new_node->vpts_end = K;
|
new_node->vpts_end = K;
|
||||||
}
|
}
|
||||||
|
|
||||||
port->original_port->put_buffer(port->original_port, buf, stream);
|
port->original_port->put_buffer(port->original_port, buf, stream);
|
||||||
|
|
||||||
/* finally we should append the current buffer to the list
|
/* Finally we should append the current buffer to the list
|
||||||
* this is thread-safe due to the way we handle the list in the GUI thread */
|
* This is thread-safe due to the way we handle the list in the GUI thread */
|
||||||
new_node->next = this->list->next;
|
new_node->next = this->list->next;
|
||||||
this->list->next = new_node;
|
this->list->next = new_node;
|
||||||
|
|
||||||
#undef port
|
#undef port
|
||||||
#undef this
|
#undef this
|
||||||
}
|
}
|
||||||
|
|
||||||
static void scope_dispose(post_plugin_t *this) {
|
static void scope_dispose(post_plugin_t *post) {
|
||||||
MyNode *list = ((scope_plugin_t*)this)->list;
|
|
||||||
MyNode *prev;
|
|
||||||
MyNode *node = list;
|
|
||||||
|
|
||||||
/* Free all elements of the list (a ring buffer) */
|
MyNode *list = ((scope_plugin_t*)post)->list;
|
||||||
do {
|
MyNode *prev;
|
||||||
prev = node->next;
|
MyNode *node = list;
|
||||||
|
|
||||||
free(node->mem);
|
/* Free all elements of the list (a ring buffer) */
|
||||||
free(node);
|
do {
|
||||||
|
prev = node->next;
|
||||||
|
|
||||||
node = prev;
|
free(node->mem);
|
||||||
}
|
free(node);
|
||||||
while(node != list);
|
|
||||||
|
node = prev;
|
||||||
|
}
|
||||||
|
while(node != list);
|
||||||
|
|
||||||
|
|
||||||
free(this);
|
free(post);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -125,49 +123,49 @@ static void scope_dispose(post_plugin_t *this) {
|
|||||||
* plugin init function *
|
* plugin init function *
|
||||||
************************/
|
************************/
|
||||||
|
|
||||||
xine_post_t* scope_plugin_new(xine_t *xine, xine_audio_port_t *audio_target) {
|
xine_post_t *scope_plugin_new(xine_t *xine, xine_audio_port_t *audio_target) {
|
||||||
|
|
||||||
scope_plugin_t *scope_plugin = calloc(1, sizeof(scope_plugin_t));
|
scope_plugin_t *scope_plugin = (scope_plugin_t *) calloc(1, sizeof(scope_plugin_t));
|
||||||
post_plugin_t *post_plugin = (post_plugin_t*)scope_plugin;
|
post_plugin_t *post_plugin = (post_plugin_t *)scope_plugin;
|
||||||
|
|
||||||
{
|
{
|
||||||
post_in_t *input;
|
post_in_t *input;
|
||||||
post_out_t *output;
|
post_out_t *output;
|
||||||
post_audio_port_t *port;
|
post_audio_port_t *port;
|
||||||
|
|
||||||
_x_post_init(post_plugin, 1, 0);
|
_x_post_init(post_plugin, 1, 0);
|
||||||
|
|
||||||
port = _x_post_intercept_audio_port(post_plugin, audio_target, &input, &output);
|
port = _x_post_intercept_audio_port(post_plugin, audio_target, &input, &output);
|
||||||
port->new_port.open = scope_port_open;
|
port->new_port.open = scope_port_open;
|
||||||
port->new_port.close = scope_port_close;
|
port->new_port.close = scope_port_close;
|
||||||
port->new_port.put_buffer = scope_port_put_buffer;
|
port->new_port.put_buffer = scope_port_put_buffer;
|
||||||
|
|
||||||
post_plugin->xine_post.audio_input[0] = &port->new_port;
|
post_plugin->xine_post.audio_input[0] = &port->new_port;
|
||||||
post_plugin->xine_post.type = PLUGIN_POST;
|
post_plugin->xine_post.type = PLUGIN_POST;
|
||||||
|
|
||||||
post_plugin->dispose = scope_dispose;
|
post_plugin->dispose = scope_dispose;
|
||||||
}
|
}
|
||||||
|
|
||||||
// code is straight from xine_init_post() can't use that function as it only dlopens the plugins and our plugin is statically linked in
|
// code is straight from xine_init_post() can't use that function as it only dlopens the plugins and our plugin is statically linked in
|
||||||
|
|
||||||
post_plugin->running_ticket = xine->port_ticket;
|
post_plugin->running_ticket = xine->port_ticket;
|
||||||
post_plugin->xine = xine;
|
post_plugin->xine = xine;
|
||||||
|
|
||||||
/* scope_plugin_t init */
|
/* scope_plugin_t init */
|
||||||
scope_plugin->list = calloc(1, sizeof(MyNode));
|
scope_plugin->list = (MyNode *) calloc(1, sizeof(MyNode));
|
||||||
scope_plugin->list->next = scope_plugin->list;
|
scope_plugin->list->next = scope_plugin->list;
|
||||||
|
|
||||||
return &post_plugin->xine_post;
|
return &post_plugin->xine_post;
|
||||||
}
|
}
|
||||||
|
|
||||||
MyNode* scope_plugin_list(void *post) {
|
MyNode *scope_plugin_list(void *post) {
|
||||||
return ((scope_plugin_t*)post)->list;
|
return ((scope_plugin_t*)post)->list;
|
||||||
}
|
}
|
||||||
|
|
||||||
int scope_plugin_channels(void *post) {
|
int scope_plugin_channels(void *post) {
|
||||||
return ((scope_plugin_t*)post)->channels;
|
return ((scope_plugin_t*)post)->channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
metronom_t* scope_plugin_metronom(void *post) {
|
metronom_t* scope_plugin_metronom(void *post) {
|
||||||
return &((scope_plugin_t*)post)->metronom;
|
return &((scope_plugin_t*)post)->metronom;
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,25 @@
|
|||||||
|
|
||||||
typedef struct my_node_s MyNode;
|
typedef struct my_node_s MyNode;
|
||||||
|
|
||||||
struct my_node_s
|
struct my_node_s {
|
||||||
{
|
MyNode *next;
|
||||||
MyNode *next;
|
int16_t *mem;
|
||||||
int16_t *mem;
|
int num_frames;
|
||||||
int num_frames;
|
int64_t vpts;
|
||||||
int64_t vpts;
|
int64_t vpts_end;
|
||||||
int64_t vpts_end;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
xine_post_t*
|
xine_post_t *scope_plugin_new( xine_t*, xine_audio_port_t* );
|
||||||
scope_plugin_new( xine_t*, xine_audio_port_t* );
|
|
||||||
|
|
||||||
/* we sacrifice type-safety here because some GCCs appear broken
|
/* we sacrifice type-safety here because some GCCs appear broken and choke on redefining the xine_post_t typedef */
|
||||||
* and choke on redefining the xine_post_t typedef
|
|
||||||
*/
|
|
||||||
|
|
||||||
MyNode*
|
MyNode *scope_plugin_list(void*);
|
||||||
scope_plugin_list( void* );
|
int scope_plugin_channels(void*);
|
||||||
|
metronom_t *scope_plugin_metronom(void*);
|
||||||
int
|
|
||||||
scope_plugin_channels( void* );
|
|
||||||
|
|
||||||
metronom_t*
|
|
||||||
scope_plugin_metronom( void* );
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,9 +233,10 @@ void BackendSettingsPage::Load_Device(QString output, QVariant device) {
|
|||||||
ui_->combobox_device->setEnabled(false);
|
ui_->combobox_device->setEnabled(false);
|
||||||
ui_->lineedit_device->setText("");
|
ui_->lineedit_device->setText("");
|
||||||
|
|
||||||
#ifndef Q_OS_WIN32
|
#ifdef Q_OS_WIN
|
||||||
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Automatically select", QVariant(""));
|
if (engine()->type() != Engine::GStreamer)
|
||||||
#endif
|
#endif
|
||||||
|
ui_->combobox_device->addItem(IconLoader::Load("soundcard"), "Automatically select", QVariant(""));
|
||||||
|
|
||||||
for (DeviceFinder *f : dialog()->app()->enginedevice()->device_finders_) {
|
for (DeviceFinder *f : dialog()->app()->enginedevice()->device_finders_) {
|
||||||
if (!f->outputs().contains(output)) continue;
|
if (!f->outputs().contains(output)) continue;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user