From 304d3a226c20e0da7ac2f4dedbda3876a1b817f9 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Fri, 24 Jul 2020 15:04:55 +0900 Subject: Fixed xine scope plugin functionality with xine 1.2.10. Signed-off-by: Michele Calgaro --- src/app/xineEngine.cpp | 36 ++++++------------ src/app/xineScope.c | 100 ++++++++++++++++++++++++++++++++++--------------- src/app/xineScope.h | 89 ++++++++++++++++++++++++------------------- 3 files changed, 132 insertions(+), 93 deletions(-) (limited to 'src') diff --git a/src/app/xineEngine.cpp b/src/app/xineEngine.cpp index 3409a20..c57f79e 100644 --- a/src/app/xineEngine.cpp +++ b/src/app/xineEngine.cpp @@ -22,11 +22,6 @@ #include "xineScope.h" -#define XINE_SAFE_MODE 1 - -extern "C" { void _debug( const char *string ) { debug() << string; } } //FIXME - - namespace Codeine { @@ -111,9 +106,7 @@ VideoWindow::init() if( !m_xine ) return false; - #ifdef XINE_SAFE_MODE xine_engine_set_param( m_xine, XINE_ENGINE_PARAM_VERBOSITY, 99 ); - #endif debug() << "xine_config_load()\n"; xine_config_load( m_xine, TQFile::encodeName( TQDir::homeDirPath() + "/.xine/config" ) ); @@ -121,6 +114,11 @@ VideoWindow::init() debug() << "xine_init()\n"; xine_init( m_xine ); +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) + xine_register_plugins( m_xine, scope_plugin_info ); +#endif + debug() << "xine_open_video_driver()\n"; m_videoPort = xine_open_video_driver( m_xine, "auto", XINE_VISUAL_TYPE_X11, videoWindow()->x11Visual() ); @@ -147,12 +145,12 @@ VideoWindow::init() xine_osd_set_text_palette( m_osd, XINE_TEXTPALETTE_WHITE_BLACK_TRANSPARENT, XINE_OSD_TEXT1 ); } -#ifndef XINE_SAFE_MODE -#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \ - (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION < 10) debug() << "scope_plugin_new()\n"; +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) + m_scope = xine_post_init( m_xine, "codeine-scope", 1, &m_audioPort, NULL ); +#else m_scope = scope_plugin_new( m_xine, m_audioPort ); -#endif //FIXME this one seems to make seeking unstable for Codeine, perhaps xine_set_param( m_stream, XINE_PARAM_METRONOM_PREBUFFER, 6000 ); //less buffering, faster seeking.. @@ -265,20 +263,15 @@ VideoWindow::load( const KURL &url ) //TODO popup message for no audio //TODO popup message for no video + no audio - #ifndef XINE_SAFE_MODE // ensure old buffers are deleted // FIXME leaves one erroneous buffer timerEvent( 0 ); -#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \ - (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION < 10) if( m_scope ) { xine_post_out_t *source = xine_get_audio_source( m_stream ); xine_post_in_t *target = (xine_post_in_t*)xine_post_input( m_scope, const_cast("audio in") ); xine_post_wire( source, target ); } -#endif - #endif announceStateChange(); @@ -579,11 +572,10 @@ VideoWindow::scope() if( xine_get_status( m_stream ) != XINE_STATUS_PLAY ) return scope; -#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \ - (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION < 10) //prune the buffer list and update the m_current_vpts timestamp timerEvent( 0 ); + const int64_t pts_per_smpls = 0; //scope_plugin_pts_per_smpls( m_scope ); for( int channels = xine_get_stream_info( m_stream, XINE_STREAM_INFO_AUDIO_CHANNELS ), frame = 0; frame < SCOPE_SIZE; ) { MyNode *best_node = 0; @@ -599,7 +591,7 @@ VideoWindow::scope() diff = m_current_vpts; diff -= best_node->vpts; diff *= 1<<16; - diff /= myMetronom->pts_per_smpls; + diff /= pts_per_smpls; const int16_t* data16 = best_node->mem; @@ -627,7 +619,6 @@ VideoWindow::scope() m_current_vpts = best_node->vpts_end; m_current_vpts++; //FIXME needs to be done for some reason, or you get situations where it uses same buffer again and again } -#endif return scope; } @@ -635,10 +626,7 @@ VideoWindow::scope() void VideoWindow::timerEvent( TQTimerEvent* ) { -#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \ - (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION < 10) /// here we prune the buffer list regularly - #ifndef XINE_SAFE_MODE MyNode * const first_node = myList->next; MyNode const * const list_end = myList; @@ -661,8 +649,6 @@ VideoWindow::timerEvent( TQTimerEvent* ) prev = node; } - #endif -#endif } void diff --git a/src/app/xineScope.c b/src/app/xineScope.c index cd3b4e1..3e7cb69 100644 --- a/src/app/xineScope.c +++ b/src/app/xineScope.c @@ -1,8 +1,6 @@ /* Author: Max Howell , (C) 2004 Copyright: See COPYING file that comes with this distribution */ -/* gcc doesn't like inline for me */ -#define inline /* need access to port_ticket */ #define XINE_ENGINE_INTERNAL @@ -12,16 +10,10 @@ static MyNode theList; -static metronom_t theMetronom; static int myChannels = 0; +static int64_t pts_per_smpls; MyNode* const myList = &theList; -metronom_t* const myMetronom = &theMetronom; - - -/* defined in xineEngine.cpp */ -extern void _debug( const char * ); - /************************* * post plugin functions * @@ -30,9 +22,7 @@ extern void _debug( const char * ); static int scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bits, uint32_t rate, int mode ) { - _debug( "scope_port_open()\n" ); - - #define port ((post_audio_port_t*)port_gen) + post_audio_port_t *port = (post_audio_port_t *)port_gen; _x_post_rewire( (post_plugin_t*)port->post ); _x_post_inc_usage( port ); @@ -44,13 +34,20 @@ scope_port_open( xine_audio_port_t *port_gen, xine_stream_t *stream, uint32_t bi myChannels = _x_ao_mode2channels( mode ); - return port->original_port->open( port->original_port, stream, bits, rate, mode ); + int ret = port->original_port->open( port->original_port, stream, bits, rate, mode ); +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) + pts_per_smpls = ((uint32_t)90000 * (uint32_t)32768) / rate; +#else + pts_per_smpls = stream->metronom->pts_per_smpls; +#endif + return ret; } static void scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream ) { - _debug( "scope_port_close()\n" ); + post_audio_port_t *port = (post_audio_port_t *)port_gen; port->stream = NULL; port->original_port->close( port->original_port, stream ); @@ -61,28 +58,29 @@ scope_port_close( xine_audio_port_t *port_gen, xine_stream_t *stream ) static void scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_stream_t *stream ) { -#if XINE_MAJOR_VERSION < 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION < 2) || \ - (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION < 10) - MyNode *new_node; - const int num_samples = buf->num_frames * myChannels; + post_audio_port_t *port = (post_audio_port_t *)port_gen; /* we are too simple to handle 8bit */ /* what does it mean when stream == NULL? */ if( port->bits == 8 ) { port->original_port->put_buffer( port->original_port, buf, stream ); return; } - /* I keep my own metronom because xine wouldn't for some reason */ - memcpy( myMetronom, stream->metronom, sizeof(metronom_t) ); + MyNode *new_node; + const int num_samples = buf->num_frames * myChannels; new_node = malloc( sizeof(MyNode) ); - new_node->vpts = myMetronom->got_audio_samples( myMetronom, buf->vpts, buf->num_frames ); +#ifdef METRONOM_VPTS + new_node->vpts = stream->metronom->get_option(stream->metronom, METRONOM_VPTS); +#else + new_node->vpts = stream->metronom->got_audio_samples( stream->metronom, 0, 0 ); +#endif new_node->num_frames = buf->num_frames; new_node->mem = malloc( num_samples * 2 ); memcpy( new_node->mem, buf->mem, num_samples * 2 ); { int64_t - K = myMetronom->pts_per_smpls; /*smpls = 1<<16 samples*/ + K = pts_per_smpls; /*smpls = 1<<16 samples*/ K *= num_samples; K /= (1<<16); K += new_node->vpts; @@ -97,9 +95,6 @@ scope_port_put_buffer( xine_audio_port_t *port_gen, audio_buffer_t *buf, xine_st * NOTE this is thread-safe due to the way we handle the list in the GUI thread */ new_node->next = myList->next; myList->next = new_node; -#endif - - #undef port } static void @@ -113,13 +108,17 @@ scope_dispose( post_plugin_t *this ) * plugin init function * ************************/ -xine_post_t* -scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target ) +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) +static post_plugin_t* scope_plugin_new( post_class_t *class_gen, int inputs, xine_audio_port_t *audio_target[], xine_video_port_t *video_target[] ) +#else +xine_post_t* scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target ) +#endif { if( audio_target == NULL ) return NULL; - post_plugin_t *post_plugin = xine_xmalloc( sizeof(post_plugin_t) ); + post_plugin_t *post_plugin = calloc( 1, sizeof(post_plugin_t) ); { post_plugin_t *this = post_plugin; @@ -129,7 +128,12 @@ scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target ) _x_post_init( this, 1, 0 ); - port = _x_post_intercept_audio_port( this, audio_target, &input, &output ); +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) + port = _x_post_intercept_audio_port( post_plugin, audio_target[0], &input, &output ); +#else + port = _x_post_intercept_audio_port( post_plugin, audio_target, &input, &output ); +#endif port->new_port.open = scope_port_open; port->new_port.close = scope_port_close; port->new_port.put_buffer = scope_port_put_buffer; @@ -145,10 +149,46 @@ scope_plugin_new( xine_t *xine, xine_audio_port_t *audio_target ) /* 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->xine = xine; #endif +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) + return post_plugin; +#else return &post_plugin->xine_post; +#endif +} + +int64_t scope_plugin_pts_per_smpls( void *post ) +{ + return pts_per_smpls; +} + +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) +static void *scope_init_plugin(xine_t *xine, const void *data) +{ + static const post_class_t post_scope_class = { + .open_plugin = scope_plugin_new, + .identifier = "codeine-scope", + .description = "Codeine Scope", + .dispose = NULL, + }; + + (void)xine; + (void)data; + + return (void*)&post_scope_class; } + +static const post_info_t scope_special_info = { + .type = XINE_POST_TYPE_AUDIO_VISUALIZATION, +}; + +const plugin_info_t scope_plugin_info[] = { + { PLUGIN_POST, 10, "codeine-scope", XINE_VERSION_CODE, &scope_special_info, scope_init_plugin }, + { PLUGIN_NONE, 0, NULL, 0, NULL, NULL } +}; +#endif diff --git a/src/app/xineScope.h b/src/app/xineScope.h index f2dae75..623d56d 100644 --- a/src/app/xineScope.h +++ b/src/app/xineScope.h @@ -1,38 +1,51 @@ -/* Author: Max Howell , (C) 2004 - 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) -*/ - -#ifndef XINESCOPE_H -#define XINESCOPE_H - -/* need access to some stuff for scope time stamping */ -#define METRONOM_INTERNAL - -#include -#include - -typedef struct my_node_s MyNode; - -struct my_node_s -{ - MyNode *next; - int16_t *mem; - int num_frames; - int64_t vpts; - int64_t vpts_end; -}; - -extern metronom_t* const myMetronom; -extern MyNode* const myList; - -#ifdef __cplusplus -extern "C" -{ - xine_post_t* - scope_plugin_new( xine_t*, xine_audio_port_t* ); -} -#endif - -#endif +/* Author: Max Howell , (C) 2004 + 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) +*/ + +#ifndef XINESCOPE_H +#define XINESCOPE_H + +/* need access to some stuff for scope time stamping */ +#define METRONOM_INTERNAL + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif +#include +#ifdef __cplusplus +} +#endif + +typedef struct my_node_s MyNode; + +struct my_node_s +{ + MyNode *next; + int16_t *mem; + int num_frames; + int64_t vpts; + int64_t vpts_end; +}; + +extern MyNode* const myList; + +#ifdef __cplusplus +extern "C" +{ +#if XINE_MAJOR_VERSION > 1 || (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION > 2) || \ + (XINE_MAJOR_VERSION == 1 && XINE_MINOR_VERSION == 2 && XINE_SUB_VERSION >= 10) + extern const plugin_info_t scope_plugin_info[]; +#else + xine_post_t* scope_plugin_new( xine_t*, xine_audio_port_t* ); +#endif + int64_t scope_plugin_pts_per_smpls( void* ); +} +#endif + +#endif -- cgit v1.2.1