/** @internal @This allocates an telxf pipe. * * @param mgr common management structure * @param uprobe structure used to raise events * @param signature signature of the pipe allocator * @param args optional arguments * @return pointer to upipe or NULL in case of allocation error */ static struct upipe *upipe_telxf_alloc(struct upipe_mgr *mgr, struct uprobe *uprobe, uint32_t signature, va_list args) { struct upipe *upipe = upipe_telxf_alloc_void(mgr, uprobe, signature, args); if (unlikely(upipe == NULL)) return NULL; struct upipe_telxf *upipe_telxf = upipe_telxf_from_upipe(upipe); upipe_telxf_init_urefcount(upipe); upipe_telxf_init_sync(upipe); upipe_telxf_init_output(upipe); upipe_telxf_init_flow_def(upipe); /* There is no known implementation of teletext in non-25 Hz systems. */ upipe_telxf->fps.num = 25; upipe_telxf->fps.den = 1; upipe_telxf->octetrate = 0; upipe_telxf->next_uref = NULL; upipe_telxf->next_uref_size = 0; uref_init(&upipe_telxf->au_uref_s); uref_clock_set_date_sys(&upipe_telxf->au_uref_s, UINT64_MAX, UREF_DATE_NONE); uref_clock_set_date_prog(&upipe_telxf->au_uref_s, UINT64_MAX, UREF_DATE_NONE); uref_clock_set_date_orig(&upipe_telxf->au_uref_s, UINT64_MAX, UREF_DATE_NONE); upipe_throw_ready(upipe); return upipe; }
/** @internal @This flushes all dates. * * @param upipe description structure of the pipe */ static void upipe_a52f_flush_dates(struct upipe *upipe) { struct upipe_a52f *upipe_a52f = upipe_a52f_from_upipe(upipe); uref_clock_set_date_sys(&upipe_a52f->au_uref_s, UINT64_MAX, UREF_DATE_NONE); uref_clock_set_date_prog(&upipe_a52f->au_uref_s, UINT64_MAX, UREF_DATE_NONE); uref_clock_set_date_orig(&upipe_a52f->au_uref_s, UINT64_MAX, UREF_DATE_NONE); uref_clock_delete_dts_pts_delay(&upipe_a52f->au_uref_s); }
/** @internal @This interpolates the PCRs for packets without a PCR. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to pump that generated the buffer */ static void upipe_ts_pcr_interpolator_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_pcr_interpolator *upipe_ts_pcr_interpolator = upipe_ts_pcr_interpolator_from_upipe(upipe); bool discontinuity = ubase_check(uref_flow_get_discontinuity(uref)); if (discontinuity) { upipe_ts_pcr_interpolator->last_pcr = 0; upipe_ts_pcr_interpolator->packets = 0; upipe_ts_pcr_interpolator->pcr_packets = 0; upipe_ts_pcr_interpolator->pcr_delta = 0; upipe_ts_pcr_interpolator->discontinuity = true; upipe_notice_va(upipe, "Clearing state"); } upipe_ts_pcr_interpolator->packets++; uint64_t pcr_prog = 0; uref_clock_get_cr_prog(uref, &pcr_prog); if (pcr_prog) { uint64_t delta = pcr_prog - upipe_ts_pcr_interpolator->last_pcr; upipe_ts_pcr_interpolator->last_pcr = pcr_prog; upipe_verbose_va(upipe, "pcr_prog %"PRId64" offset %"PRId64" stored offset %"PRIu64" bitrate %"PRId64" bps", pcr_prog, delta, upipe_ts_pcr_interpolator->pcr_delta, INT64_C(27000000) * upipe_ts_pcr_interpolator->packets * 188 * 8 / delta); if (upipe_ts_pcr_interpolator->pcr_delta) upipe_ts_pcr_interpolator->pcr_packets = upipe_ts_pcr_interpolator->packets; upipe_ts_pcr_interpolator->pcr_delta = delta; upipe_ts_pcr_interpolator->packets = 0; } else if (upipe_ts_pcr_interpolator->pcr_packets) { uint64_t offset = upipe_ts_pcr_interpolator->pcr_delta * upipe_ts_pcr_interpolator->packets / upipe_ts_pcr_interpolator->pcr_packets; uint64_t prog = upipe_ts_pcr_interpolator->last_pcr + offset; uref_clock_set_date_prog(uref, prog, UREF_DATE_CR); upipe_throw_clock_ts(upipe, uref); } if (!upipe_ts_pcr_interpolator->pcr_packets) { uref_free(uref); return; } if (upipe_ts_pcr_interpolator->discontinuity) { uref_flow_set_discontinuity(uref); upipe_ts_pcr_interpolator->discontinuity = false; } upipe_ts_pcr_interpolator_output(upipe, uref, upump_p); }