[vlmc-devel] [PATCH] Integrate libVLC consumer into VLMC

Paweł Goliński golpaw1 at gmail.com
Fri Jul 22 08:41:38 CEST 2016


Dnia 22.07.2016 o godz. 06:22 yikei lu <luyikei.qmltu at gmail.com> napisał(a):

> 2016-07-22 3:07 GMT+09:00 Pawel Golinski <golpaw1 at gmail.com>:
> 
> Hi ! Thanks for the patch.
> 
>> ---
>> src/Backend/MLT/MLTBackend.cpp                     |  15 +
>> src/Backend/MLT/modules/libvlc/consumer_libvlc.c   | 559 +++++++++++++++++++++
>> src/Backend/MLT/modules/libvlc/consumer_libvlc.yml |  70 +++
>> .../MLT/modules/libvlc/consumer_libvlc_window.yml  |  39 ++
>> src/CMakeLists.txt                                 |   8 +-
>> 5 files changed, 689 insertions(+), 2 deletions(-)
>> create mode 100644 src/Backend/MLT/modules/libvlc/consumer_libvlc.c
>> create mode 100644 src/Backend/MLT/modules/libvlc/consumer_libvlc.yml
>> create mode 100644 src/Backend/MLT/modules/libvlc/consumer_libvlc_window.yml
>> 
>> diff --git a/src/Backend/MLT/MLTBackend.cpp b/src/Backend/MLT/MLTBackend.cpp
>> index 3d39930..c466995 100644
>> --- a/src/Backend/MLT/MLTBackend.cpp
>> +++ b/src/Backend/MLT/MLTBackend.cpp
>> @@ -5,6 +5,7 @@
>>  * Copyright (C) 2008-2016 VideoLAN
>>  *
>>  * Authors: Yikei Lu <luyikei.qmltu at gmail.com>
>> + *          Pawel Golinski <golpaw1 at gmail.com>
>>  *
>>  * This program is free software; you can redistribute it and/or
>>  * modify it under the terms of the GNU General Public License
>> @@ -43,6 +44,15 @@ using namespace Backend::MLT;
>> static Backend::IBackend::LogHandler    staticLogHandler;
>> static std::mutex                       logMutex;
>> 
>> +extern "C" mlt_consumer consumer_libvlc_init( mlt_profile profile, mlt_service_type type, const char *id, const void *arg );
>> +
>> +static mlt_properties metadata( mlt_service_type type, const char *id, void *data )
>> +{
>> +    char file[ 4096 ];
>> +    snprintf( file, 4096, "%s%s", MLT_MODULES_PATH, (char*)data );
>> +    return mlt_properties_parse_yaml( file );
>> +}
>> +
>> IBackend*
>> Backend::instance()
>> {
>> @@ -54,6 +64,11 @@ MLTBackend::MLTBackend()
>>     m_mltRepo = Mlt::Factory::init();
>>     m_profile.setFrameRate( 2997, 100 );
>> 
>> +    m_mltRepo->register_service( consumer_type, "libvlc", (mlt_register_callback)consumer_libvlc_init );
>> +    m_mltRepo->register_service( consumer_type, "libvlc_window", (mlt_register_callback)consumer_libvlc_init );
>> +    m_mltRepo->register_metadata( consumer_type, "libvlc", metadata, (void*)"/libvlc/consumer_libvlc.yml" );
>> +    m_mltRepo->register_metadata( consumer_type, "libvlc_window", metadata, (void*)"/libvlc/consumer_libvlc_window.yml" );
>> +
> 
> I think you should make factory.c and do registration there like other
> modules do. Not in MLTBackend.

Why?
We're using MLT that is already compiled so we need to register plugins at runtime.
This is the least complex way to do that and it's 100% correct.

> 
>>     for ( int i = 0; i < m_mltRepo->filters()->count(); ++i )
>>     {
>>         auto pro = std::unique_ptr<Mlt::Properties>( m_mltRepo->metadata( filter_type, m_mltRepo->filters()->get_name( i ) ) );
>> diff --git a/src/Backend/MLT/modules/libvlc/consumer_libvlc.c b/src/Backend/MLT/modules/libvlc/consumer_libvlc.c
>> new file mode 100644
>> index 0000000..a34f8fa
>> --- /dev/null
>> +++ b/src/Backend/MLT/modules/libvlc/consumer_libvlc.c
>> @@ -0,0 +1,559 @@
>> +/*****************************************************************************
>> + * consumer_libvlc.c: libVLC consumer plugin for MLT
>> + *****************************************************************************
>> + * Copyright (C) 2008-2016 VideoLAN
>> + *
>> + * Authors: Pawel Golinski <golpaw1 at gmail.com>
>> + *
>> + * This program is free software; you can redistribute it and/or
>> + * modify it under the terms of the GNU General Public License
>> + * as published by the Free Software Foundation; either version 2
>> + * of the License, or (at your option) any later version.
>> + *
>> + * This program is distributed in the hope that it will be useful,
>> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
>> + * GNU General Public License for more details.
>> + *
>> + * You should have received a copy of the GNU General Public License
>> + * along with this program; if not, write to the Free Software
>> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
>> + *****************************************************************************/
>> +
>> +#include <framework/mlt.h>
>> +
>> +#include <vlc/vlc.h>
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <assert.h>
>> +#include <string.h>
>> +
>> +#define VIDEO_COOKIE 0
>> +#define AUDIO_COOKIE 1
>> +
>> +#define INITIAL_POSITION -1
>> +
>> +// Debug code
>> +
>> +pthread_mutex_t log_mutex;
>> +
>> +static void log_cb( void *data, int level, const libvlc_log_t *ctx, const char *fmt, va_list args )
>> +{
>> +       pthread_mutex_lock( &log_mutex );
>> +       printf( "VLC LOG: " );
>> +       vprintf( fmt, args );
>> +       printf( "\n" );
>> +       pthread_mutex_unlock( &log_mutex );
>> +}
>> +
>> +typedef struct consumer_libvlc_s *consumer_libvlc;
> 
> You should use VlmcLogger.
> 
>> +
>> +struct consumer_libvlc_s
>> +{
>> +       mlt_consumer parent;
>> +       libvlc_instance_t *vlc;
>> +       libvlc_media_t *media;
>> +       libvlc_media_player_t *media_player;
>> +       libvlc_event_manager_t *mp_manager;
>> +       int64_t latest_video_pts;
>> +       int64_t latest_audio_pts;
>> +       mlt_deque frame_queue;
>> +       pthread_mutex_t queue_mutex;
>> +       mlt_position video_position;
>> +       mlt_position audio_position;
>> +       void *video_imem_data;
>> +       void *audio_imem_data;
>> +       int running;
>> +       int output_to_window;
>> +};
>> +
>> +static void setup_vlc( consumer_libvlc self );
>> +static void setup_vlc_sout( consumer_libvlc self );
>> +static int setup_vlc_window( consumer_libvlc self );
>> +static int imem_get( void *data, const char* cookie, int64_t *dts, int64_t *pts,
>> +                                        unsigned *flags, size_t *bufferSize, void **buffer );
>> +static void imem_release( void *data, const char* cookie, size_t buffSize, void *buffer );
>> +static int consumer_start( mlt_consumer parent );
>> +static int consumer_stop( mlt_consumer parent );
>> +static int consumer_is_stopped( mlt_consumer parent );
>> +static void consumer_close( mlt_consumer parent );
>> +static void consumer_purge( mlt_consumer parent );
>> +static void mp_callback( const struct libvlc_event_t *evt, void *data );
>> +
>> +mlt_consumer consumer_libvlc_init( mlt_profile profile, mlt_service_type type, const char *id, const void *arg )
>> +{
>> +       int err;
>> +       mlt_consumer parent = NULL;
>> +       consumer_libvlc self = NULL;
>> +
>> +       // Allocate the consumer data structures
>> +       parent = calloc( 1, sizeof( struct mlt_consumer_s ) );
>> +       self = calloc( 1, sizeof( struct consumer_libvlc_s ) );
>> +       assert( parent != NULL && self != NULL );
>> +       err = mlt_consumer_init( parent, self, profile );
>> +       assert( err == 0 );
>> +
>> +       mlt_properties properties = MLT_CONSUMER_PROPERTIES( parent );
>> +       mlt_properties_set_lcnumeric( properties, "C" );
>> +       self->parent = parent;
>> +
>> +       // Set default libVLC specific properties
>> +       mlt_properties_set( properties, "input_vcodec", "RGBA" );
>> +       mlt_properties_set( properties, "input_acodec", "s16l" );
>> +       mlt_properties_set( properties, "output_vcodec", "mp2v" );
>> +       mlt_properties_set( properties, "output_acodec", "mpga" );
>> +       mlt_properties_set_int( properties, "output_vb", 8000000 );
>> +       mlt_properties_set_int( properties, "output_ab", 128000 );
>> +       if ( self->output_to_window )
>> +               mlt_properties_set_data( properties, "output_dst", arg, 0, NULL, NULL );
>> +       else
>> +               mlt_properties_set( properties, "output_dst", ( char* )arg );
>> +       mlt_properties_set( properties, "output_mux", "ps" );
>> +       mlt_properties_set( properties, "output_access", "file" );
>> +
>> +       self->vlc = libvlc_new( 0, NULL );
>> +       assert( self->vlc != NULL );
>> +
>> +       // Debug code
>> +       libvlc_log_set( self->vlc, log_cb, NULL );
>> +       pthread_mutex_init( &log_mutex, NULL );
>> +
>> +       self->frame_queue = mlt_deque_init( );
>> +       assert( self->frame_queue != NULL );
>> +
>> +       pthread_mutex_init( &self->queue_mutex, NULL );
>> +
>> +       parent->start = consumer_start;
>> +       parent->stop = consumer_stop;
>> +       parent->is_stopped = consumer_is_stopped;
>> +       parent->close = consumer_close;
>> +       parent->purge = consumer_purge;
>> +
>> +       // Set output_to_window flag if needed
>> +       if ( !strcmp( id, "libvlc_window" ) )
>> +               self->output_to_window = 1;
>> +
>> +       return parent;
>> +}
>> +
>> +static void setup_vlc( consumer_libvlc self )
>> +{
>> +       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +
>> +       // imem setup phase
>> +
>> +       // Allocate buffers
>> +       char imem_video_conf[ 512 ];
>> +       char imem_audio_conf[ 512 ];
>> +       char imem_get_conf[ 512 ];
>> +       char imem_release_conf[ 512 ];
>> +       char imem_data_conf[ 512 ];
>> +
>> +       // We will create media using imem MRL
>> +       sprintf( imem_video_conf, "imem://width=%i:height=%i:dar=%s:fps=%s/1:cookie=0:codec=%s:cat=2:caching=0",
>> +               mlt_properties_get_int( properties, "width" ),
>> +               mlt_properties_get_int( properties, "height" ),
>> +               mlt_properties_get( properties, "display_ratio" ),
>> +               mlt_properties_get( properties, "fps" ),
>> +               mlt_properties_get( properties, "input_vcodec" ) );
>> +
>> +       // Audio stream will be added as input slave
>> +       sprintf( imem_audio_conf, ":input-slave=imem://cookie=1:cat=1:codec=%s:samplerate=%d:channels=%d:caching=0",
>> +               mlt_properties_get( properties, "input_acodec" ),
>> +               mlt_properties_get_int( properties, "frequency" ),
>> +               mlt_properties_get_int( properties, "channels" ) );
>> +
>> +       // This configures imem callbacks
>> +       sprintf( imem_get_conf,
>> +               ":imem-get=%" PRIdPTR,
>> +               (intptr_t)(void*)&imem_get );
>> +
>> +       sprintf( imem_release_conf,
>> +               ":imem-release=%" PRIdPTR,
>> +               (intptr_t)(void*)&imem_release );
>> +
>> +       sprintf( imem_data_conf,
>> +               ":imem-data=%" PRIdPTR,
>> +               (intptr_t)(void*)self );
>> +
>> +       // Create media...
>> +       self->media = libvlc_media_new_location( self->vlc, imem_video_conf );
>> +       assert( self->media != NULL );
>> +
>> +       // ...and apply configuration parameters.
>> +       libvlc_media_add_option( self->media, imem_audio_conf );
>> +       libvlc_media_add_option( self->media, imem_get_conf );
>> +       libvlc_media_add_option( self->media, imem_release_conf );
>> +       libvlc_media_add_option( self->media, imem_data_conf );
>> +
>> +       // Setup sout chain if we're not outputting to window
>> +       if ( !self->output_to_window )
>> +       {
>> +               setup_vlc_sout( self );
>> +       }
>> +}
>> +
>> +static void setup_vlc_sout( consumer_libvlc self )
>> +{
>> +       assert( self->media != NULL );
>> +
>> +       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +
>> +       char sout_conf[ 512 ];
>> +
>> +       // This configures file output
>> +       sprintf( sout_conf, ":sout=#transcode{"
>> +               "vcodec=%s,fps=%s,width=%d,height=%d,vb=%d,"
>> +               "acodec=%s,channels=%d,samplerate=%d,ab=%d}"
>> +               ":standard{access=%s,mux=%s,dst=\"%s\"}",
>> +               mlt_properties_get( properties, "output_vcodec" ),
>> +               mlt_properties_get( properties, "fps" ),
>> +               mlt_properties_get_int( properties, "width" ),
>> +               mlt_properties_get_int( properties, "height" ),
>> +               mlt_properties_get_int( properties, "output_vb" ),
>> +               mlt_properties_get( properties, "output_acodec" ),
>> +               mlt_properties_get_int( properties, "channels" ),
>> +               mlt_properties_get_int( properties, "frequency" ),
>> +               mlt_properties_get_int( properties, "output_ab" ),
>> +               mlt_properties_get( properties, "output_access" ),
>> +               mlt_properties_get( properties, "output_mux" ),
>> +               mlt_properties_get( properties, "output_dst" ) );
>> +
>> +       libvlc_media_add_option( self->media, sout_conf );
>> +}
>> +
>> +static int setup_vlc_window( consumer_libvlc self )
>> +{
>> +       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +
>> +       char *window_type = mlt_properties_get( properties, "window_type" );
>> +       void *window_handle = mlt_properties_get_data( properties, "output_dst", NULL );
>> +
>> +       if ( window_type != NULL && window_handle != NULL )
>> +       {
>> +               if ( !strcmp( window_type, "nsobject") )
>> +               {
>> +                       libvlc_media_player_set_nsobject( self->media_player, window_handle );
>> +               }
>> +               else if ( !strcmp( window_type, "xwindow" ) )
>> +               {
>> +                       libvlc_media_player_set_xwindow( self->media_player, ( uint32_t )window_handle );
>> +               }
>> +               else if ( !strcmp( window_type, "hwnd" ) )
>> +               {
>> +                       libvlc_media_player_set_hwnd( self->media_player, window_handle );
>> +               }
>> +               else
>> +               {
>> +                       // Some unknown window_type was passed
>> +                       return 1;
>> +               }
>> +
>> +               // Setup finished successfully
>> +               return 0;
>> +       }
>> +       else
>> +       {
>> +               // We failed to get window_type and/or window_handle
>> +               return 1;
>> +       }
>> +}
>> +
>> +static int imem_get( void *data, const char* cookie, int64_t *dts, int64_t *pts,
>> +                                        uint32_t *flags, size_t *bufferSize, void **buffer )
>> +{
>> +       consumer_libvlc self = data;
>> +       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +       mlt_frame frame = NULL;
>> +       // Whether or not fetched frame need releasing
>> +       int cleanup_frame = 0;
>> +       *buffer = NULL;
>> +
>> +       int cookie_int = cookie[ 0 ] - '0';
>> +
>> +       // Get data if needed
>> +       pthread_mutex_lock( &self->queue_mutex );
>> +
>> +       frame = mlt_deque_pop_front( self->frame_queue );
>> +
>> +       // If we got frame from queue, we need to release it later
>> +       if ( frame != NULL )
>> +               cleanup_frame = 1;
>> +       else
>> +               frame = mlt_consumer_get_frame( self->parent );
>> +
>> +       if ( cookie_int == AUDIO_COOKIE && self->running )
>> +       {
>> +               assert( frame != NULL );
>> +               mlt_position current_position = mlt_frame_original_position( frame );
>> +
>> +               // We terminate imem if we got repeated frame, as this means pause
>> +               if ( current_position == self->audio_position )
>> +               {
>> +                       self->running = 0;
>> +                       pthread_mutex_unlock( &self->queue_mutex );
>> +                       return 1;
>> +               }
>> +               else
>> +               {
>> +                       // Update position
>> +                       self->audio_position = current_position;
>> +
>> +                       // This is used to pass frames to imem_release() if they need cleanup
>> +                       self->audio_imem_data = NULL;
>> +
>> +                       mlt_audio_format afmt = mlt_audio_s16;
>> +                       double fps = mlt_properties_get_double( properties, "fps" );
>> +                       int frequency = mlt_properties_get_int( properties, "frequency" );
>> +                       int channels = mlt_properties_get_int( properties, "channels" );
>> +                       int samples = mlt_sample_calculator( fps, frequency, self->audio_position );
>> +                       double pts_diff = ( double )samples / ( double )frequency * 1000000.0;
>> +
>> +                       mlt_frame_get_audio( frame, buffer, &afmt, &frequency, &channels, &samples );
>> +                       *bufferSize = samples * sizeof( int16_t ) * channels;
>> +
>> +                       *pts = self->latest_audio_pts + pts_diff + 0.5;
>> +                       *dts = *pts;
>> +
>> +                       self->latest_audio_pts = *pts;
>> +
>> +                       if ( cleanup_frame )
>> +                               self->audio_imem_data = frame;
>> +                       else
>> +                               mlt_deque_push_back( self->frame_queue, frame );
>> +               }
>> +       }
>> +       else if ( cookie_int == VIDEO_COOKIE && self->running )
>> +       {
>> +               assert( frame != NULL );
>> +               mlt_position current_position = mlt_frame_original_position( frame );
>> +
>> +               if ( current_position == self->video_position )
>> +               {
>> +                       self->running = 0;
>> +                       pthread_mutex_unlock( &self->queue_mutex );
>> +                       return 1;
>> +               }
>> +               else
>> +               {
>> +                       self->video_position = current_position;
>> +
>> +                       self->video_imem_data = NULL;
>> +
>> +                       double fps = mlt_properties_get_double( properties, "fps" );
>> +                       double pts_diff = 1.0 / fps * 1000000.0;
>> +
>> +                       mlt_image_format vfmt = mlt_image_rgb24a;
>> +                       int width = mlt_properties_get_int( properties, "width" );
>> +                       int height = mlt_properties_get_int( properties, "height" );
>> +                       mlt_frame_get_image( frame, ( uint8_t ** )buffer, &vfmt, &width, &height, 0 );
>> +                       *bufferSize = mlt_image_format_size( vfmt, width, height, NULL );
>> +
>> +                       *pts = self->latest_video_pts + pts_diff;
>> +                       *dts = *pts;
>> +
>> +                       self->latest_video_pts = *pts;
>> +
>> +                       if ( cleanup_frame )
>> +                               self->video_imem_data = frame;
>> +                       else
>> +                               mlt_deque_push_back( self->frame_queue, frame );
>> +                       }
>> +       }
>> +       else if ( self->running )
>> +       {
>> +               // Invalid cookie
>> +               assert( 0 );
>> +       }
>> +       pthread_mutex_unlock( &self->queue_mutex );
>> +
>> +       assert( frame != NULL );
>> +       if ( *buffer == NULL )
>> +               return 1;
>> +
>> +       return 0;
>> +}
>> +
>> +static void imem_release( void *data, const char* cookie, size_t buffSize, void *buffer )
>> +{
>> +       consumer_libvlc self = data;
>> +
>> +       int cookie_int = cookie[ 0 ] - '0';
>> +
>> +       if ( cookie_int == VIDEO_COOKIE && self->running )
>> +       {
>> +               if ( self->video_imem_data )
>> +               {
>> +                       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +                       mlt_frame frame = self->video_imem_data;
>> +                       mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
>> +                       self->video_imem_data = NULL;
>> +               }
>> +       }
>> +       else if ( cookie_int == AUDIO_COOKIE && self->running )
>> +       {
>> +               if ( self->audio_imem_data )
>> +               {
>> +                       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +                       mlt_frame frame = self->audio_imem_data;
>> +                       mlt_events_fire( properties, "consumer-frame-show", frame, NULL );
>> +                       self->audio_imem_data = NULL;
>> +
>> +               }
>> +       }
>> +       else if ( self->running )
>> +       {
>> +               // Invalid cookie
>> +               assert( 0 );
>> +       }
>> +}
>> +
>> +static void mp_callback( const struct libvlc_event_t *evt, void *data )
>> +{
>> +       consumer_libvlc self = data;
>> +       assert( self != NULL );
>> +
>> +       switch ( evt->type )
>> +       {
>> +               case libvlc_MediaPlayerStopped:
>> +                       self->running = 0;
>> +                       break;
>> +
>> +               default:
>> +                       assert( 0 );
>> +       }
>> +}
>> +
>> +static int consumer_start( mlt_consumer parent )
>> +{
>> +       int err;
>> +
>> +       consumer_libvlc self = parent->child;
>> +       assert( self != NULL );
>> +
>> +       mlt_properties properties = MLT_CONSUMER_PROPERTIES( self->parent );
>> +
>> +
>> +       if ( consumer_is_stopped( parent ) )
>> +       {
>> +               // Free all previous resources
>> +               if ( self->media_player )
>> +               {
>> +                       libvlc_media_player_release( self->media_player );
>> +                       self->media_player = NULL;
>> +               }
>> +               if ( self->media )
>> +               {
>> +                       libvlc_media_release( self->media );
>> +                       self->media = NULL;
>> +               }
>> +
>> +               // Apply properties to new media
>> +               setup_vlc( self );
>> +               self->media_player = libvlc_media_player_new_from_media( self->media );
>> +               assert( self->media_player != NULL );
>> +
>> +               // Set window output if we're using it
>> +               if ( self->output_to_window )
>> +               {
>> +                       err = setup_vlc_window( self );
>> +
>> +                       if ( err )
>> +                       {
>> +                               char error_msg[] = "Wrong window_type and/or output_dst parameters supplied.\n";
>> +                               char *window_type = mlt_properties_get( properties, "window_type" );
>> +                               mlt_log_error( MLT_CONSUMER_SERVICE( self->parent ), error_msg );
>> +                               mlt_events_fire( properties, "consumer-fatal-error", NULL );
>> +                               return err;
>> +                       }
>> +               }
>> +
>> +               // Catch media_player stop
>> +               self->mp_manager = libvlc_media_player_event_manager( self->media_player );
>> +               assert( self->mp_manager != NULL );
>> +               libvlc_event_attach( self->mp_manager, libvlc_MediaPlayerStopped, &mp_callback, self );
>> +
>> +               // Reset play heads
>> +               self->video_position = INITIAL_POSITION;
>> +               self->audio_position = INITIAL_POSITION;
>> +
>> +               // Run media player
>> +               self->running = 1;
>> +               err = libvlc_media_player_play( self->media_player );
>> +
>> +               // If we failed to play, we're not running
>> +               if ( err ) {
>> +                       self->running = 0;
>> +               }
>> +
>> +               return err;
>> +       }
>> +       return 1;
>> +}
>> +
>> +static int consumer_stop( mlt_consumer parent )
>> +{
>> +       consumer_libvlc self = parent->child;
>> +       assert( self != NULL );
>> +
>> +       if ( self->media_player )
>> +       {
>> +               self->running = 0;
>> +               libvlc_media_player_stop( self->media_player );
>> +       }
>> +
>> +       // Reset pts counters
>> +       self->latest_video_pts = 0;
>> +       self->latest_audio_pts = 0;
>> +
>> +       return 0;
>> +}
>> +
>> +static int consumer_is_stopped( mlt_consumer parent )
>> +{
>> +       consumer_libvlc self = parent->child;
>> +       assert( self != NULL );
>> +
>> +       if ( self->media_player )
>> +       {
>> +               return !self->running;
>> +       }
>> +
>> +       return 1;
>> +}
>> +
>> +static void consumer_purge( mlt_consumer parent )
>> +{
>> +       // We do nothing here, we purge on stop()
>> +}
>> +
>> +static void consumer_close( mlt_consumer parent )
>> +{
>> +       if ( parent == NULL )
>> +       {
>> +               return;
>> +       }
>> +
>> +       consumer_libvlc self = parent->child;
>> +
>> +       if ( self != NULL )
>> +       {
>> +               consumer_stop( parent );
>> +
>> +               if ( self->media_player )
>> +                       libvlc_media_player_release( self->media_player );
>> +
>> +               if ( self->media )
>> +                       libvlc_media_release( self->media );
>> +
>> +               if ( self->vlc )
>> +                       libvlc_release( self->vlc );
>> +
>> +               pthread_mutex_destroy( &self->queue_mutex );
>> +               free( self );
>> +       }
>> +
>> +       parent->close = NULL;
>> +       mlt_consumer_close( parent );
>> +}
>> diff --git a/src/Backend/MLT/modules/libvlc/consumer_libvlc.yml b/src/Backend/MLT/modules/libvlc/consumer_libvlc.yml
>> new file mode 100644
>> index 0000000..2776715
>> --- /dev/null
>> +++ b/src/Backend/MLT/modules/libvlc/consumer_libvlc.yml
>> @@ -0,0 +1,70 @@
>> +schema_version: 0.1
>> +type: consumer
>> +identifier: libvlc
>> +title: libVLC
>> +version: 1
>> +creator: Pawel Golinski
>> +license: GNU GPL
>> +language: en
>> +tags:
>> +  - Audio
>> +  - Video
>> +description: >
>> +  libVLC video and audio output module. It uses VLC "standard" module.
>> +  It can be set up using usual MLT consumer properties and additional
>> +  libVLC specific properties described here.
>> +parameters:
>> +  - identifier: output_dst
>> +    argument: yes
>> +    title: File/URL
>> +    type: string
>> +    description: "sout-standard-dst" option
>> +    required: yes
>> +
>> +  - identifier: input_vcodec
>> +    title: Input vcodec
>> +    type: string
>> +    description: Format, in which raw video frames will be supplied to the consumer.
>> +    default: RGBA
>> +
>> +  - identifier: input_acodec
>> +    title: Input acodec
>> +    type: string
>> +    description: Format, in which raw audio frames will be supplied to the consumer.
>> +    default: s16l
>> +
>> +  - identifier: output_vcodec
>> +    title: Output vcodec.
>> +    type: string
>> +    description: "sout-transcode-vcodec" option
>> +    default: mp2v
>> +
>> +  - identifier: output_acodec
>> +    title: Output acodec.
>> +    type: string
>> +    description: "sout-transcode-acodec" option
>> +    default: mpga
>> +
>> +  - identifier: output_vb
>> +    title: Output video bitrate.
>> +    type: integer
>> +    description: "sout-transcode-vb" option
>> +    default: 8000000
>> +
>> +  - identifier: output_ab
>> +    title: Output audio bitrate.
>> +    type: integer
>> +    description: "sout-transcode-ab" option
>> +    default: 128000
>> +
>> +  - identifier: output_mux
>> +    title: Output muxer.
>> +    type: string
>> +    description: "sout-standard-mux" option
>> +    default: ps
>> +
>> +  - identifier: output_access
>> +    title: Output method.
>> +    type: string
>> +    description: "sout-standard-access" option
>> +    default: file
>> diff --git a/src/Backend/MLT/modules/libvlc/consumer_libvlc_window.yml b/src/Backend/MLT/modules/libvlc/consumer_libvlc_window.yml
>> new file mode 100644
>> index 0000000..d2b7410
>> --- /dev/null
>> +++ b/src/Backend/MLT/modules/libvlc/consumer_libvlc_window.yml
>> @@ -0,0 +1,39 @@
>> +schema_version: 0.1
>> +type: consumer
>> +identifier: libvlc_window
>> +title: libVLC Window
>> +version: 1
>> +creator: Pawel Golinski
>> +license: GNU GPL
>> +language: en
>> +tags:
>> +  - Audio
>> +  - Video
>> +description: >
>> +  libVLC video and audio output module. It uses VLC window output.
>> +  It can be set up using usual MLT consumer properties and additional
>> +  libVLC specific properties described here.
>> +parameters:
>> +  - identifier: output_dst
>> +    argument: yes
>> +    title: Window handle
>> +    description: Window, to which libVLC should render the media.
>> +    required: yes
>> +
>> +  - identifier: window_type
>> +    title: Window type
>> +    type: string
>> +    description: Type of the window, the output_dst points to (xwindow/nsobject/hwnd)
>> +    required: yes
>> +
>> +  - identifier: input_vcodec
>> +    title: Input vcodec
>> +    type: string
>> +    description: Format, in which raw video frames will be supplied to the consumer.
>> +    default: RGBA
>> +
>> +  - identifier: input_acodec
>> +    title: Input acodec
>> +    type: string
>> +    description: Format, in which raw audio frames will be supplied to the consumer.
>> +    default: s16l
>> \ No newline at end of file
>> diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
>> index a85cf0a..be37f15 100644
>> --- a/src/CMakeLists.txt
>> +++ b/src/CMakeLists.txt
>> @@ -55,6 +55,9 @@ INCLUDE_DIRECTORIES(${FREI0R_INCLUDE_DIR})
>> # Instruct CMake to run moc automatically when needed.
>> SET(CMAKE_AUTOMOC ON)
>> 
>> +SET(MLT_MODULES Backend/MLT/modules)
>> +ADD_DEFINITIONS(-DMLT_MODULES_PATH="${CMAKE_CURRENT_BINARY_DIR}/src/${MLT_MODULES}")
>> +
>> SET(VLMC_SRCS
>>     Commands/Commands.cpp
>>     Backend/IBackend.h
>> @@ -74,6 +77,7 @@ SET(VLMC_SRCS
>>     Backend/MLT/MLTFilter.cpp
>>     Backend/MLT/MLTTransition.cpp
>>     Backend/MLT/MLTMultiTrack.cpp
>> +    Backend/MLT/modules/libvlc/consumer_libvlc.c
>>     EffectsEngine/EffectHelper.cpp
>>     Library/Library.cpp
>>     Library/MediaContainer.cpp
>> @@ -314,14 +318,14 @@ ENDIF(UNIX)
>> 
>> if( APPLE )
>>     set(APPLICATION_BUNDLE ${CMAKE_BINARY_DIR}/bin/vlmc.app)
>> -    set(APPLICATION_LIB_DIR ${LIBVLC_LIB_DIR})
>> +    set(APPLICATION_LIB_DIR ${LIBVLC_LIBRARY_DIRS})
>> 
>>     # re-enable this when we start addressing redistribution
>>     # message(STATUS "Looking for bundle ${APPLICATION_BUNDLE} with library path ${APPLICATION_LIB_DIR}")
>>     # install(CODE "include(BundleUtilities)
>>     add_custom_command(TARGET vlmc
>>         POST_BUILD
>> -        COMMAND ${CMAKE_SOURCE_DIR}/cmake/FixBundle.sh ${APPLICATION_BUNDLE}/Contents/MacOS ${LIBVLC_LIB_DIR}
>> +        COMMAND ${CMAKE_SOURCE_DIR}/cmake/FixBundle.sh ${APPLICATION_BUNDLE}/Contents/MacOS ${LIBVLC_LIBRARY_DIRS}
> 
> Why did you rename LIB to LIBRARY?

Shoot. That's remains from another patch :/ (which needs to be merged asap btw because compilation is broken on OS X)

> 
>>         COMMENT "Fixing application bundle for local run")
>>     # fixup_bundle(\"${APPLICATION_BUNDLE}\" \"\" \"${APPLICATION_LIB_DIR}\")" COMPONENT Runtime)
>> endif()
>> --
>> 2.7.4 (Apple Git-66)
> 
> Maybe it's a good idea to have a separated repository or make it
> merged into the official mlt repository.

I don't think guys at mlt would want to maintain these plugins so probably official mlt repo is not an option.

> But I have to see how others
> think :)
> 
>> _______________________________________________
>> Vlmc-devel mailing list
>> Vlmc-devel at videolan.org
>> https://mailman.videolan.org/listinfo/vlmc-devel
> _______________________________________________
> Vlmc-devel mailing list
> Vlmc-devel at videolan.org
> https://mailman.videolan.org/listinfo/vlmc-devel


More information about the Vlmc-devel mailing list