@@ -299,6 +299,8 @@ struct upipe_ts_demux {
299299 bool eit_enabled ;
300300 /** enable EITs table ID decoder */
301301 bool eits_enabled ;
302+ /** maximum allowed interval between PCRs */
303+ uint64_t max_pcr_interval ;
302304
303305 /** probe to get new flow events from inner pipes created by psi_pid
304306 * objects */
@@ -415,6 +417,8 @@ struct upipe_ts_demux_program {
415417
416418 /** offset between MPEG timestamps and Upipe timestamps */
417419 int64_t timestamp_offset ;
420+ /** maximum allowed interval between PCRs */
421+ uint64_t max_pcr_interval ;
418422 /** last MPEG clock reference */
419423 uint64_t last_pcr ;
420424 /** highest Upipe timestamp given to a frame */
@@ -766,6 +770,9 @@ static int upipe_ts_demux_output_clock_ts(struct upipe *upipe,
766770 if (output -> max_delay + max_pcr_interval < output -> max_delay )
767771 max_pcr_interval = UINT64_MAX - output -> max_delay ;
768772
773+ if (program -> max_pcr_interval > max_pcr_interval )
774+ max_pcr_interval = program -> max_pcr_interval ;
775+
769776 /* handle 2^33 wrap-arounds */
770777 uint64_t delta = (TS_CLOCK_MAX + dts_orig -
771778 (program -> last_pcr % TS_CLOCK_MAX )) % TS_CLOCK_MAX ;
@@ -1948,7 +1955,7 @@ static void upipe_ts_demux_program_handle_pcr(struct upipe *upipe,
19481955 uint64_t delta =
19491956 (TS_CLOCK_MAX + pcr_orig -
19501957 (upipe_ts_demux_program -> last_pcr % TS_CLOCK_MAX )) % TS_CLOCK_MAX ;
1951- if (delta <= MAX_PCR_INTERVAL )
1958+ if (delta <= upipe_ts_demux_program -> max_pcr_interval )
19521959 upipe_ts_demux_program -> last_pcr += delta ;
19531960 else {
19541961 upipe_warn_va (upipe , "PCR discontinuity %" PRIu64 , delta );
@@ -2104,8 +2111,11 @@ static struct upipe *upipe_ts_demux_program_alloc(struct upipe_mgr *mgr,
21042111 args , & flow_def );
21052112 if (unlikely (upipe == NULL ))
21062113 return NULL ;
2114+
2115+ struct upipe_ts_demux * demux = upipe_ts_demux_from_program_mgr (upipe -> mgr );
21072116 struct upipe_ts_demux_program * upipe_ts_demux_program =
21082117 upipe_ts_demux_program_from_upipe (upipe );
2118+
21092119 upipe_ts_demux_program_init_urefcount (upipe );
21102120 urefcount_init (upipe_ts_demux_program_to_urefcount_real (upipe_ts_demux_program ), upipe_ts_demux_program_free );
21112121 upipe_ts_demux_program_init_output (upipe );
@@ -2134,6 +2144,7 @@ static struct upipe *upipe_ts_demux_program_alloc(struct upipe_mgr *mgr,
21342144 }
21352145 upipe_ts_demux_program -> timestamp_offset = 0 ;
21362146 upipe_ts_demux_program -> timestamp_highest = TS_CLOCK_MAX ;
2147+ upipe_ts_demux_program -> max_pcr_interval = demux -> max_pcr_interval ;
21372148 upipe_ts_demux_program -> last_pcr = TS_CLOCK_MAX ;
21382149 uprobe_init (& upipe_ts_demux_program -> pmtd_probe ,
21392150 upipe_ts_demux_program_pmtd_probe , NULL );
@@ -2159,7 +2170,6 @@ static struct upipe *upipe_ts_demux_program_alloc(struct upipe_mgr *mgr,
21592170 upipe_ts_demux_program_init_sub (upipe );
21602171 upipe_throw_ready (upipe );
21612172
2162- struct upipe_ts_demux * demux = upipe_ts_demux_from_program_mgr (upipe -> mgr );
21632173 const uint8_t * filter , * mask ;
21642174 size_t size ;
21652175 const char * def ;
@@ -2239,6 +2249,38 @@ static struct upipe *upipe_ts_demux_program_alloc(struct upipe_mgr *mgr,
22392249 return upipe ;
22402250}
22412251
2252+ /** @internal @This sets the maximum allow interval between PCRs.
2253+ *
2254+ * @param upipe description structure of the pipe
2255+ * @param max maximum allowed interval between PCRs in 27MHz ticks
2256+ * @return an error code
2257+ */
2258+ static int upipe_ts_demux_program_set_max_pcr_interval (struct upipe * upipe ,
2259+ uint64_t max )
2260+ {
2261+ struct upipe_ts_demux_program * program =
2262+ upipe_ts_demux_program_from_upipe (upipe );
2263+ program -> max_pcr_interval = max ;
2264+ return UBASE_ERR_NONE ;
2265+ }
2266+
2267+ /** @internal @This gets the configured maximum interval between PCRs.
2268+ *
2269+ * @param upipe description structure of the pipe
2270+ * @param max filled with the maximum allowed internal between PCRs in 27MHz
2271+ * ticks.
2272+ * @return an error code
2273+ */
2274+ static int upipe_ts_demux_program_get_max_pcr_interval (struct upipe * upipe ,
2275+ uint64_t * max )
2276+ {
2277+ struct upipe_ts_demux_program * program =
2278+ upipe_ts_demux_program_from_upipe (upipe );
2279+ if (max )
2280+ * max = program -> max_pcr_interval ;
2281+ return UBASE_ERR_NONE ;
2282+ }
2283+
22422284/** @internal @This processes control commands on a ts_demux_program pipe.
22432285 *
22442286 * @param upipe description structure of the pipe
@@ -2281,10 +2323,27 @@ static int upipe_ts_demux_program_control(struct upipe *upipe,
22812323 * p = upipe_ts_demux_program -> pmtd ;
22822324 return (* p != NULL ) ? UBASE_ERR_NONE : UBASE_ERR_UNHANDLED ;
22832325 }
2284-
22852326 default :
2286- return UBASE_ERR_NONE ;
2327+ break ;
2328+ }
2329+
2330+ if (ubase_get_signature (args ) == UPIPE_TS_DEMUX_SIGNATURE ) {
2331+ switch (command ) {
2332+ case UPIPE_TS_DEMUX_SET_MAX_PCR_INTERVAL : {
2333+ UBASE_SIGNATURE_CHECK (args , UPIPE_TS_DEMUX_SIGNATURE );
2334+ uint64_t max = va_arg (args , uint64_t );
2335+ return upipe_ts_demux_program_set_max_pcr_interval (upipe , max );
2336+ }
2337+
2338+ case UPIPE_TS_DEMUX_GET_MAX_PCR_INTERVAL : {
2339+ UBASE_SIGNATURE_CHECK (args , UPIPE_TS_DEMUX_SIGNATURE );
2340+ uint64_t * max = va_arg (args , uint64_t * );
2341+ return upipe_ts_demux_program_get_max_pcr_interval (upipe , max );
2342+ }
2343+ }
22872344 }
2345+
2346+ return UBASE_ERR_NONE ;
22882347}
22892348
22902349/** @This frees a upipe.
@@ -3382,6 +3441,7 @@ static struct upipe *upipe_ts_demux_alloc(struct upipe_mgr *mgr,
33823441 upipe_ts_demux -> auto_conformance = true;
33833442 upipe_ts_demux -> eit_enabled = true;
33843443 upipe_ts_demux -> eits_enabled = true;
3444+ upipe_ts_demux -> max_pcr_interval = MAX_PCR_INTERVAL ;
33853445 upipe_ts_demux -> nit_pid = 0 ;
33863446 upipe_ts_demux -> flow_def_input = NULL ;
33873447
@@ -3677,6 +3737,44 @@ static int _upipe_ts_demux_set_eits_enabled(struct upipe *upipe,
36773737 return UBASE_ERR_NONE ;
36783738}
36793739
3740+ /** @internal @This sets the maximum allow interval between PCRs.
3741+ *
3742+ * @param upipe description structure of the pipe
3743+ * @param max maximum allowed interval between PCRs in 27MHz ticks
3744+ * @return an error code
3745+ */
3746+ static int _upipe_ts_demux_set_max_pcr_interval (struct upipe * upipe ,
3747+ uint64_t max )
3748+ {
3749+ struct upipe_ts_demux * demux = upipe_ts_demux_from_upipe (upipe );
3750+ demux -> max_pcr_interval = max ;
3751+
3752+ struct uchain * uchain ;
3753+ ulist_foreach (& demux -> programs , uchain ) {
3754+ struct upipe_ts_demux_program * program =
3755+ upipe_ts_demux_program_from_uchain (uchain );
3756+ struct upipe * sub = upipe_ts_demux_program_to_upipe (program );
3757+ upipe_ts_demux_program_set_max_pcr_interval (sub , max );
3758+ }
3759+ return UBASE_ERR_NONE ;
3760+ }
3761+
3762+ /** @internal @This gets the configured maximum interval between PCRs.
3763+ *
3764+ * @param upipe description structure of the pipe
3765+ * @param max filled with the maximum allowed internal between PCRs in 27MHz
3766+ * ticks.
3767+ * @return an error code
3768+ */
3769+ static int _upipe_ts_demux_get_max_pcr_interval (struct upipe * upipe ,
3770+ uint64_t * max )
3771+ {
3772+ struct upipe_ts_demux * demux = upipe_ts_demux_from_upipe (upipe );
3773+ if (max )
3774+ * max = demux -> max_pcr_interval ;
3775+ return UBASE_ERR_NONE ;
3776+ }
3777+
36803778/** @internal @This processes control commands on a ts_demux pipe.
36813779 *
36823780 * @param upipe description structure of the pipe
@@ -3749,6 +3847,16 @@ static int upipe_ts_demux_control(struct upipe *upipe,
37493847 int enabled = va_arg (args , int );
37503848 return _upipe_ts_demux_set_eits_enabled (upipe , !!enabled );
37513849 }
3850+ case UPIPE_TS_DEMUX_SET_MAX_PCR_INTERVAL : {
3851+ UBASE_SIGNATURE_CHECK (args , UPIPE_TS_DEMUX_SIGNATURE );
3852+ uint64_t max = va_arg (args , uint64_t );
3853+ return _upipe_ts_demux_set_max_pcr_interval (upipe , max );
3854+ }
3855+ case UPIPE_TS_DEMUX_GET_MAX_PCR_INTERVAL : {
3856+ UBASE_SIGNATURE_CHECK (args , UPIPE_TS_DEMUX_SIGNATURE );
3857+ uint64_t * max = va_arg (args , uint64_t * );
3858+ return _upipe_ts_demux_get_max_pcr_interval (upipe , max );
3859+ }
37523860
37533861 default :
37543862 break ;
0 commit comments