Skip to content

Commit bced08b

Browse files
quariumcmassiot
authored andcommitted
upipe_ts_demux: add configurable max PCRs interval
1 parent 1dcccce commit bced08b

File tree

2 files changed

+143
-4
lines changed

2 files changed

+143
-4
lines changed

include/upipe-ts/upipe_ts_demux.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ enum upipe_ts_demux_command {
5858
UPIPE_TS_DEMUX_SET_EIT_ENABLED,
5959
/** enables or disables EITs table ID decoding (int) */
6060
UPIPE_TS_DEMUX_SET_EITS_ENABLED,
61+
/** sets the maximum allow interval between PCRs (uint64_t) */
62+
UPIPE_TS_DEMUX_SET_MAX_PCR_INTERVAL,
63+
/** gets the configured maximum interval between PCRs (uint64_t *) */
64+
UPIPE_TS_DEMUX_GET_MAX_PCR_INTERVAL,
6165
};
6266

6367
/** @This returns the currently detected conformance mode. It cannot return
@@ -128,6 +132,33 @@ static inline int upipe_ts_demux_set_eits_enabled(struct upipe *upipe,
128132
UPIPE_TS_DEMUX_SIGNATURE, enabled ? 1 : 0);
129133
}
130134

135+
/** @This sets the maximum allowed interval between PCRs.
136+
*
137+
* @param upipe description structure of the pipe
138+
* @param max maximum allowed interval between PCRs in 27MHz ticks
139+
* @return an error code
140+
*/
141+
static inline int upipe_ts_demux_set_max_pcr_interval(struct upipe *upipe,
142+
uint64_t max)
143+
{
144+
return upipe_control(upipe, UPIPE_TS_DEMUX_SET_MAX_PCR_INTERVAL,
145+
UPIPE_TS_DEMUX_SIGNATURE, max);
146+
}
147+
148+
/** @This gets the configured maximum allowed interval between PCRs.
149+
*
150+
* @param upipe description structure of the pipe
151+
* @param max filled with the maximum allowed internal between PCRs in 27MHz
152+
* ticks
153+
* @return an error code
154+
*/
155+
static inline int upipe_ts_demux_get_max_pcr_interval(struct upipe *upipe,
156+
uint64_t *max)
157+
{
158+
return upipe_control(upipe, UPIPE_TS_DEMUX_GET_MAX_PCR_INTERVAL,
159+
UPIPE_TS_DEMUX_SIGNATURE, max);
160+
}
161+
131162
/** @This returns the management structure for all ts_demux pipes.
132163
*
133164
* @return pointer to manager

lib/upipe-ts/upipe_ts_demux.c

Lines changed: 112 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)