X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fsdi.cpp;h=9c6946e950a319b2d88e5a5fed55160d168bf6d9;hb=c9665c24d178c33a4736f90e68c8ca0f2350024e;hp=a937ae18ed24d3243c782ed1e536724e9d156199;hpb=6da459431abbea07af556699a251673a706ca584;p=vlc diff --git a/modules/access/sdi.cpp b/modules/access/sdi.cpp index a937ae18ed..9c6946e950 100644 --- a/modules/access/sdi.cpp +++ b/modules/access/sdi.cpp @@ -1,4 +1,4 @@ -/* BlackMagic SDI driver */ +/* Blackmagic SDI driver */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -16,11 +16,12 @@ #include #include #include +#include #include -#include "DeckLinkAPI.h" -#include "DeckLinkAPIDispatch.cpp" +#include +#include static int Open ( vlc_object_t * ); static void Close( vlc_object_t * ); @@ -70,10 +71,10 @@ static void Close( vlc_object_t * ); vlc_module_begin () set_shortname( N_("SDI") ) - set_description( N_("BlackMagic SDI input") ) + set_description( N_("Blackmagic SDI input") ) set_category( CAT_INPUT ) set_subcategory( SUBCAT_INPUT_ACCESS ) - + add_integer( "sdi-card-index", 0, NULL, CARD_INDEX_TEXT, CARD_INDEX_LONGTEXT, true ) add_string( "sdi-mode", "pal ", NULL, @@ -126,38 +127,37 @@ struct demux_sys_t class DeckLinkCaptureDelegate : public IDeckLinkInputCallback { public: - DeckLinkCaptureDelegate( demux_t *p_demux ) : m_ref_(1), p_demux_(p_demux) {} + DeckLinkCaptureDelegate( demux_t *p_demux ) : p_demux_(p_demux) + { + vlc_atomic_set( &m_ref_, 1 ); + } virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, LPVOID *ppv) { return E_NOINTERFACE; } - /* Note: AddRef() and Release() here are not thread safe. */ - virtual ULONG STDMETHODCALLTYPE AddRef(void) { - return ++m_ref_; + return vlc_atomic_inc( &m_ref_ ); } virtual ULONG STDMETHODCALLTYPE Release(void) { - if ( --m_ref_ == 0 ) - { + uintptr_t new_ref = vlc_atomic_dec( &m_ref_ ); + if ( new_ref == 0 ) delete this; - return 0; - } - return m_ref_; + return new_ref; } virtual HRESULT STDMETHODCALLTYPE VideoInputFormatChanged(BMDVideoInputFormatChangedEvents, IDeckLinkDisplayMode*, BMDDetectedVideoInputFormatFlags); virtual HRESULT STDMETHODCALLTYPE VideoInputFrameArrived(IDeckLinkVideoInputFrame*, IDeckLinkAudioInputPacket*); private: - int m_ref_; + vlc_atomic_t m_ref_; demux_t *p_demux_; }; HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChangedEvents events, IDeckLinkDisplayMode *mode, BMDDetectedVideoInputFormatFlags) { - msg_Dbg( p_demux_, "Video input format changed" ); + msg_Dbg( p_demux_, "Video input format changed" ); return S_OK; } @@ -206,7 +206,7 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame } p_video_frame->i_pts = p_video_frame->i_dts = VLC_TS_0 + stream_time; } - + if( audioFrame ) { const int i_bytes = audioFrame->GetSampleFrameCount() * sizeof(int16_t) * p_sys->i_channels; @@ -215,6 +215,8 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame if( !p_audio_frame ) { msg_Err( p_demux_, "Could not allocate memory for audio frame" ); + if( p_video_frame ) + block_Release( p_video_frame ); return S_OK; } @@ -270,7 +272,7 @@ static int Open( vlc_object_t *p_this ) vlc_mutex_init( &p_sys->frame_lock ); vlc_cond_init( &p_sys->has_frame ); - p_sys->p_video_frame = NULL; + p_sys->b_first_frame = true; IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); if( !decklink_iterator ) @@ -304,7 +306,7 @@ static int Open( vlc_object_t *p_this ) const char *psz_model_name; result = p_sys->p_card->GetModelName( &psz_model_name ); - + if( result != S_OK ) { msg_Err( p_demux, "Could not get model name" ); @@ -320,7 +322,7 @@ static int Open( vlc_object_t *p_this ) Close( p_this ); return VLC_EGENERIC; } - + /* Set up the video and audio sources. */ IDeckLinkConfiguration *p_config; if( p_sys->p_card->QueryInterface( IID_IDeckLinkConfiguration, (void**)&p_config) != S_OK ) @@ -329,7 +331,7 @@ static int Open( vlc_object_t *p_this ) Close( p_this ); return VLC_EGENERIC; } - + char *psz_tmp = var_CreateGetNonEmptyString( p_demux, "sdi-video-connection" ); if( psz_tmp ) { @@ -366,7 +368,7 @@ static int Open( vlc_object_t *p_this ) Close( p_this ); return VLC_EGENERIC; } - } + } psz_tmp = var_CreateGetNonEmptyString( p_demux, "sdi-audio-connection" ); if( psz_tmp ) @@ -412,7 +414,7 @@ static int Open( vlc_object_t *p_this ) Close( p_this ); return VLC_EGENERIC; } - + char *psz_display_mode = var_CreateGetString( p_demux, "sdi-mode" ); if( !psz_display_mode || strlen( psz_display_mode ) == 0 || strlen( psz_display_mode ) > 4 ) { msg_Err( p_demux, "Missing or invalid --sdi-mode string" ); @@ -430,12 +432,12 @@ static int Open( vlc_object_t *p_this ) strcpy(sz_display_mode_padded, " "); for( int i = 0; i < strlen( psz_display_mode ); ++i ) sz_display_mode_padded[i] = psz_display_mode[i]; - + free( psz_display_mode ); BMDDisplayMode wanted_mode_id; memcpy( &wanted_mode_id, &sz_display_mode_padded, sizeof(wanted_mode_id) ); - + bool b_found_mode = false; for (;;) @@ -443,7 +445,7 @@ static int Open( vlc_object_t *p_this ) IDeckLinkDisplayMode *p_display_mode; result = p_display_iterator->Next( &p_display_mode ); if( result != S_OK || !p_display_mode ) - break; + break; char sz_mode_id_text[5] = {0}; BMDDisplayMode mode_id = ntohl( p_display_mode->GetDisplayMode() ); @@ -531,7 +533,7 @@ static int Open( vlc_object_t *p_this ) Close( p_this ); return VLC_EGENERIC; } - + /* Set up audio. */ p_sys->i_rate = var_CreateGetInteger( p_demux, "sdi-audio-rate" ); p_sys->i_channels = var_CreateGetInteger( p_demux, "sdi-audio-channels" ); @@ -545,7 +547,7 @@ static int Open( vlc_object_t *p_this ) return VLC_EGENERIC; } } - + p_sys->p_delegate = new DeckLinkCaptureDelegate( p_demux ); p_sys->p_input->SetCallback( p_sys->p_delegate ); @@ -567,7 +569,7 @@ static int Open( vlc_object_t *p_this ) video_fmt.video.i_frame_rate = p_sys->i_fps_num; video_fmt.video.i_frame_rate_base = p_sys->i_fps_den; video_fmt.i_bitrate = video_fmt.video.i_width * video_fmt.video.i_height * video_fmt.video.i_frame_rate * 2 * 8; - + psz_tmp = var_CreateGetNonEmptyString( p_demux, "sdi-aspect-ratio" ); if( psz_tmp ) { @@ -584,7 +586,7 @@ static int Open( vlc_object_t *p_this ) msg_Dbg( p_demux, "added new video es %4.4s %dx%d", (char*)&video_fmt.i_codec, video_fmt.video.i_width, video_fmt.video.i_height ); p_sys->p_video_es = es_out_Add( p_demux->out, &video_fmt ); - + es_format_t audio_fmt; es_format_Init( &audio_fmt, AUDIO_ES, VLC_CODEC_S16N ); audio_fmt.audio.i_channels = p_sys->i_channels; @@ -597,8 +599,6 @@ static int Open( vlc_object_t *p_this ) (char*)&audio_fmt.i_codec, audio_fmt.audio.i_rate, audio_fmt.audio.i_bitspersample, audio_fmt.audio.i_channels); p_sys->p_audio_es = es_out_Add( p_demux->out, &audio_fmt ); - p_sys->b_first_frame = true; - /* Update default_pts to a suitable value for access */ var_Create( p_demux, "sdi-caching", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); @@ -622,6 +622,12 @@ static void Close( vlc_object_t *p_this ) if( p_sys->p_delegate ) p_sys->p_delegate->Release(); + if( p_sys->p_video_frame ) + block_Release( p_sys->p_video_frame ); + + if( p_sys->p_audio_frame ) + block_Release( p_sys->p_audio_frame ); + free( p_sys ); } @@ -685,7 +691,7 @@ static int Demux( demux_t *p_demux ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_video_block->i_pts ); es_out_Send( p_demux->out, p_sys->p_video_es, p_video_block ); } - + if( p_audio_block ) { if( p_audio_block->i_pts > p_sys->i_last_pts )