]> git.sesse.net Git - vlc/blobdiff - modules/access/sdi.cpp
Do a more proper fix (with symbolic constants) for i_pts.
[vlc] / modules / access / sdi.cpp
index 51937e2ec9f921152de40b51c6cac4c5a190bef8..d31ed17068556997845b721ab6d2607d0e344269 100644 (file)
@@ -54,8 +54,9 @@ struct demux_sys_t
     DeckLinkCaptureDelegate *p_delegate;
     es_out_id_t  *p_es;
 
-    vlc_mutex_t lock;
-    block_t *p_frame;  // protected by <lock>
+    vlc_mutex_t frame_lock;
+    block_t *p_frame;  // protected by <frame_lock>
+    vlc_cond_t has_frame;  // related to <frame_lock>
 };
 
 class DeckLinkCaptureDelegate : public IDeckLinkInputCallback
@@ -85,32 +86,34 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
 {
     demux_sys_t *p_sys = p_demux_->p_sys;
 
-    if (videoFrame) {
-        if (videoFrame->GetFlags() & bmdFrameHasNoInputSource) {
+    if(videoFrame)
+    {
+        if(videoFrame->GetFlags() & bmdFrameHasNoInputSource)
+        {
             msg_Warn( p_demux_, "No input signal detected" );
             return S_OK;
         }
 
-        msg_Dbg( p_demux_, "Received a frame" );
-
         block_t *p_frame;
-       p_frame = block_New( p_demux_, 720 * 576 * 3 );
-        if ( !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;
+        videoFrame->GetStreamTime( &stream_time, &frame_duration, CLOCK_FREQ );
+        p_frame->i_pts = VLC_TS_0 + stream_time;
 
-        vlc_mutex_lock( &p_sys->lock );
-       p_sys->p_frame = p_frame;  // FIXME: leak
-        vlc_mutex_unlock( &p_sys->lock );
+        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;
@@ -135,11 +138,13 @@ static int Open( vlc_object_t *p_this )
     if( !p_sys )
         return VLC_ENOMEM;
 
-    vlc_mutex_init( &p_sys->lock );
+    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;
@@ -148,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;
     }
@@ -162,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 );
@@ -236,19 +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 );
 
-    vlc_mutex_lock( &p_sys->lock );
-    block_t *p_block = p_sys->p_frame;
+    p_block = p_sys->p_frame;
     p_sys->p_frame = NULL;
-    vlc_mutex_unlock( &p_sys->lock );
-
-    if ( p_block ) {
-        msg_Dbg( p_demux, "Sending frame" ); 
-        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 );
-    } else {
-        usleep(50000);  // FIXME
-    }
+
+    vlc_mutex_unlock( &p_sys->frame_lock );
+
+    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;
 }