[vlc-commits] transcode: refactor fps conversion out from video transcode

Ilkka Ollakka git at videolan.org
Sun Nov 30 12:34:42 CET 2014


vlc | branch: master | Ilkka Ollakka <ileoo at videolan.org> | Sat Nov 29 23:47:19 2014 +0200| [62a5a151673cdc8fc1300d93789006cdbcdf8873] | committer: Ilkka Ollakka

transcode: refactor fps conversion out from video transcode

Use fps video filter for framerate conversion. Also do framerate conversion
after deinterlacer so we don't screw deinterlacing with frame dropping.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=62a5a151673cdc8fc1300d93789006cdbcdf8873
---

 modules/stream_out/transcode/transcode.h |    3 +-
 modules/stream_out/transcode/video.c     |  141 +++---------------------------
 2 files changed, 13 insertions(+), 131 deletions(-)

diff --git a/modules/stream_out/transcode/transcode.h b/modules/stream_out/transcode/transcode.h
index 66daca0..0dc0589 100644
--- a/modules/stream_out/transcode/transcode.h
+++ b/modules/stream_out/transcode/transcode.h
@@ -107,8 +107,7 @@ struct sout_stream_id_sys_t
     /* Sync */
     date_t          next_input_pts; /**< Incoming calculated PTS */
     date_t          next_output_pts; /**< output calculated PTS */
-    int             i_input_frame_interval;
-    int             i_output_frame_interval;
+
 };
 
 /* OSD */
diff --git a/modules/stream_out/transcode/video.c b/modules/stream_out/transcode/video.c
index d0ad9d5..79f9a81 100644
--- a/modules/stream_out/transcode/video.c
+++ b/modules/stream_out/transcode/video.c
@@ -288,6 +288,16 @@ static void transcode_video_filter_init( sout_stream_t *p_stream,
 
         p_fmt_out = filter_chain_GetFmtOut( id->p_f_chain );
     }
+    if( p_stream->p_sys->b_master_sync )
+    {
+        filter_chain_AppendFilter( id->p_f_chain,
+                                   "fps",
+                                   NULL,
+                                   p_fmt_out,
+                                   &id->p_encoder->fmt_in );
+
+        p_fmt_out = filter_chain_GetFmtOut( id->p_f_chain );
+    }
 
     /* Check that we have visible_width/height*/
     if( !p_fmt_out->video.i_visible_height )
@@ -513,21 +523,6 @@ static void transcode_video_encoder_init( sout_stream_t *p_stream,
         id->p_encoder->fmt_in.video.i_frame_rate,
         id->p_encoder->fmt_in.video.i_frame_rate_base );
 
-    id->i_input_frame_interval  = id->p_decoder->fmt_out.video.i_frame_rate_base * CLOCK_FREQ / id->p_decoder->fmt_out.video.i_frame_rate;
-    msg_Info( p_stream, "input interval %d (base %d)",
-                        id->i_input_frame_interval, id->p_decoder->fmt_out.video.i_frame_rate_base );
-
-    id->i_output_frame_interval = id->p_encoder->fmt_in.video.i_frame_rate_base * CLOCK_FREQ / id->p_encoder->fmt_in.video.i_frame_rate;
-    msg_Info( p_stream, "output interval %d (base %d)",
-                        id->i_output_frame_interval, id->p_encoder->fmt_in.video.i_frame_rate_base );
-
-    date_Init( &id->next_input_pts,
-               id->p_decoder->fmt_out.video.i_frame_rate,
-               1 );
-
-    date_Init( &id->next_output_pts,
-               id->p_encoder->fmt_in.video.i_frame_rate,
-               1 );
 
     /* Check whether a particular aspect ratio was requested */
     if( id->p_encoder->fmt_out.video.i_sar_num <= 0 ||
@@ -633,51 +628,10 @@ void transcode_video_close( sout_stream_t *p_stream,
         filter_chain_Delete( id->p_uf_chain );
 }
 
-static picture_t* check_picture_drop( sout_stream_id_sys_t *id, picture_t *input_pic) {
-    /* If input pts lower than next_output_pts - output_frame_interval Then the
-     * future input frame should fit better and we can drop this one
-     *
-     * We check this here as we don't need to run user defined video filter at
-     * all for pictures we are going to drop anyway
-     *
-     * Duplication need is checked in OutputFrame */
-
-    if( ( input_pic->date ) <
-        ( date_Get( &id->next_output_pts ) - (mtime_t)id->i_output_frame_interval ) )
-    {
-#if 0
-        msg_Dbg( p_stream, "dropping frame (%"PRId64" + %"PRId64" vs %"PRId64")",
-                 p_pic->date, id->i_input_frame_interval, date_Get(&id->next_output_pts) );
-#endif
-        picture_Release( input_pic );
-        return NULL;
-    }
-    return input_pic;
-}
-
 static void OutputFrame( sout_stream_t *p_stream, picture_t *p_pic, sout_stream_id_sys_t *id, block_t **out )
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
     picture_t *p_pic2 = NULL;
-    const mtime_t original_date = p_pic->date;
-    bool b_need_duplicate=false;
-    /* If input pts is lower than next_output_pts - output_frame_interval
-     * Then the future input frame should fit better and we can drop this one 
-     *
-     * We check it here also because we can have case that video filters outputs multiple
-     * pictures but we don't need to use them all, for example yadif2x and outputting to some
-     * different fps value
-     */
-    if( ( original_date ) <
-        ( date_Get( &id->next_output_pts ) - (mtime_t)id->i_output_frame_interval ) )
-    {
-#if 0
-        msg_Dbg( p_stream, "dropping frame (%"PRId64" + %"PRId64" vs %"PRId64")",
-                 p_pic->date, id->i_input_frame_interval, date_Get(&id->next_output_pts) );
-#endif
-        picture_Release( p_pic );
-        return;
-    }
 
     /*
      * Encoding
@@ -720,11 +674,6 @@ static void OutputFrame( sout_stream_t *p_stream, picture_t *p_pic, sout_stream_
         }
     }
 
-    /* set output pts*/
-    p_pic->date = date_Get( &id->next_output_pts );
-    /*This pts is handled, increase clock to next one*/
-    date_Increment( &id->next_output_pts, id->p_encoder->fmt_in.video.i_frame_rate_base );
-
     if( p_sys->i_threads == 0 )
     {
         block_t *p_block;
@@ -733,56 +682,14 @@ static void OutputFrame( sout_stream_t *p_stream, picture_t *p_pic, sout_stream_
         block_ChainAppend( out, p_block );
     }
 
-    /* we need to duplicate while next_output_pts + output_frame_interval < input_pts (next input pts)*/
-    b_need_duplicate = ( date_Get( &id->next_output_pts ) + id->i_output_frame_interval ) <
-                       ( original_date );
-
     if( p_sys->i_threads )
     {
-        if( p_sys->b_master_sync )
-        {
-            p_pic2 = video_new_buffer_encoder( id->p_encoder );
-            if( likely( p_pic2 != NULL ) )
-                picture_Copy( p_pic2, p_pic );
-        }
         vlc_mutex_lock( &p_sys->lock_out );
         picture_fifo_Push( p_sys->pp_pics, p_pic );
         vlc_cond_signal( &p_sys->cond );
         vlc_mutex_unlock( &p_sys->lock_out );
     }
 
-    while( (p_sys->b_master_sync && b_need_duplicate ))
-    {
-        if( p_sys->i_threads >= 1 )
-        {
-            picture_t *p_tmp = NULL;
-            /* We can't modify the picture, we need to duplicate it */
-            p_tmp = video_new_buffer_encoder( id->p_encoder );
-            if( likely( p_tmp != NULL ) )
-            {
-                picture_Copy( p_tmp, p_pic2 );
-                p_tmp->date = date_Get( &id->next_output_pts );
-                vlc_mutex_lock( &p_sys->lock_out );
-                picture_fifo_Push( p_sys->pp_pics, p_tmp );
-                vlc_cond_signal( &p_sys->cond );
-                vlc_mutex_unlock( &p_sys->lock_out );
-            }
-        }
-        else
-        {
-            block_t *p_block;
-            p_pic->date = date_Get( &id->next_output_pts );
-            p_block = id->p_encoder->pf_encode_video(id->p_encoder, p_pic);
-            block_ChainAppend( out, p_block );
-        }
-#if 0
-        msg_Dbg( p_stream, "duplicated frame");
-#endif
-        date_Increment( &id->next_output_pts, id->p_encoder->fmt_in.video.i_frame_rate_base );
-        b_need_duplicate = ( date_Get( &id->next_output_pts ) + id->i_output_frame_interval ) <
-                           ( original_date );
-    }
-
     if( p_sys->i_threads && p_pic2 )
         picture_Release( p_pic2 );
     else if ( p_sys->i_threads == 0 )
@@ -879,23 +786,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
                 id->b_transcode = false;
                 return VLC_EGENERIC;
             }
-            date_Set( &id->next_output_pts, p_pic->date );
-            date_Set( &id->next_input_pts, p_pic->date );
-        }
-
-        /* Check input drift regardless, if it's more than 100ms from our approximation, we most likely have lost pictures
-         * and are in danger to become out of sync, so better reset timestamps then */
-        if( likely( p_pic->date != VLC_TS_INVALID ) )
-        {
-            mtime_t input_drift = p_pic->date - date_Get( &id->next_input_pts );
-            if( unlikely( (input_drift > (CLOCK_FREQ/10)) ||
-                          (input_drift < -(CLOCK_FREQ/10))
-               ) )
-            {
-                msg_Warn( p_stream, "Reseting video sync" );
-                date_Set( &id->next_output_pts, p_pic->date );
-                date_Set( &id->next_input_pts, p_pic->date );
-            }
         }
 
         /* Run the filter and output chains; first with the picture,
@@ -911,12 +801,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
             if( !p_filtered_pic )
                 break;
 
-            /*drop check. We do it here because we want to feed all frames to deinterlacer */
-            if( p_sys->b_master_sync )
-                p_filtered_pic = check_picture_drop( id, p_filtered_pic );
-            if( !p_filtered_pic )
-                break;
-
             for ( ;; ) {
                 picture_t *p_user_filtered_pic = p_filtered_pic;
 
@@ -933,7 +817,6 @@ int transcode_video_process( sout_stream_t *p_stream, sout_stream_id_sys_t *id,
 
             p_pic = NULL;
         }
-        date_Increment( &id->next_input_pts, id->p_decoder->fmt_out.video.i_frame_rate_base );
     }
 
     if( p_sys->i_threads >= 1 )
@@ -976,8 +859,8 @@ bool transcode_video_add( sout_stream_t *p_stream, es_format_t *p_fmt,
 
     if( p_sys->fps_num )
     {
-        id->p_encoder->fmt_out.video.i_frame_rate = (p_sys->fps_num );
-        id->p_encoder->fmt_out.video.i_frame_rate_base = (p_sys->fps_den ? p_sys->fps_den : 1);
+        id->p_encoder->fmt_in.video.i_frame_rate = id->p_encoder->fmt_out.video.i_frame_rate = (p_sys->fps_num );
+        id->p_encoder->fmt_in.video.i_frame_rate_base = id->p_encoder->fmt_out.video.i_frame_rate_base = (p_sys->fps_den ? p_sys->fps_den : 1);
     }
 
     return true;



More information about the vlc-commits mailing list