Пример #1
0
/** @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;
}
Пример #2
0
/** @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);
}
Пример #3
0
/** @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;
}
Пример #4
0
/** @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;
}
Пример #5
0
/** @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);
}
Пример #6
0
/** @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);
}
Пример #7
0
/** @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");
}
Пример #8
0
/** @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);
}
Пример #9
0
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;
}
Пример #10
0
/** @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);
    }
}
Пример #11
0
/** @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;
}
Пример #12
0
/** @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;
}
Пример #13
0
/** @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);
}
Пример #14
0
/** @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);
        }
Пример #15
0
/** @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);
}
Пример #16
0
/** @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);
}
Пример #17
0
/** @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;
}
Пример #18
0
/** @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;
}
Пример #19
0
/** @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;
}
Пример #20
0
/** @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;
}
Пример #21
0
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;
}
Пример #22
0
/** @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);
}
Пример #23
0
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;
}
Пример #24
0
/** @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;
}
Пример #25
0
/** @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;
}
Пример #26
0
/** @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;
}
Пример #27
0
/** @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;
}
Пример #28
0
/** @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;
}
Пример #29
0
/** @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;
}
Пример #30
0
/** @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;
}