[vlc-commits] demux: h26x: rewrite output dts

Francois Cartegnie git at videolan.org
Tue Mar 23 23:18:31 UTC 2021


vlc/vlc-3.0 | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Tue Mar 23 18:35:40 2021 +0100| [989c616b1a479edb9ee73d836aa066a681d6906f] | committer: Francois Cartegnie

demux: h26x: rewrite output dts

fed dts is always bogus as it can't match AU boundaries

(cherry picked from commit dcca36793a58776a5cf48ece3dd9a574d75123e0)

> http://git.videolan.org/gitweb.cgi/vlc/vlc-3.0.git/?a=commit;h=989c616b1a479edb9ee73d836aa066a681d6906f
---

 modules/demux/mpeg/h26x.c | 72 +++++++++++++++++++++++++++++++----------------
 1 file changed, 47 insertions(+), 25 deletions(-)

diff --git a/modules/demux/mpeg/h26x.c b/modules/demux/mpeg/h26x.c
index a43b27aef9..77146bbe48 100644
--- a/modules/demux/mpeg/h26x.c
+++ b/modules/demux/mpeg/h26x.c
@@ -77,7 +77,8 @@ struct demux_sys_t
 {
     es_out_id_t *p_es;
 
-    date_t      dts;
+    date_t      feed_dts;
+    date_t      output_dts;
     unsigned    frame_rate_num;
     unsigned    frame_rate_den;
 
@@ -346,18 +347,19 @@ static int GenericOpen( demux_t *p_demux, const char *psz_module,
         if ( f_fps < 0.001f ) f_fps = 0.001f;
         p_sys->frame_rate_den = 1000;
         p_sys->frame_rate_num = 1000 * f_fps;
-        date_Init( &p_sys->dts, 2 * p_sys->frame_rate_num, p_sys->frame_rate_den );
+        date_Init( &p_sys->feed_dts, 2 * p_sys->frame_rate_num, p_sys->frame_rate_den );
     }
     else
-        date_Init( &p_sys->dts, 2 * 30000, 1000 );
-    date_Set( &p_sys->dts, VLC_TS_0 );
+        date_Init( &p_sys->feed_dts, 25000, 1000 );
+    date_Set( &p_sys->feed_dts, VLC_TS_0 );
+    p_sys->output_dts = p_sys->feed_dts;
 
     /* Load the mpegvideo packetizer */
     es_format_Init( &fmt, VIDEO_ES, i_codec );
     if( f_fps )
     {
-        fmt.video.i_frame_rate = p_sys->dts.i_divider_num >> 1;
-        fmt.video.i_frame_rate_base = p_sys->dts.i_divider_den;
+        fmt.video.i_frame_rate = p_sys->feed_dts.i_divider_num >> 1;
+        fmt.video.i_frame_rate_base = p_sys->feed_dts.i_divider_den;
     }
     p_sys->p_packetizer = demux_PacketizerNew( p_demux, &fmt, psz_module );
     if( !p_sys->p_packetizer )
@@ -422,7 +424,7 @@ static int Demux( demux_t *p_demux)
     }
     else
     {
-        p_block_in->i_dts = date_Get( &p_sys->dts );
+        p_block_in->i_dts = date_Get( &p_sys->feed_dts );
     }
 
     while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer,
@@ -431,12 +433,35 @@ static int Demux( demux_t *p_demux)
         while( p_block_out )
         {
             block_t *p_next = p_block_out->p_next;
-
             p_block_out->p_next = NULL;
 
+            if( p_sys->p_packetizer->fmt_out.video.i_frame_rate_base &&
+                p_sys->p_packetizer->fmt_out.video.i_frame_rate_base != p_sys->frame_rate_den &&
+                p_sys->p_packetizer->fmt_out.video.i_frame_rate &&
+                p_sys->p_packetizer->fmt_out.video.i_frame_rate_base != p_sys->frame_rate_num )
+            {
+                p_sys->frame_rate_num = p_sys->p_packetizer->fmt_out.video.i_frame_rate;
+                p_sys->frame_rate_den = p_sys->p_packetizer->fmt_out.video.i_frame_rate_base;
+                date_Change( &p_sys->feed_dts, 2 * p_sys->frame_rate_num, p_sys->frame_rate_den );
+                date_Change( &p_sys->output_dts, 2 * p_sys->frame_rate_num, p_sys->frame_rate_den );
+                msg_Dbg( p_demux, "using %.2f fps", (double) p_sys->frame_rate_num / p_sys->frame_rate_den );
+            }
+
+            /* we only want to use the pts-dts offset and length from packetizer */
+            mtime_t dtsdiff = p_block_out->i_pts > p_block_out->i_dts
+                            ? p_block_out->i_pts - p_block_out->i_dts
+                            : 0;
+            /* Always start frame N=1 so we get PCR on N=0 */
+            date_t dtsdate = p_sys->output_dts;
+            mtime_t dts = date_Increment( &dtsdate, 2 );
+
+            p_block_out->i_dts = dts;
+            if( p_block_out->i_pts != VLC_TS_INVALID )
+                p_block_out->i_pts = dts + dtsdiff;
+
             if( p_block_in )
             {
-                p_block_in->i_dts = date_Get( &p_sys->dts );
+                p_block_in->i_dts = date_Get( &p_sys->feed_dts );
                 p_block_in->i_pts = VLC_TS_INVALID;
             }
 
@@ -453,23 +478,18 @@ static int Demux( demux_t *p_demux)
 
             /* h264 packetizer does merge multiple NAL into AU, but slice flag persists */
             bool frame = p_block_out->i_flags & BLOCK_FLAG_TYPE_MASK;
-            const mtime_t i_frame_dts = p_block_out->i_dts;
             const mtime_t i_frame_length = p_block_out->i_length;
+
+            /* first output */
+            if( date_Get( &p_sys->output_dts ) == VLC_TS_0 )
+                es_out_SetPCR( p_demux->out, date_Get( &p_sys->output_dts ) );
+
             es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
+
+            mtime_t pcr = b_eof ? dts : date_Get( &p_sys->output_dts );
+
             if( frame )
             {
-                if( p_sys->p_packetizer->fmt_out.video.i_frame_rate_base &&
-                    p_sys->p_packetizer->fmt_out.video.i_frame_rate_base != p_sys->frame_rate_den &&
-                    p_sys->p_packetizer->fmt_out.video.i_frame_rate &&
-                    p_sys->p_packetizer->fmt_out.video.i_frame_rate_base != p_sys->frame_rate_num )
-                {
-                    p_sys->frame_rate_num = p_sys->p_packetizer->fmt_out.video.i_frame_rate;
-                    p_sys->frame_rate_den = p_sys->p_packetizer->fmt_out.video.i_frame_rate_base;
-                    date_Change( &p_sys->dts, 2 * p_sys->frame_rate_num, p_sys->frame_rate_den );
-                    msg_Dbg( p_demux, "using %.2f fps", (double) p_sys->frame_rate_num / p_sys->frame_rate_den );
-                }
-
-                es_out_SetPCR( p_demux->out, date_Get( &p_sys->dts ) );
                 unsigned i_nb_fields;
                 if( i_frame_length > 0 )
                 {
@@ -478,11 +498,13 @@ static int Demux( demux_t *p_demux)
                 }
                 else i_nb_fields = 2;
                 if( i_nb_fields <= 6 ) /* in the legit range */
-                    date_Increment( &p_sys->dts, i_nb_fields );
-                else /* Somehow some discontinuity */
-                    date_Set( &p_sys->dts, i_frame_dts );
+                {
+                    date_Increment( &p_sys->output_dts, i_nb_fields );
+                }
             }
 
+            es_out_SetPCR( p_demux->out, pcr );
+
             p_block_out = p_next;
         }
     }



More information about the vlc-commits mailing list