[vlc-devel] [PATCH 03/13] es_out: add the ES_OUT_SET_FIRST_PCR control

Thomas Guillem thomas at gllm.fr
Wed Aug 21 16:13:54 CEST 2019


This control will send this first pcr to the main clock and will be used for
clock update notification.

Only the ts module need this control for now. Indeed, this is the only one that
is sending absolute ts.

In order to check if a module need this control, one should check the
DEMUX_GET_TIME implementation for a subtraction with a first_pcr member.
---
 include/vlc_es_out.h         |  4 ++++
 src/input/es_out.c           | 35 +++++++++++++++++++++++++++++++++++
 src/input/es_out_timeshift.c |  6 ++++++
 3 files changed, 45 insertions(+)

diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
index 8ee4ef0be1..3ca7ae96a0 100644
--- a/include/vlc_es_out.h
+++ b/include/vlc_es_out.h
@@ -64,6 +64,10 @@ enum es_out_query_e
     ES_OUT_SET_GROUP_PCR,       /* arg1= int i_group, arg2=vlc_tick_t i_pcr(microsecond!)*/
     ES_OUT_RESET_PCR,           /* no arg */
 
+    /* A demux module can set the first PCR if it is different than zero */
+    ES_OUT_SET_FIRST_PCR,       /* arg1=vlc_tick_t i_first_pcr (using default group 0) */
+    ES_OUT_SET_FIRST_GROUP_PCR, /* arg1= int i_group, arg2=vlc_tick_t i_first_pcr*/
+
     /* This will update the fmt, drain and restart the decoder (if any).
      * The new fmt must have the same i_cat and i_id. */
     ES_OUT_SET_ES_FMT,         /* arg1= es_out_id_t* arg2=es_format_t* res=can fail */
diff --git a/src/input/es_out.c b/src/input/es_out.c
index 0ea21d9fa6..2db2fa7d2c 100644
--- a/src/input/es_out.c
+++ b/src/input/es_out.c
@@ -75,6 +75,8 @@ typedef struct
     vlc_clock_main_t *p_main_clock;
     vlc_clock_t      *p_master_clock;
 
+    vlc_tick_t        i_first_pcr;
+
     vlc_meta_t *p_meta;
     struct vlc_list node;
 } es_out_pgrm_t;
@@ -1332,6 +1334,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group )
     p_pgrm->b_selected = false;
     p_pgrm->b_scrambled = false;
     p_pgrm->p_meta = NULL;
+    p_pgrm->i_first_pcr = 0;
 
     p_pgrm->p_master_clock = NULL;
     p_pgrm->p_input_clock = input_clock_New( p_sys->rate );
@@ -3061,6 +3064,38 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
         EsOutChangePosition( out, true );
         return VLC_SUCCESS;
 
+    case ES_OUT_SET_FIRST_PCR:
+    case ES_OUT_SET_FIRST_GROUP_PCR:
+    {
+        es_out_pgrm_t *p_pgrm = NULL;
+        int            i_group = 0;
+        vlc_tick_t     i_pcr;
+
+        /* Search program */
+        if( i_query == ES_OUT_SET_FIRST_PCR )
+        {
+            p_pgrm = p_sys->p_pgrm;
+            if( !p_pgrm )
+                p_pgrm = EsOutProgramAdd( out, i_group );   /* Create it */
+        }
+        else
+        {
+            i_group = va_arg( args, int );
+            p_pgrm = EsOutProgramFind( out, i_group );
+        }
+        if( !p_pgrm )
+            return VLC_EGENERIC;
+
+        i_pcr = va_arg( args, vlc_tick_t );
+        if( i_pcr == VLC_TICK_INVALID )
+        {
+            msg_Err( p_sys->p_input, "Invalid FIRST PCR value in ES_OUT_SET_(GROUP_)PCR !" );
+            return VLC_EGENERIC;
+        }
+        vlc_clock_main_SetFirstPcr(p_pgrm->p_main_clock, i_pcr);
+        return VLC_SUCCESS;
+    }
+
     case ES_OUT_SET_GROUP:
     {
         int i = va_arg( args, int );
diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
index 2fd8855251..ee69eace8c 100644
--- a/src/input/es_out_timeshift.c
+++ b/src/input/es_out_timeshift.c
@@ -607,6 +607,8 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
     case ES_OUT_SET_PCR:
     case ES_OUT_SET_GROUP_PCR:
     case ES_OUT_RESET_PCR:
+    case ES_OUT_SET_FIRST_PCR:
+    case ES_OUT_SET_FIRST_GROUP_PCR:
     case ES_OUT_SET_NEXT_DISPLAY_TIME:
     case ES_OUT_SET_GROUP_META:
     case ES_OUT_SET_GROUP_EPG:
@@ -1397,11 +1399,13 @@ static int CmdInitControl( ts_cmd_t *p_cmd, int i_query, va_list args, bool b_co
         break;
 
     case ES_OUT_SET_PCR:                /* arg1=vlc_tick_t i_pcr(microsecond!) (using default group 0)*/
+    case ES_OUT_SET_FIRST_PCR:
     case ES_OUT_SET_NEXT_DISPLAY_TIME:  /* arg1=int64_t i_pts(microsecond) */
         p_cmd->u.control.u.i_i64 = va_arg( args, int64_t );
         break;
 
     case ES_OUT_SET_GROUP_PCR:          /* arg1= int i_group, arg2=vlc_tick_t i_pcr(microsecond!)*/
+    case ES_OUT_SET_FIRST_GROUP_PCR:
         p_cmd->u.control.u.int_i64.i_int = va_arg( args, int );
         p_cmd->u.control.u.int_i64.i_i64 = va_arg( args, vlc_tick_t );
         break;
@@ -1556,10 +1560,12 @@ static int CmdExecuteControl( es_out_t *p_out, ts_cmd_t *p_cmd )
         return es_out_Control( p_out, i_query, p_cmd->u.control.u.i_int );
 
     case ES_OUT_SET_PCR:                /* arg1=vlc_tick_t i_pcr(microsecond!) (using default group 0)*/
+    case ES_OUT_SET_FIRST_PCR:
     case ES_OUT_SET_NEXT_DISPLAY_TIME:  /* arg1=int64_t i_pts(microsecond) */
         return es_out_Control( p_out, i_query, p_cmd->u.control.u.i_i64 );
 
     case ES_OUT_SET_GROUP_PCR:          /* arg1= int i_group, arg2=vlc_tick_t i_pcr(microsecond!)*/
+    case ES_OUT_SET_FIRST_GROUP_PCR:
         return es_out_Control( p_out, i_query, p_cmd->u.control.u.int_i64.i_int,
                                                p_cmd->u.control.u.int_i64.i_i64 );
 
-- 
2.20.1



More information about the vlc-devel mailing list