/** @internal @This merges the new access unit into a possibly existing * incomplete PES, and outputs the PES if possible. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to pump that generated the buffer * @return false if the input must be blocked */ static bool upipe_ts_pese_handle(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_pese *upipe_ts_pese = upipe_ts_pese_from_upipe(upipe); const char *def; if (unlikely(ubase_check(uref_flow_get_def(uref, &def)))) { upipe_ts_pese_work(upipe, NULL); uref_ts_flow_get_pes_id(uref, &upipe_ts_pese->pes_id); upipe_ts_pese->pes_header_size = 0; uref_ts_flow_get_pes_header(uref, &upipe_ts_pese->pes_header_size); upipe_ts_pese->pes_min_duration = 0; uref_ts_flow_get_pes_min_duration(uref, &upipe_ts_pese->pes_min_duration); upipe_ts_pese->input_latency = 0; uref_clock_get_latency(uref, &upipe_ts_pese->input_latency); if (unlikely(!ubase_check(uref_clock_set_latency(uref, upipe_ts_pese->input_latency + upipe_ts_pese->pes_min_duration)))) upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); upipe_ts_pese_store_flow_def(upipe, NULL); upipe_ts_pese_require_ubuf_mgr(upipe, uref); return true; } if (upipe_ts_pese->flow_def == NULL) return false; uint64_t uref_duration = upipe_ts_pese->pes_min_duration; uref_clock_get_duration(uref, &uref_duration); size_t uref_size = 0; uref_block_size(uref, &uref_size); uref_block_delete_start(uref); ulist_add(&upipe_ts_pese->next_pes, uref_to_uchain(uref)); upipe_ts_pese->next_pes_duration += uref_duration; upipe_ts_pese->next_pes_size += uref_size; if (upipe_ts_pese->next_pes_duration >= upipe_ts_pese->pes_min_duration) upipe_ts_pese_work(upipe, upump_p); return true; }
/** @internal @This takes the payload of a TS packet and finds PSI sections * inside it. * * @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_psim_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_psim *upipe_ts_psim = upipe_ts_psim_from_upipe(upipe); if (unlikely(ubase_check(uref_flow_get_discontinuity(uref)))) upipe_ts_psim_flush(upipe); if (ubase_check(uref_block_get_start(uref))) { if (likely(upipe_ts_psim->acquired)) { /* just remove pointer_field */ if (unlikely(!ubase_check(uref_block_resize(uref, 1, -1)))) { uref_free(uref); upipe_ts_psim_flush(upipe); return; } } else { /* jump to the start of the next section */ uint8_t pointer_field; if (unlikely(!ubase_check(uref_block_extract(uref, 0, 1, &pointer_field)) || !ubase_check(uref_block_resize(uref, 1 + pointer_field, -1)))) { uref_free(uref); return; } upipe_ts_psim_sync_acquired(upipe); } uref_block_delete_start(uref); } else if (unlikely(upipe_ts_psim->next_uref == NULL)) { uref_free(uref); upipe_ts_psim_flush(upipe); return; } while (upipe_ts_psim_merge(upipe, uref, upump_p)); uref_free(uref); }