/** @internal @This handles and outputs a frame. * * @param upipe description structure of the pipe * @param upump_p reference to pump that generated the buffer */ static void upipe_a52f_output_frame(struct upipe *upipe, struct upump **upump_p) { struct upipe_a52f *upipe_a52f = upipe_a52f_from_upipe(upipe); struct uref au_uref_s = upipe_a52f->au_uref_s; struct urational drift_rate = upipe_a52f->drift_rate; /* From now on, PTS declaration only impacts the next frame. */ upipe_a52f_flush_dates(upipe); struct uref *uref = upipe_a52f_extract_uref_stream(upipe, upipe_a52f->next_frame_size); if (unlikely(uref == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } lldiv_t div = lldiv(A52_FRAME_SAMPLES * UCLOCK_FREQ + upipe_a52f->duration_residue, upipe_a52f->samplerate); uint64_t duration = div.quot; upipe_a52f->duration_residue = div.rem; /* We work on encoded data so in the DTS domain. Rebase on DTS. */ uint64_t date; #define SET_DATE(dv) \ if (ubase_check(uref_clock_get_dts_##dv(&au_uref_s, &date))) { \ uref_clock_set_dts_##dv(uref, date); \ uref_clock_set_dts_##dv(&upipe_a52f->au_uref_s, date + duration); \ } else if (ubase_check(uref_clock_get_dts_##dv(uref, &date))) \ uref_clock_set_date_##dv(uref, UINT64_MAX, UREF_DATE_NONE); SET_DATE(sys) SET_DATE(prog) SET_DATE(orig) #undef SET_DATE uref_clock_set_dts_pts_delay(uref, 0); if (drift_rate.den) uref_clock_set_rate(uref, drift_rate); else uref_clock_delete_rate(uref); UBASE_FATAL(upipe, uref_clock_set_duration(uref, duration)) if (upipe_a52f->got_discontinuity) uref_flow_set_discontinuity(uref); upipe_a52f->got_discontinuity = false; upipe_a52f_output(upipe, uref, upump_p); }
/** @internal @This works on a telx frame and outputs it. * * @param upipe description structure of the pipe * @param upump_p reference to pump that generated the buffer */ static void upipe_telxf_work(struct upipe *upipe, struct upump **upump_p) { struct upipe_telxf *upipe_telxf = upipe_telxf_from_upipe(upipe); uint64_t octetrate = (upipe_telxf->next_uref_size * upipe_telxf->fps.num + upipe_telxf->fps.den - 1) / upipe_telxf->fps.den; if (octetrate != upipe_telxf->octetrate) { upipe_telxf->octetrate = octetrate; struct uref *flow_def = upipe_telxf_alloc_flow_def_attr(upipe); if (unlikely(flow_def == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(upipe_telxf->next_uref); goto upipe_telxf_work_err; } UBASE_FATAL(upipe, uref_pic_flow_set_fps(flow_def, upipe_telxf->fps)) UBASE_FATAL(upipe, uref_block_flow_set_octetrate(flow_def, upipe_telxf->octetrate)) flow_def = upipe_telxf_store_flow_def_attr(upipe, flow_def); if (unlikely(flow_def == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(upipe_telxf->next_uref); goto upipe_telxf_work_err; } upipe_telxf_store_flow_def(upipe, flow_def); } upipe_telxf_sync_acquired(upipe); uint64_t duration = UCLOCK_FREQ * upipe_telxf->fps.den / upipe_telxf->fps.num; /* We work on encoded data so in the DTS domain. Rebase on DTS. */ uint64_t date; struct urational drift_rate; drift_rate.den = 0; uref_clock_get_rate(upipe_telxf->next_uref, &drift_rate); #define SET_DATE(dv) \ if (ubase_check(uref_clock_get_dts_##dv(upipe_telxf->next_uref, &date)))\ uref_clock_set_dts_##dv(&upipe_telxf->au_uref_s, date); \ if (ubase_check(uref_clock_get_dts_##dv(&upipe_telxf->au_uref_s, \ &date))) { \ uref_clock_set_dts_##dv(upipe_telxf->next_uref, date); \ uref_clock_set_dts_##dv(&upipe_telxf->au_uref_s, date + duration); \ } else if (ubase_check(uref_clock_get_cr_##dv(upipe_telxf->next_uref, \ &date))) { \ /* EN 300 472 Annex A */ \ uref_clock_set_dts_##dv(upipe_telxf->next_uref, \ date + MAX_DELAY_TELX); \ uref_clock_set_dts_##dv(&upipe_telxf->au_uref_s, date + \ MAX_DELAY_TELX + duration); \ } SET_DATE(sys) SET_DATE(prog) SET_DATE(orig) #undef SET_DATE uref_clock_set_dts_pts_delay(upipe_telxf->next_uref, 0); if (drift_rate.den) uref_clock_set_rate(upipe_telxf->next_uref, drift_rate); upipe_telxf_output(upipe, upipe_telxf->next_uref, upump_p); upipe_telxf_work_err: upipe_telxf->next_uref = NULL; upipe_telxf->next_uref_size = 0; }