/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_a52f_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; const char *def; if (unlikely(!ubase_check(uref_flow_get_def(flow_def, &def)) || (ubase_ncmp(def, "block.ac3.") && ubase_ncmp(def, "block.eac3.") && strcmp(def, "block.")))) return UBASE_ERR_INVALID; struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } struct upipe_a52f *upipe_a52f = upipe_a52f_from_upipe(upipe); upipe_a52f->input_latency = 0; uref_clock_get_latency(flow_def, &upipe_a52f->input_latency); if (unlikely(upipe_a52f->samplerate && !ubase_check(uref_clock_set_latency(flow_def_dup, upipe_a52f->input_latency + UCLOCK_FREQ * A52_FRAME_SAMPLES / upipe_a52f->samplerate)))) upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); flow_def = upipe_a52f_store_flow_def_input(upipe, flow_def_dup); if (flow_def != NULL) upipe_a52f_store_flow_def(upipe, flow_def); return UBASE_ERR_NONE; }
/** @internal @This tries to find TS packets in the buffered input urefs. * * @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_check_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_check *upipe_ts_check = upipe_ts_check_from_upipe(upipe); size_t size; if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { uref_free(uref); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } while (size > upipe_ts_check->output_size) { struct uref *next = uref_block_split(uref, upipe_ts_check->output_size); if (unlikely(next == NULL)) { uref_free(uref); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } if (!upipe_ts_check_check(upipe, uref, upump_p)) { uref_free(next); return; } size -= upipe_ts_check->output_size; uref = next; } if (size == upipe_ts_check->output_size) upipe_ts_check_check(upipe, uref, upump_p); }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow flow definition packet * @return an error code */ static int upipe_filter_ebur128_set_flow_def(struct upipe *upipe, struct uref *flow) { struct upipe_filter_ebur128 *upipe_filter_ebur128 = upipe_filter_ebur128_from_upipe(upipe); if (flow == NULL) return UBASE_ERR_INVALID; UBASE_RETURN(uref_flow_match_def(flow, "sound.s16.")) uint8_t channels, planes; uint64_t rate; if (unlikely(!ubase_check(uref_sound_flow_get_rate(flow, &rate)) || !ubase_check(uref_sound_flow_get_channels(flow, &channels)) || !ubase_check(uref_sound_flow_get_planes(flow, &planes)) || planes != 1)) { return UBASE_ERR_INVALID; } struct uref *flow_dup; if (unlikely((flow_dup = uref_dup(flow)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } if (unlikely(upipe_filter_ebur128->st)) { //ebur128_destroy(&upipe_filter_ebur128->st); ebur128_change_parameters(upipe_filter_ebur128->st, channels, rate); } else { upipe_filter_ebur128->st = ebur128_init(channels, rate, EBUR128_MODE_LRA | EBUR128_MODE_I | EBUR128_MODE_HISTOGRAM); } upipe_filter_ebur128_store_flow_def(upipe, flow_dup); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_s337d_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; const char *def; uint64_t rate; if (unlikely(!ubase_check(uref_flow_get_def(flow_def, &def)) || (ubase_ncmp(def, "block.s337.") && strcmp(def, "block.")) || !ubase_check(uref_sound_flow_get_rate(flow_def, &rate)))) return UBASE_ERR_INVALID; struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } struct upipe_s337d *upipe_s337d = upipe_s337d_from_upipe(upipe); upipe_s337d->sample_rate = rate; flow_def = upipe_s337d_store_flow_def_input(upipe, flow_def_dup); if (flow_def != NULL) upipe_s337d_store_flow_def(upipe, flow_def); return UBASE_ERR_NONE; }
/** @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_s337d_output_frame(struct upipe *upipe, struct upump **upump_p) { struct upipe_s337d *upipe_s337d = upipe_s337d_from_upipe(upipe); /* assume repetition rate and shift dts backwards */ size_t samples = upipe_s337d->next_uref_size / 4; uint64_t dts_shift = (uint64_t)samples * UCLOCK_FREQ / upipe_s337d->sample_rate; struct uref au_uref_s = *upipe_s337d->next_uref; /* consume burst preamble */ upipe_s337d_consume_uref_stream(upipe, S337_PREAMBLE_SIZE); /* extract burst payload */ struct uref *uref = upipe_s337d_extract_uref_stream(upipe, upipe_s337d->next_frame_size); if (unlikely(uref == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } 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 - dts_shift); SET_DATE(sys) SET_DATE(prog) SET_DATE(orig) #undef SET_DATE upipe_s337d_output(upipe, uref, upump_p); }
/** @internal @This creates regularly empty urefs. * * @param upump description structure of the timer */ static void upipe_voidsrc_worker(struct upump *upump) { struct upipe *upipe = upump_get_opaque(upump, struct upipe *); struct upipe_voidsrc *upipe_voidsrc = upipe_voidsrc_from_upipe(upipe); uint64_t now; if (upipe_voidsrc->pts == UINT64_MAX) upipe_voidsrc->pts = uclock_now(upipe_voidsrc->uclock); for (now = uclock_now(upipe_voidsrc->uclock); !upipe_single(upipe) && upipe_voidsrc->pts <= now; now = uclock_now(upipe_voidsrc->uclock)) { struct uref *uref = uref_alloc(upipe_voidsrc->uref_mgr); if (unlikely(!uref)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } uref_clock_set_duration(uref, upipe_voidsrc->interval); uref_clock_set_pts_sys(uref, upipe_voidsrc->pts); uref_clock_set_pts_prog(uref, upipe_voidsrc->pts); upipe_voidsrc->pts += upipe_voidsrc->interval; upipe_voidsrc_output(upipe, uref, &upipe_voidsrc->timer); } if (!upipe_single(upipe)) upipe_voidsrc_wait_timer(upipe, upipe_voidsrc->pts - now, upipe_voidsrc_worker); }
/** @internal @This parses and outputs a m3u file. * * @param upipe description structure of the pipe * @return an error code */ static void upipe_m3u_reader_process(struct upipe *upipe) { struct upipe_m3u_reader *upipe_m3u_reader = upipe_m3u_reader_from_upipe(upipe); if (unlikely(upipe_m3u_reader->current_flow_def == NULL)) { upipe_m3u_reader->current_flow_def = uref_dup(upipe_m3u_reader->flow_def); if (unlikely(upipe_m3u_reader->current_flow_def == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } } /* parse m3u */ int ret = UBASE_ERR_NONE; struct uref *uref = upipe_m3u_reader->next_uref; for (size_t offset = 0; uref && ubase_check(ret) && ubase_check(uref_block_scan(uref, &offset, '\n')); offset = 0, uref = upipe_m3u_reader->next_uref) { struct uref *line = upipe_m3u_reader_extract_uref_stream(upipe, offset + 1); ret = upipe_m3u_reader_process_line( upipe, upipe_m3u_reader->current_flow_def, line); uref_free(line); } if (!ubase_check(ret)) upipe_err(upipe, "invalid m3u"); }
/** @internal @This receives data. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to pump that generated the buffer */ static void upipe_telxf_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_telxf *upipe_telxf = upipe_telxf_from_upipe(upipe); size_t uref_size; if (!ubase_check(uref_block_size(uref, &uref_size)) || !uref_size) { uref_free(uref); return; } bool end = ubase_check(uref_block_get_end(uref)); if (ubase_check(uref_block_get_start(uref))) { if (upipe_telxf->next_uref != NULL) upipe_telxf_work(upipe, upump_p); upipe_telxf->next_uref = uref; upipe_telxf->next_uref_size = uref_size; } else if (likely(upipe_telxf->next_uref != NULL)) { struct ubuf *ubuf = uref_detach_ubuf(uref); uref_free(uref); if (unlikely(!ubase_check(uref_block_append(upipe_telxf->next_uref, ubuf)))) { ubuf_free(ubuf); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } upipe_telxf->next_uref_size += uref_size; } else { uref_free(uref); return; } if (end) upipe_telxf_work(upipe, upump_p); }
static int upipe_rtcp_check(struct upipe *upipe, struct uref *flow_format) { struct upipe_rtcp *upipe_rtcp = upipe_rtcp_from_upipe(upipe); if (flow_format != NULL) upipe_rtcp_store_flow_def(upipe, flow_format); if (upipe_rtcp->flow_def == NULL) return UBASE_ERR_NONE; if (upipe_rtcp->uref_mgr == NULL) { upipe_rtcp_require_uref_mgr(upipe); return UBASE_ERR_NONE; } if (upipe_rtcp->ubuf_mgr == NULL) { struct uref *flow_format = uref_block_flow_alloc_def(upipe_rtcp->uref_mgr, NULL); if (unlikely(flow_format == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_rtcp_require_ubuf_mgr(upipe, flow_format); return UBASE_ERR_NONE; } return UBASE_ERR_NONE; }
/** @This starts the watcher waiting for the sink to unblock. * * @param upipe description structure of the pipe */ static void upipe_dveo_asi_sink_poll(struct upipe *upipe) { struct upipe_dveo_asi_sink *upipe_dveo_asi_sink = upipe_dveo_asi_sink_from_upipe(upipe); if (unlikely(!ubase_check(upipe_dveo_asi_sink_check_upump_mgr(upipe)))) { upipe_err_va(upipe, "can't get upump_mgr"); upipe_throw_fatal(upipe, UBASE_ERR_UPUMP); return; } struct upump *watcher = upump_alloc_fd_write(upipe_dveo_asi_sink->upump_mgr, upipe_dveo_asi_sink_watcher, upipe, upipe->refcount, upipe_dveo_asi_sink->fd); if (unlikely(watcher == NULL)) { upipe_err(upipe, "can't create watcher"); upipe_throw_fatal(upipe, UBASE_ERR_UPUMP); } else { upipe_dveo_asi_sink_set_upump(upipe, watcher); upump_start(watcher); } }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_block_to_sound_set_flow_def(struct upipe *upipe, struct uref *flow_def) { struct upipe_block_to_sound *upipe_block_to_sound = upipe_block_to_sound_from_upipe(upipe); if (flow_def == NULL) return UBASE_ERR_INVALID; if (unlikely(!ubase_check(uref_flow_match_def(flow_def, "block.")))) { uref_free(flow_def); return UBASE_ERR_INVALID; } flow_def = uref_dup(upipe_block_to_sound->flow_def_config); if (unlikely(flow_def == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } if(unlikely(!ubase_check(uref_flow_match_def(flow_def, "sound.s32.")))) { uref_free(flow_def); return UBASE_ERR_INVALID; } uint8_t channels, planes, sample_size; if(unlikely(!ubase_check(uref_sound_flow_get_channels(flow_def, &channels))) || unlikely(!ubase_check(uref_sound_flow_get_planes(flow_def, &planes))) || unlikely(!ubase_check(uref_sound_flow_get_sample_size(flow_def, &sample_size)))) { uref_free(flow_def); return UBASE_ERR_INVALID; } struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_block_to_sound_store_flow_def(upipe, flow_def_dup); upipe_block_to_sound_require_ubuf_mgr(upipe, flow_def); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_ts_pesd_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; const char *def; UBASE_RETURN(uref_flow_get_def(flow_def, &def)) if (ubase_ncmp(def, EXPECTED_FLOW_DEF)) return UBASE_ERR_INVALID; struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } if (unlikely(!ubase_check(uref_flow_set_def_va(flow_def_dup, "block.%s", def + strlen(EXPECTED_FLOW_DEF))))) upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); upipe_ts_pesd_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @internal @This handles inner reader pipe events. * * @param uprobe structure used to raise events * @param inner pointer to inner pipe * @param event event thrown * @param args optional arguments * @return an error code */ static int probe_reader(struct uprobe *uprobe, struct upipe *inner, int event, va_list args) { struct upipe_hls *upipe_hls = upipe_hls_from_probe_reader(uprobe); struct upipe *upipe = upipe_hls_to_upipe(upipe_hls); if (event >= UPROBE_LOCAL) return UBASE_ERR_NONE; if (event == UPROBE_NEED_OUTPUT) { struct uref *flow_format = va_arg(args, struct uref *); const char *def; UBASE_RETURN(uref_flow_get_def(flow_format, &def)); struct uref *flow_format_dup = uref_dup(flow_format); if (unlikely(!flow_format_dup)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_hls_store_flow_def(upipe, flow_format_dup); if (!strcmp(def, "block.m3u.playlist.")) { struct upipe_mgr *upipe_null_mgr = upipe_null_mgr_alloc(); struct upipe *output = upipe_void_alloc_output( inner, upipe_null_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_hls->probe_null), UPROBE_LOG_VERBOSE, "null")); upipe_mgr_release(upipe_null_mgr); upipe_release(output); upipe_split_throw_update(upipe); return UBASE_ERR_NONE; } else if (!strcmp(def, "block.m3u.master.")) { struct upipe_mgr *upipe_hls_master_mgr = upipe_hls_master_mgr_alloc(); UBASE_ALLOC_RETURN(upipe_hls_master_mgr); struct upipe *output = upipe_void_alloc_output( inner, upipe_hls_master_mgr, uprobe_pfx_alloc(uprobe_use(&upipe_hls->probe_master), UPROBE_LOG_VERBOSE, "master")); upipe_mgr_release(upipe_hls_master_mgr); UBASE_ALLOC_RETURN(output); upipe_hls_store_bin_output(upipe, output); return UBASE_ERR_NONE; } else upipe_warn_va(upipe, "unsupported flow format %s", def); return UBASE_ERR_INVALID; } return upipe_throw_proxy(upipe, inner, event, args); }
/** @internal @This handles input buffers. * * @param upipe description structure of the pipe * @param uref input buffer to handle * @param upump_p reference to pump that generated the buffer */ static void upipe_ablk_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ablk *upipe_ablk = upipe_ablk_from_upipe(upipe); struct uref *input_flow_def = upipe_ablk->input_flow_def; struct uref *flow_def = upipe_ablk->flow_def; if (uref->ubuf) { upipe_ablk_output(upipe, uref, upump_p); return; } if (unlikely(!input_flow_def)) { upipe_warn(upipe, "no input flow definition"); uref_free(uref); return; } if (unlikely(!flow_def)) { upipe_warn(upipe, "no output flow definition set"); uref_free(uref); return; } if (unlikely(!upipe_ablk->ubuf_mgr)) { upipe_warn(upipe, "no ubuf manager set"); uref_free(uref); return; } if (unlikely(!upipe_ablk->ubuf)) { upipe_verbose(upipe, "allocate blank sound"); uint64_t samples = 0; uint8_t sample_size = 0; uref_sound_flow_get_samples(flow_def, &samples); uref_sound_flow_get_sample_size(flow_def, &sample_size); struct ubuf *ubuf = ubuf_sound_alloc(upipe_ablk->ubuf_mgr, samples); if (unlikely(!ubuf)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(uref); return; } const char *channel; uint8_t *buf = NULL; ubuf_sound_foreach_plane(ubuf, channel) { ubuf_sound_plane_write_uint8_t(ubuf, channel, 0, -1, &buf); memset(buf, 0, sample_size * samples); ubuf_sound_plane_unmap(ubuf, channel, 0, -1); }
/** @internal @This handles input. * * @param upipe description structure of the pipe * @param uref uref structure * @param upump_p reference to pump that generated the buffer */ static void upipe_htons_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct ubuf *ubuf; size_t size = 0; int remain, bufsize = -1, offset = 0; uint8_t *buf = NULL; /* block size */ if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { upipe_warn(upipe, "could not read uref block size"); uref_free(uref); return; } /* copy ubuf if shared or not 16b-unaligned or segmented */ bufsize = -1; if (!ubase_check(uref_block_write(uref, 0, &bufsize, &buf)) || ((uintptr_t)buf & 1) || bufsize != size) { ubuf = ubuf_block_copy(uref->ubuf->mgr, uref->ubuf, 0, size); if (unlikely(!ubuf)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); uref_free(uref); return; } uref_attach_ubuf(uref, ubuf); } else { uref_block_unmap(uref, 0); } /* process ubuf chunks */ while (size > 0) { bufsize = -1; if (unlikely(!ubase_check(uref_block_write(uref, offset, &bufsize, &buf)))) { upipe_warn(upipe, "unexpected buffer error"); uref_free(uref); return; } if (unlikely((uintptr_t)buf & 1)) { upipe_warn_va(upipe, "unaligned buffer: %p", buf); } for (remain = bufsize; remain > 1; remain -= 2) { *(uint16_t *)buf = htons(*(uint16_t *)buf); buf += 2; } uref_block_unmap(uref, offset); offset += bufsize; size -= bufsize; } upipe_htons_output(upipe, uref, upump_p); }
/** @internal @This tries to find TS packets in the buffered input urefs. * * @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_check_input(struct upipe *upipe, struct uref *uref, struct upump **upump_p) { struct upipe_ts_check *upipe_ts_check = upipe_ts_check_from_upipe(upipe); size_t size; if (unlikely(!ubase_check(uref_block_size(uref, &size)))) { uref_free(uref); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } bool first = true; while (size > upipe_ts_check->output_size) { struct uref *output = uref_block_splice(uref, 0, upipe_ts_check->output_size); if (unlikely(output == NULL)) { uref_free(uref); upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return; } if (!first) uref_flow_delete_discontinuity(output); first = false; if (!upipe_ts_check_check(upipe, output, upump_p)) { uref_free(uref); return; } uref_block_resize(uref, upipe_ts_check->output_size, -1); size -= upipe_ts_check->output_size; } if (!first) uref_flow_delete_discontinuity(uref); if (size == upipe_ts_check->output_size) upipe_ts_check_check(upipe, uref, upump_p); }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_ts_psim_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF)) struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_ts_psim_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_burst_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (unlikely(!ubase_check(uref_flow_match_def(flow_def, "block.")))) return UBASE_ERR_INVALID; struct uref *flow_def_dup = uref_dup(flow_def); if (unlikely(flow_def_dup == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_burst_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow flow definition packet * @return an error code */ static int upipe_filter_ebur128_set_flow_def(struct upipe *upipe, struct uref *flow) { struct upipe_filter_ebur128 *upipe_filter_ebur128 = upipe_filter_ebur128_from_upipe(upipe); if (flow == NULL) return UBASE_ERR_INVALID; enum upipe_filter_ebur128_fmt fmt; const char *def; UBASE_RETURN(uref_flow_get_def(flow, &def)) if (!ubase_ncmp(def, "sound.s16.")) fmt = UPIPE_FILTER_EBUR128_SHORT; else if (!ubase_ncmp(def, "sound.s32.")) fmt = UPIPE_FILTER_EBUR128_INT; else if (!ubase_ncmp(def, "sound.f32.")) fmt = UPIPE_FILTER_EBUR128_FLOAT; else if (!ubase_ncmp(def, "sound.f64.")) fmt = UPIPE_FILTER_EBUR128_DOUBLE; else return UBASE_ERR_INVALID; uint64_t rate; if (unlikely(!ubase_check(uref_sound_flow_get_rate(flow, &rate)) || !ubase_check(uref_sound_flow_get_channels(flow, &upipe_filter_ebur128->channels)) || !ubase_check(uref_sound_flow_get_planes(flow, &upipe_filter_ebur128->planes)))) return UBASE_ERR_INVALID; struct uref *flow_dup; if (unlikely((flow_dup = uref_dup(flow)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_filter_ebur128->fmt = fmt; if (unlikely(upipe_filter_ebur128->st)) { //ebur128_destroy(&upipe_filter_ebur128->st); ebur128_change_parameters(upipe_filter_ebur128->st, upipe_filter_ebur128->channels, rate); } else { upipe_filter_ebur128->st = ebur128_init(upipe_filter_ebur128->channels, rate, EBUR128_MODE_LRA | EBUR128_MODE_I | EBUR128_MODE_HISTOGRAM); } upipe_filter_ebur128_store_flow_def(upipe, flow_dup); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_filter_blend_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; UBASE_RETURN(uref_flow_match_def(flow_def, "pic.")) struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } UBASE_RETURN(uref_pic_set_progressive(flow_def_dup)) upipe_input(upipe, flow_def_dup, NULL); return UBASE_ERR_NONE; }
static int upipe_rtcp_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; struct uref *flow_def_dup = uref_dup(flow_def); if (unlikely(flow_def_dup == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_rtcp_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @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); }
static int upipe_rtp_h264_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; UBASE_RETURN(uref_flow_match_def(flow_def, "block.h264.")) struct uref *flow_def_dup = uref_dup(flow_def); if (unlikely(flow_def_dup == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_rtp_h264_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @This sets the dictionary to set into urefs. * * @param upipe description structure of the pipe * @param dict dictionary to set * @return an error code */ static int _upipe_setflowdef_set_dict(struct upipe *upipe, struct uref *dict) { struct upipe_setflowdef *upipe_setflowdef = upipe_setflowdef_from_upipe(upipe); if (upipe_setflowdef->dict != NULL) uref_free(upipe_setflowdef->dict); if (dict != NULL) { upipe_setflowdef->dict = uref_dup(dict); if (upipe_setflowdef->dict == NULL) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } } else upipe_setflowdef->dict = NULL; upipe_setflowdef_build_flow_def(upipe); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_ts_pcr_interpolator_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; const char *def; UBASE_RETURN(uref_flow_get_def(flow_def, &def)) if (ubase_ncmp(def, EXPECTED_FLOW_DEF)) return UBASE_ERR_INVALID; struct uref *flow_def_dup = uref_dup(flow_def); if (unlikely(flow_def_dup == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } upipe_ts_pcr_interpolator_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow def of the m3u pipe. * * @param upipe description structure of the pipe * @param flow_def new input flow definition * @return an error code */ static int upipe_m3u_reader_set_flow_def(struct upipe *upipe, struct uref *flow_def) { struct upipe_m3u_reader *upipe_m3u_reader = upipe_m3u_reader_from_upipe(upipe); UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF)); struct uref *flow_def_dup = uref_dup(flow_def); if (unlikely(flow_def_dup == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } uref_free(upipe_m3u_reader->flow_def); upipe_m3u_reader->flow_def = flow_def_dup; return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_ts_check_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF)) struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } struct upipe_ts_check *upipe_ts_check = upipe_ts_check_from_upipe(upipe); UBASE_RETURN(uref_block_flow_set_size(flow_def_dup, upipe_ts_check->output_size)) UBASE_RETURN(uref_flow_set_def(flow_def_dup, OUTPUT_FLOW_DEF)) upipe_ts_check_store_flow_def(upipe, flow_def_dup); return UBASE_ERR_NONE; }
/** @internal @This sets the input flow definition. * * @param upipe description structure of the pipe * @param flow_def flow definition packet * @return an error code */ static int upipe_telxf_set_flow_def(struct upipe *upipe, struct uref *flow_def) { if (flow_def == NULL) return UBASE_ERR_INVALID; const char *def; if (unlikely(!ubase_check(uref_flow_get_def(flow_def, &def)) || (ubase_ncmp(def, "block.dvb_teletext.") && strcmp(def, "block.")))) return UBASE_ERR_INVALID; struct uref *flow_def_dup; if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } flow_def = upipe_telxf_store_flow_def_input(upipe, flow_def_dup); if (flow_def != NULL) upipe_telxf_store_flow_def(upipe, flow_def); return UBASE_ERR_NONE; }
/** @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 gets or allocates the current item. * * @param upipe description structure of the pipe * @param flow_def the current flow definition * @param item_p pointer to the item * @return an error code */ static int upipe_m3u_reader_get_item(struct upipe *upipe, struct uref *flow_def, struct uref **item_p) { struct upipe_m3u_reader *upipe_m3u_reader = upipe_m3u_reader_from_upipe(upipe); if (unlikely(item_p == NULL) || unlikely(flow_def == NULL)) return UBASE_ERR_INVALID; if (unlikely(upipe_m3u_reader->item == NULL)) { upipe_m3u_reader->item = uref_sibling_alloc_control(flow_def); if (unlikely(upipe_m3u_reader->item == NULL)) { upipe_throw_fatal(upipe, UBASE_ERR_ALLOC); return UBASE_ERR_ALLOC; } } *item_p = upipe_m3u_reader->item; return UBASE_ERR_NONE; }