[vlc-devel] help test decklink output plugin (video and audio)

Jean-Baptiste Kempf jb at videolan.org
Tue Aug 16 09:40:53 CEST 2011


On Tue, Aug 16, 2011 at 09:29:00AM +0700, Ocon 8866 wrote :
> Please help test my plugin: Decklink output.

Nice work!

I cannot test, but can tell a few remarks, before inclusion:
 - no tabs in source code, please,
 - cleanup your includes (do you need all of those?) and your defines,
 - be careful about your code sytle consistency,
 - align code when it helps read it.

> # if __WORDSIZE == 64
> #  define INT64_C(c)	c ## L
> # else
> #  define INT64_C(c)	c ## LL
> # endif

This shouldn't be here.

> #define CLOCK_FREQ INT64_C(1000000)

Already defined in the VLC headers.

> #define DECKLINK_VIDEO_CODEC VLC_CODEC_UYVY
This is the recommended one by Decklink?

> #define DECKLINK_AUDIO_CODEC VLC_CODEC_S16N
Why not FL32?

> typedef struct {
> 
>     IDeckLink *p_card;
>     IDeckLinkOutput *p_output;
>     IDeckLinkConfiguration *p_config;
>     IDeckLinkDisplayModeIterator *p_display_iterator;
>     IDeckLinkIterator *decklink_iterator;
>     int         i_card_index;
>     char        *psz_video_connection;
>     BMDDisplayMode        display_mode;
>     BMDVideoOutputFlags		videoOutputFlags;
>     char        *psz_audio_connection;
> 	int i_channels;
> 	int i_rate;
>     uint32_t i_dominance_flags;
>     int i_width;
>     int i_height;
>     BMDTimeScale i_timescale;
>     BMDTimeValue i_frameduration;
>     vlc_mutex_t m_lock;
>     vlc_atomic_t m_ref;
> } decklink_sys_t;

Please do so alignment

> /*****************************************************************************
>  * Module descriptor
>  *****************************************************************************/
> //
> //
> vlc_module_begin()
>     set_shortname( N_("DecklinkOutput") )
>     set_description( N_("Decklink Output plug-in") )
> //    add_shortcut( "decklink-output" )
>     set_section( N_("Decklink General Options"), NULL )
>     add_integer( CFG_PREFIX "card-index", 0,
>                  CARD_INDEX_TEXT, CARD_INDEX_LONGTEXT, true )
> 
>     add_submodule ()
> //    set_shortname (N_("DecklinkVOut"))
>     set_description (N_("Decklink Video Output module"))
>     set_category(CAT_VIDEO)
>     set_subcategory(SUBCAT_VIDEO_VOUT)
>     set_capability("vout display", 0)
>     set_callbacks (OpenVideo, CloseVideo)
>     set_section( N_("Decklink Video Options"), NULL )
> //    add_shortcut( "decklink-vout" )
>     add_string( VIDEO_CFG_PREFIX "video-connection", 0,
>                  VIDEO_CONNECTION_TEXT, VIDEO_CONNECTION_LONGTEXT, true )
>                  change_string_list( ppsz_videoconns, ppsz_videoconns_text, 0 )
>     add_string( VIDEO_CFG_PREFIX "mode", "pal ",
>                  MODE_TEXT, MODE_LONGTEXT, true )
> 
>     add_submodule ()
> //    set_shortname (N_("DecklinkAOut"))
>     set_description (N_("Decklink Audio Output module"))
>     set_category( CAT_AUDIO )
>     set_subcategory( SUBCAT_AUDIO_AOUT )
>     set_capability( "audio output", 0 )
>     set_callbacks (OpenAudio, CloseAudio)
> //    add_shortcut( "decklink-aout" )
>     set_section( N_("Decklink Audio Options"), NULL )
>     add_string( AUDIO_CFG_PREFIX "audio-connection", 0,
>                 AUDIO_CONNECTION_TEXT, AUDIO_CONNECTION_LONGTEXT, true )
>                 change_string_list( ppsz_audioconns, ppsz_audioconns_text, 0 )
>     add_integer( AUDIO_CFG_PREFIX "audio-rate", 48000,
>                 RATE_TEXT, RATE_LONGTEXT, true )
>     add_integer( AUDIO_CFG_PREFIX "audio-channels", 2,
>                 CHANNELS_TEXT, CHANNELS_LONGTEXT, true )
> vlc_module_end ()

You shouldn't need 2 submodules, but only 1 module and 1 submodule.

> /*****************************************************************************
>  * Open: initialize interface  , public IDeckLinkAudioOutputCallback
>  *****************************************************************************/
> 
> static int OpenDecklink( vlc_object_t *p_this )
> {
> 
> 
> 	if(!(vlc_atomic_get( &decklink_sys.m_ref ))){
> 	//if(!(decklink_sys.m_ref)){
> 		vlc_mutex_init(&decklink_sys.m_lock);
> 		vlc_mutex_lock(&decklink_sys.m_lock);
> 		vlc_atomic_set( &(decklink_sys.m_ref), 0 );
> 
> 	    int i_rate;
> 	    int i_card_index;
> 	    int i_channels;
> 	    BMDVideoOutputFlags		videoOutputFlags = 0;
> 	    bool        b_found_mode;
> 
> 		i_card_index = var_InheritInteger( p_this, CFG_PREFIX "card-index" );
> 
> 		//IDeckLinkDisplayModeIterator *p_display_iterator = NULL;
> 
> 	    decklink_sys.decklink_iterator = CreateDeckLinkIteratorInstance();
> 	    if( !decklink_sys.decklink_iterator )
> 	    {
> 	        msg_Err( p_this, "DeckLink drivers not found." );
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 	    HRESULT result;
> 	    if( i_card_index < 0 )
> 	    {
> 	        msg_Err( p_this, "Invalid card index %d", i_card_index );
> 	        if( decklink_sys.decklink_iterator )
> 	        	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 	    for( int i = 0; i <= i_card_index; ++i )
> 	    {
> 	        if( decklink_sys.p_card ){
> 
> 	        	//decklink_sys.p_card->Release();
> 	            msg_Dbg( p_this, "Error here %d Cannot Release Pcard dc", i);
> 	        }
> 	        result = decklink_sys.decklink_iterator->Next( &decklink_sys.p_card );
> 	        if( result != S_OK )
> 	            break;
> 	    }
> 	    if( result != S_OK )
> 	    {
> 	        msg_Err( p_this, "DeckLink PCI card %d not found", i_card_index );
> 	        if( decklink_sys.decklink_iterator )
> 	        	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 
> 	    const char *psz_model_name;
> 	    result = decklink_sys.p_card->GetModelName( &psz_model_name );
> 
> 	    if( result != S_OK )
> 	    {
> 	        msg_Err( p_this, "Could not get model name" );
> 	        if( decklink_sys.decklink_iterator )
> 	        	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 	    msg_Dbg( p_this, "Opened DeckLink PCI card %d (%s)", i_card_index, psz_model_name );
> 	    if( decklink_sys.p_card->QueryInterface( IID_IDeckLinkOutput, (void**)&decklink_sys.p_output) != S_OK )
> 	    {
> 	        msg_Err( p_this, "Card has no outputs" );
> 	        if( decklink_sys.decklink_iterator )
> 	        	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 	    if( decklink_sys.p_card->QueryInterface( IID_IDeckLinkConfiguration, (void**)&decklink_sys.p_config) != S_OK )
> 	    {
> 	        msg_Err( p_this, "Failed to get configuration interface" );
> 	        if( decklink_sys.decklink_iterator )
> 	        	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 
> 	    decklink_sys.i_card_index = i_card_index ;
> 
> 	    //Setting up Video Connection
> 	    char* psz_video_connection;
> 	    psz_video_connection = var_InheritString( p_this, VIDEO_CFG_PREFIX "video-connection" );
> 	    if( psz_video_connection )
> 	    {
> 	    	BMDVideoConnection conn;
> 	        if ( !strcmp( psz_video_connection, "sdi" ) )
> 	            conn = bmdVideoConnectionSDI;
> 	        else if ( !strcmp( psz_video_connection, "hdmi" ) )
> 	            conn = bmdVideoConnectionHDMI;
> 	        else if ( !strcmp( psz_video_connection, "opticalsdi" ) )
> 	            conn = bmdVideoConnectionOpticalSDI;
> 	        else if ( !strcmp( psz_video_connection, "component" ) )
> 	            conn = bmdVideoConnectionComponent;
> 	        else if ( !strcmp( psz_video_connection, "composite" ) )
> 	            conn = bmdVideoConnectionComposite;
> 	        else if ( !strcmp( psz_video_connection, "svideo" ) )
> 	            conn = bmdVideoConnectionSVideo;
> 	        else
> 	        {
> 	            msg_Err( p_this, "Invalid video-connection specified; choose one of " \
> 	                              "sdi, hdmi, opticalsdi, component, composite, or svideo." );
> 	            if( decklink_sys.decklink_iterator )
> 	            	decklink_sys.decklink_iterator->Release();
>             	free( psz_video_connection );
>             	if( decklink_sys.p_display_iterator )
>             		decklink_sys.p_display_iterator->Release();
>             	vlc_mutex_unlock(&decklink_sys.m_lock);
>     	        return VLC_EGENERIC;

leaking psz_video_connection;
You probably need to do some common error path.

> 	        }
> 	        msg_Dbg( p_this, "Setting video output connection to 0x%x", conn);
> 	        result = decklink_sys.p_config->SetInt( bmdDeckLinkConfigVideoOutputConnection, conn );
> 	        if( result != S_OK )
> 	        {
> 	            msg_Err( p_this, "Failed to set video output connection" );
> 	            if( decklink_sys.decklink_iterator )
> 	            	decklink_sys.decklink_iterator->Release();
>             	free( psz_video_connection );
>             	if( decklink_sys.p_display_iterator )
>             		decklink_sys.p_display_iterator->Release();
>             	vlc_mutex_unlock(&decklink_sys.m_lock);
>     	        return VLC_EGENERIC;

idem

> 	        }
> 
> 	        decklink_sys.psz_video_connection = psz_video_connection;
> 	        free( psz_video_connection );
> 	    }
> 
> 	    //End of Setting up Video Connection
> 
> 
> 	    // Setting up Audio Connection
> 	    char *psz_audio_connection;
> 	    psz_audio_connection = var_CreateGetNonEmptyString( p_this, AUDIO_CFG_PREFIX "audio-connection" );
> 	    if( psz_audio_connection )
> 	    {
> 	        BMDAudioConnection conn;
> 	        if ( !strcmp( psz_audio_connection, "embedded" ) )
> 	            conn = bmdAudioConnectionEmbedded;
> 	        else if ( !strcmp( psz_audio_connection, "aesebu" ) )
> 	            conn = bmdAudioConnectionAESEBU;
> 	        else if ( !strcmp( psz_audio_connection, "analog" ) )
> 	            conn = bmdAudioConnectionAnalog;
> 	        else
> 	        {
> 	            msg_Err( p_this, "Invalid audio-connection specified; choose one of " \
> 	                              "embedded, aesebu, or analog." );
> 	            if( decklink_sys.decklink_iterator )
> 	            	decklink_sys.decklink_iterator->Release();
>             	free( psz_audio_connection );
>             	if( decklink_sys.p_display_iterator )
>             		decklink_sys.p_display_iterator->Release();
>             	vlc_mutex_unlock(&decklink_sys.m_lock);
>     	        return VLC_EGENERIC;

idem for psz_audio_connection

> 	        }
> 
> 	        msg_Dbg( p_this, "Setting audio output format to 0x%x", conn);
> 	        result = decklink_sys.p_config->SetInt( bmdDeckLinkConfigAudioInputConnection, conn );
> 	        if( result != S_OK )
> 	        {
> 	            msg_Err( p_this, "Failed to set audio output connection" );
> 	            if( decklink_sys.decklink_iterator )
> 	            	decklink_sys.decklink_iterator->Release();
>             	free( psz_audio_connection );
>             	if( decklink_sys.p_display_iterator )
>             		decklink_sys.p_display_iterator->Release();
>             	vlc_mutex_unlock(&decklink_sys.m_lock);
>     	        return VLC_EGENERIC;
> 	        }
> 
> 	        decklink_sys.psz_audio_connection = psz_audio_connection;
> 	        free( psz_audio_connection );
> 	    }
> 	    // End of Setting up Audio Connection
> 
> 	    //Find Display Mode
> 
> 	    result = decklink_sys.p_output->GetDisplayModeIterator( &decklink_sys.p_display_iterator );
> 	    if( result != S_OK )
> 	    {
> 	        msg_Err( p_this, "Failed to enumerate display modes" );
>             if( decklink_sys.decklink_iterator )
>             	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 
> 	    char        *psz_display_mode;
> 	    psz_display_mode = var_CreateGetNonEmptyString( p_this, VIDEO_CFG_PREFIX "mode" );
> 	    if( !psz_display_mode || strlen( psz_display_mode ) > 4 ) {
> 	        msg_Err( p_this, "Missing or invalid mode string" );
>             if( decklink_sys.decklink_iterator )
>             	decklink_sys.decklink_iterator->Release();
>         	if( decklink_sys.p_display_iterator )
>         		decklink_sys.p_display_iterator->Release();
>         	vlc_mutex_unlock(&decklink_sys.m_lock);
> 	        return VLC_EGENERIC;
> 	    }
> 
> 	    /*
> 	     * Pad the --decklink-mode string to four characters, so the user can specify e.g. "pal"
> 	     * without having to add the trailing space.
> 	     */
> 	    char sz_display_mode_padded[5];
> 	    strcpy(sz_display_mode_padded, "    ");

Ugly init

> 	    for( int i = 0; i < strlen( psz_display_mode ); ++i )
> 	        sz_display_mode_padded[i] = psz_display_mode[i];



Best Regards,

-- 
Jean-Baptiste Kempf
http://www.jbkempf.com/ - +33 672 704 734
Sent from my Electronic Device



More information about the vlc-devel mailing list