X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Faccess%2Fsdi.cpp;h=201af4ac17f03b522f600251c7059c82aa6ea541;hb=747e352af447e8693524965c81581e5145be85f2;hp=8b405ee3d71eb665a4325826dea18287d1f64618;hpb=7feb1ed4d07a586f4b4e796421f0ae87843c51d1;p=vlc diff --git a/modules/access/sdi.cpp b/modules/access/sdi.cpp index 8b405ee3d7..201af4ac17 100644 --- a/modules/access/sdi.cpp +++ b/modules/access/sdi.cpp @@ -53,6 +53,10 @@ struct demux_sys_t IDeckLinkInput *p_input; DeckLinkCaptureDelegate *p_delegate; es_out_id_t *p_es; + + vlc_mutex_t frame_lock; + block_t *p_frame; // protected by + vlc_cond_t has_frame; // related to }; class DeckLinkCaptureDelegate : public IDeckLinkInputCallback @@ -80,7 +84,38 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFormatChanged(BMDVideoInputFormatChan HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame* videoFrame, IDeckLinkAudioInputPacket* audioFrame) { - msg_Dbg( p_demux_, "Received a frame" ); + demux_sys_t *p_sys = p_demux_->p_sys; + + if(videoFrame) + { + if(videoFrame->GetFlags() & bmdFrameHasNoInputSource) + { + msg_Warn( p_demux_, "No input signal detected" ); + return S_OK; + } + + block_t *p_frame; + p_frame = block_New( p_demux_, 720 * 576 * 3 ); + if( !p_frame ) + { + msg_Err( p_demux_, "Could not allocate memory for frame" ); + return S_OK; + } + + void *frame_bytes; + videoFrame->GetBytes( &frame_bytes ); + memcpy( p_frame->p_buffer, frame_bytes, 720 * 576 * 3 ); + + BMDTimeValue stream_time, frame_duration; + videoFrame->GetStreamTime( &stream_time, &frame_duration, 1000000 ); + p_frame->i_pts = stream_time + frame_duration; // FIXME: hack to avoid i_pts=0? + + vlc_mutex_lock( &p_sys->frame_lock ); + p_sys->p_frame = p_frame; // FIXME: leak + vlc_cond_signal( &p_sys->has_frame ); + vlc_mutex_unlock( &p_sys->frame_lock ); + } + return S_OK; } @@ -103,10 +138,13 @@ static int Open( vlc_object_t *p_this ) if( !p_sys ) return VLC_ENOMEM; - msg_Dbg( p_demux, "hello world" ); + vlc_mutex_init( &p_sys->frame_lock ); + vlc_cond_init( &p_sys->has_frame ); + p_sys->p_frame = NULL; IDeckLinkIterator *decklink_iterator = CreateDeckLinkIteratorInstance(); - if ( !decklink_iterator ) { + if( !decklink_iterator ) + { msg_Err( p_demux, "DeckLink drivers not found." ); // FIXME: Leak here and several other error paths. return VLC_EGENERIC; @@ -115,12 +153,14 @@ static int Open( vlc_object_t *p_this ) HRESULT result; result = decklink_iterator->Next( &p_sys->p_card ); - if ( result != S_OK ) { + if( result != S_OK ) + { msg_Err( p_demux, "No DeckLink PCI cards found" ); return VLC_EGENERIC; } - if ( p_sys->p_card->QueryInterface(IID_IDeckLinkInput, (void**)&p_sys->p_input) != S_OK ) { + if( p_sys->p_card->QueryInterface(IID_IDeckLinkInput, (void**)&p_sys->p_input) != S_OK ) + { msg_Err( p_demux, "Card has no inputs" ); return VLC_EGENERIC; } @@ -129,25 +169,29 @@ static int Open( vlc_object_t *p_this ) p_sys->p_input->SetCallback( p_sys->p_delegate ); result = p_sys->p_input->EnableVideoInput(bmdModePAL, bmdFormat8BitYUV, 0); - if ( result != S_OK ) { + if( result != S_OK ) + { msg_Err( p_demux, "Failed to enable video input" ); return VLC_EGENERIC; } // FIXME: add audio result = p_sys->p_input->StartStreams(); - if ( result != S_OK ) { + if( result != S_OK ) + { msg_Err( p_demux, "Failed to start streams" ); return VLC_EGENERIC; } /*eDeclare elementary streams */ es_format_t fmt; - es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_YUYV ); + es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_UYVY ); fmt.video.i_width = 720; fmt.video.i_height = 576; - fmt.video.i_sar_num = 1; - fmt.video.i_sar_den = 1; + fmt.video.i_sar_num = 16 * fmt.video.i_height; + fmt.video.i_sar_den = 9 * fmt.video.i_width; + fmt.video.i_frame_rate = 25; + fmt.video.i_frame_rate_base = 1; msg_Dbg( p_demux, "added new video es %4.4s %dx%d", (char*)&fmt.i_codec, fmt.video.i_width, fmt.video.i_height ); @@ -203,8 +247,20 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) static int Demux( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; + block_t *p_block; + + vlc_mutex_lock( &p_sys->frame_lock ); + + while( !p_sys->p_frame ) + vlc_cond_wait( &p_sys->has_frame, &p_sys->frame_lock ); + + p_block = p_sys->p_frame; + p_sys->p_frame = NULL; + + vlc_mutex_unlock( &p_sys->frame_lock ); - // FIXME + es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); + es_out_Send( p_demux->out, p_sys->p_es, p_block ); return 1; }