Exemplo n.º 1
0
/** @internal @This checks and parses a "#EXT-X-STREAM-INF" tag.
 *
 * @param upipe description structure of the pipe
 * @param flow_def the current flow definition
 * @param line the trailing characters of the line
 * @return an error code
 */
static int upipe_m3u_reader_ext_x_stream_inf(struct upipe *upipe,
                                             struct uref *flow_def,
                                             const char *line)
{
    if (!ubase_check(uref_flow_match_def(flow_def, M3U_FLOW_DEF)) &&
        !ubase_check(uref_flow_match_def(flow_def, MASTER_FLOW_DEF)))
        return UBASE_ERR_INVALID;
    UBASE_RETURN(uref_flow_set_def(flow_def, MASTER_FLOW_DEF));

    struct uref *item;
    UBASE_RETURN(upipe_m3u_reader_get_item(upipe, flow_def, &item));

    const char *iterator = line;
    struct ustring name, value;
    while (ubase_check(attribute_iterate(&iterator, &name, &value)) &&
           iterator != NULL) {
        char value_str[value.len + 1];
        int err = ustring_cpy(value, value_str, sizeof (value_str));
        if (unlikely(!ubase_check(err))) {
            upipe_err_va(upipe, "fail to copy ustring %.*s",
                         (int)value.len, value.at);
            continue;
        }

        if (!ustring_cmp_str(name, "BANDWIDTH")) {
            char *endptr;
            uint64_t bandwidth = strtoull(value_str, &endptr, 10);
            if (endptr == value_str)
                return UBASE_ERR_INVALID;
            err = uref_m3u_master_set_bandwidth(item, bandwidth);
            if (unlikely(!ubase_check(err)))
                upipe_err_va(upipe, "fail to set bandwidth to %s", value_str);
        }
        else if (!ustring_cmp_str(name, "CODECS")) {
            err = uref_m3u_master_set_codecs(item, value_str);
            if (unlikely(!ubase_check(err)))
                upipe_err_va(upipe, "fail to set codecs to %s", value_str);
        }
        else if (!ustring_cmp_str(name, "AUDIO")) {
            err = uref_m3u_master_set_audio(item, value_str);
            if (unlikely(!ubase_check(err)))
                upipe_err_va(upipe, "fail to set audio to %s", value_str);
        }
        else if (!ustring_cmp_str(name, "RESOLUTION")) {
            err = uref_m3u_master_set_resolution(item, value_str);
            if (unlikely(!ubase_check(err)))
                upipe_err_va(upipe, "fail to set resolution to %s", value_str);
        }
        else {
            upipe_warn_va(upipe, "ignoring attribute %.*s (%.*s)",
                          (int)name.len, name.at,
                          (int)value.len, value.at);
        }
    }

    return UBASE_ERR_NONE;
}
Exemplo n.º 2
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;
}
Exemplo n.º 3
0
/** @internal @This checks a flow definition validity.
 *
 * @param upipe description structure of the pipe
 * @param flow_def flow definition to check
 * @return an error code
 */
static int upipe_vblk_check_flow_def(struct upipe *upipe,
                                     struct uref *flow_def)
{
    uint64_t hsize, vsize;
    UBASE_RETURN(uref_flow_match_def(flow_def, UREF_PIC_FLOW_DEF));
    UBASE_RETURN(uref_pic_flow_get_hsize(flow_def, &hsize));
    UBASE_RETURN(uref_pic_flow_get_vsize(flow_def, &vsize));
    return UBASE_ERR_NONE;
}
Exemplo n.º 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_fsink_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, UPIPE_FSINK_EXPECTED_FLOW_DEF))
    flow_def = uref_dup(flow_def);
    UBASE_ALLOC_RETURN(flow_def)
    upipe_input(upipe, flow_def, NULL);
    return UBASE_ERR_NONE;
}
Exemplo n.º 5
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_dveo_asi_sink_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.mpegts."))
    flow_def = uref_dup(flow_def);
    UBASE_ALLOC_RETURN(flow_def)
    upipe_input(upipe, flow_def, NULL);
    return UBASE_ERR_NONE;
}
Exemplo n.º 6
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;
}
Exemplo n.º 7
0
/** @internal @This sets the output flow format.
 *
 * @param upipe description structure of the pipe
 * @param flow_def new flow format to set
 * @return an error code
 */
static int upipe_dvbcsa_enc_set_flow_def(struct upipe *upipe,
                                         struct uref *flow_def)
{
    struct upipe_dvbcsa_enc *upipe_dvbcsa_enc =
        upipe_dvbcsa_enc_from_upipe(upipe);
    UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF));
    struct uref *flow_def_dup = uref_dup(flow_def);
    UBASE_ALLOC_RETURN(flow_def_dup);
    upipe_dvbcsa_enc_store_flow_def(upipe, flow_def_dup);
    return UBASE_ERR_NONE;
}
Exemplo n.º 8
0
static int upipe_dump_set_flow_def(struct upipe *upipe, struct uref *flow_def)
{
    int ret = uref_flow_match_def(flow_def, "block.");
    if (!ubase_check(ret))
        return ret;

    struct uref *flow_def_dup = uref_dup(flow_def);
    if (unlikely(flow_def_dup == NULL))
        return UBASE_ERR_ALLOC;

    upipe_dump_store_flow_def(upipe, flow_def_dup);
    return UBASE_ERR_NONE;
}
Exemplo n.º 9
0
/** @internal @This handles input buffer of the blank source pipe. This buffer
 * is supposed to be a picture or a sound to set as source buffer of the blank
 * pipes (audio/video blank pipe generator).
 *
 * @param upipe description structure of the pipe
 * @param uref uref reference picture or sound
 * @param upump_p is ignored
 */
static void upipe_blksrc_input(struct upipe *upipe,
                               struct uref *uref,
                               struct upump **upump_p)
{
    struct upipe_blksrc *upipe_blksrc = upipe_blksrc_from_upipe(upipe);
    if (unlikely(!upipe_blksrc->flow_def)) {
        upipe_warn(upipe, "flow def is not set");
        uref_free(uref);
    }
    else if (ubase_check(uref_flow_match_def(upipe_blksrc->flow_def,
                                             UREF_PIC_FLOW_DEF))) {
        upipe_dbg(upipe, "set picture buffer");
        upipe_vblk_set_pic(upipe_blksrc->blk, uref);
    }
    else if (ubase_check(uref_flow_match_def(upipe_blksrc->flow_def,
                                             UREF_SOUND_FLOW_DEF)))
        upipe_ablk_set_sound(upipe_blksrc->blk, uref);
    else {
        upipe_warn(upipe, "unsupported flow definition");
        uref_free(uref);
    }
}
Exemplo n.º 10
0
/** @internal @This checks the validity of a sound flow def.
 *
 * @param upipe description structure of the pipe
 * @param flow_def flow definition to check
 * @return an error code
 */
static int upipe_ablk_check_flow_def(struct upipe *upipe,
                                     struct uref *flow_def)
{
    uint8_t planes, sample_size, channels;
    uint64_t rate, samples;

    UBASE_RETURN(uref_flow_match_def(flow_def, UREF_SOUND_FLOW_DEF));
    UBASE_RETURN(uref_sound_flow_get_planes(flow_def, &planes));
    UBASE_RETURN(uref_sound_flow_get_channels(flow_def, &channels));
    UBASE_RETURN(uref_sound_flow_get_rate(flow_def, &rate));
    UBASE_RETURN(uref_sound_flow_get_sample_size(flow_def, &sample_size));
    UBASE_RETURN(uref_sound_flow_get_samples(flow_def, &samples));
    return UBASE_ERR_NONE;
}
Exemplo n.º 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_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;
}
Exemplo n.º 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_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;
}
Exemplo n.º 13
0
/** @internal @This checks and parses a "#EXT-X-VERSION" tag.
 *
 * @param upipe description structure of the pipe
 * @param flow_def the current flow definition
 * @param line the trailing characters of the line
 * @return an error code
 */
static int upipe_m3u_reader_process_version(struct upipe *upipe,
                                            struct uref *flow_def,
                                            const char *line)
{
    UBASE_RETURN(uref_flow_match_def(flow_def, M3U_FLOW_DEF));

    char *endptr;
    unsigned long int version = strtoul(line, &endptr, 10);
    if (line == endptr || *endptr != '\0' || version > UINT8_MAX) {
        upipe_warn_va(upipe, "invalid version %s", line);
        return UBASE_ERR_INVALID;
    }
    upipe_dbg_va(upipe, "version: %u", version);
    return uref_m3u_flow_set_version(flow_def, version);
}
Exemplo n.º 14
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_audiobar_set_flow_def(struct upipe *upipe,
                                       struct uref *flow_def)
{
    if (flow_def == NULL)
        return UBASE_ERR_INVALID;
    uref_dump(flow_def, upipe->uprobe);
    UBASE_RETURN(uref_flow_match_def(flow_def, INPUT_FLOW_DEF))
    uint8_t channels;
    UBASE_RETURN(uref_sound_flow_get_channels(flow_def, &channels))

    struct uref *flow_def_dup;
    if (unlikely((flow_def_dup = uref_dup(flow_def)) == NULL))
        return UBASE_ERR_ALLOC;
    upipe_input(upipe, flow_def_dup, NULL);
    return UBASE_ERR_NONE;
}
Exemplo n.º 15
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;
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
0
/** @internal @This checks an URI.
 *
 * @param upipe description structure of the pipe
 * @param flow_def the current flow definition
 * @param uri the uri
 * @return an error code
 */
static int upipe_m3u_reader_process_uri(struct upipe *upipe,
                                        struct uref *flow_def,
                                        const char *uri)
{
    struct upipe_m3u_reader *upipe_m3u_reader =
        upipe_m3u_reader_from_upipe(upipe);

    upipe_verbose_va(upipe, "uri %s", uri);
    UBASE_RETURN(uref_flow_match_def(flow_def, M3U_FLOW_DEF));
    struct uref *item;
    UBASE_RETURN(upipe_m3u_reader_get_item(upipe, flow_def, &item));
    UBASE_RETURN(uref_m3u_set_uri(item, uri));
    if (upipe_m3u_reader->key)
        UBASE_RETURN(uref_m3u_playlist_key_copy(item, upipe_m3u_reader->key));
    upipe_m3u_reader->item = NULL;
    ulist_add(&upipe_m3u_reader->items, uref_to_uchain(item));
    return UBASE_ERR_NONE;
}
Exemplo n.º 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_nacl_audio_set_flow_def(struct upipe *upipe,
                                         struct uref *flow_def)
{
    if (flow_def == NULL)
        return UBASE_ERR_INVALID;

    struct upipe_nacl_audio *upipe_nacl_audio =
        upipe_nacl_audio_from_upipe(upipe);
    UBASE_RETURN(uref_flow_match_def(flow_def, EXPECTED_FLOW_DEF))
    UBASE_RETURN(uref_sound_flow_match_rate(flow_def, SAMPLE_RATE, SAMPLE_RATE))
    UBASE_RETURN(uref_sound_flow_match_channels(flow_def, 2, 2))
    UBASE_RETURN(uref_sound_flow_match_planes(flow_def, 1, 1))
    UBASE_RETURN(uref_sound_flow_check_channel(flow_def, "lr"))

    upipe_nacl_audio->latency = 0;
    uref_clock_get_latency(flow_def, &upipe_nacl_audio->latency);
    return UBASE_ERR_NONE;
}
Exemplo n.º 19
0
/** @internal @This outputs the m3u.
 *
 * @param upipe description structure of the pipe
 * @param upump_p reference to source pump to block
 */
static void upipe_m3u_reader_output_all(struct upipe *upipe,
                                        struct upump **upump_p)
{
    struct upipe_m3u_reader *upipe_m3u_reader =
        upipe_m3u_reader_from_upipe(upipe);

    struct uref *flow_def = upipe_m3u_reader->current_flow_def;
    upipe_m3u_reader->current_flow_def = NULL;
    if (unlikely(!ubase_check(uref_flow_match_def(flow_def, M3U_FLOW_DEF)))) {
        upipe_err(upipe, "invalid m3u");
        uref_free(flow_def);
        return;
    }

    /* force new flow def */
    upipe_m3u_reader_store_flow_def(upipe, NULL);
    /* set output flow def */
    upipe_m3u_reader_store_flow_def(upipe, flow_def);

    /* output */
    struct uchain *uchain;
    bool first = true;
    upipe_use(upipe);
    while ((uchain = ulist_pop(&upipe_m3u_reader->items)) != NULL) {
        struct uref *uref = uref_from_uchain(uchain);

        if (first)
            uref_block_set_start(uref);
        first = false;

        if (ulist_empty(&upipe_m3u_reader->items))
            uref_block_set_end(uref);

        upipe_m3u_reader_output(upipe, uref, upump_p);
    }
    upipe_release(upipe);
}
Exemplo n.º 20
0
static int upipe_m3u_reader_process_media(struct upipe *upipe,
                                          struct uref *flow_def,
                                          const char *line)
{
    struct upipe_m3u_reader *upipe_m3u_reader =
        upipe_m3u_reader_from_upipe(upipe);

    if (!ubase_check(uref_flow_match_def(flow_def, M3U_FLOW_DEF)) &&
        !ubase_check(uref_flow_match_def(flow_def, MASTER_FLOW_DEF)))
        return UBASE_ERR_INVALID;
    UBASE_RETURN(uref_flow_set_def(flow_def, MASTER_FLOW_DEF));

    struct uref *item = uref_sibling_alloc_control(flow_def);
    if (unlikely(item == NULL)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return UBASE_ERR_ALLOC;
    }

    struct ustring name, value;
    while (ubase_check(attribute_iterate(&line, &name, &value)) && line) {
        if (!ustring_cmp_str(name, "URI")) {
            value = ustring_unframe(value, '"');
            char val[value.len + 1];
            int err = ustring_cpy(value, val, sizeof (val));
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to copy %.*s",
                              (int)value.len, value.at);
                continue;
            }
            err = uref_m3u_set_uri(item, val);
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to set uri %s", val);
                continue;
            }
        }
        else if (!ustring_cmp_str(name, "TYPE")) {
            char val[value.len + 1];
            int err = ustring_cpy(value, val, sizeof (val));
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to copy %.*s",
                              (int)value.len, value.at);
                continue;
            }
            err = uref_m3u_master_set_media_type(item, val);
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to set media type %s", val);
                continue;
            }
        }
        else if (!ustring_cmp_str(name, "DEFAULT")) {
            if (!ustring_cmp_str(value, "YES")) {
                int err = uref_m3u_master_set_media_default(item);
                if (unlikely(!ubase_check(err)))
                    continue;
            }
            else if (ustring_cmp_str(value, "NO")) {
                upipe_warn_va(upipe, "invalid DEFAULT value %.*s",
                              (int)value.len, value.at);
                continue;
            }
        }
        else if (!ustring_cmp_str(name, "AUTOSELECT")) {
            if (!ustring_cmp_str(value, "YES")) {
                int err = uref_m3u_master_set_media_autoselect(item);
                if (unlikely(!ubase_check(err)))
                    continue;
            }
            else if (ustring_cmp_str(value, "NO")) {
                upipe_warn_va(upipe, "invalid AUTOSELECT value %.*s",
                              (int)value.len, value.at);
                continue;
            }
        }
        else if (!ustring_cmp_str(name, "NAME")) {
            value = ustring_unframe(value, '"');
            char val[value.len + 1];
            int err = ustring_cpy(value, val, sizeof (val));
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to copy %.*s",
                              (int)value.len, value.at);
                continue;
            }
            err = uref_m3u_master_set_media_name(item, val);
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to set media name %s", val);
                continue;
            }
        }
        else if (!ustring_cmp_str(name, "GROUP-ID")) {
            value = ustring_unframe(value, '"');
            char val[value.len + 1];
            int err = ustring_cpy(value, val, sizeof (val));
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to copy %.*s",
                              (int)value.len, value.at);
                continue;
            }
            err = uref_m3u_master_set_media_group(item, val);
            if (unlikely(!ubase_check(err))) {
                upipe_warn_va(upipe, "fail to set group id %s", val);
                continue;
            }
        }
        else {
            upipe_warn_va(upipe, "ignoring attribute %.*s (%.*s)",
                          (int)name.len, name.at,
                          (int)value.len, value.at);
        }
    }
    ulist_add(&upipe_m3u_reader->items, uref_to_uchain(item));
    return UBASE_ERR_NONE;
}
Exemplo n.º 21
0
/** @internal @This allocates a blank source 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_blksrc_alloc(struct upipe_mgr *mgr,
                                        struct uprobe *uprobe,
                                        uint32_t signature, va_list args)
{
    struct uref *flow_def;
    struct upipe *upipe = upipe_blksrc_alloc_flow(mgr, uprobe, signature, args,
                                                  &flow_def);
    if (unlikely(!upipe)) {
        return NULL;
    }

    struct upipe_blksrc *upipe_blksrc = upipe_blksrc_from_upipe(upipe);
    upipe_blksrc_init_urefcount(upipe);
    upipe_blksrc_init_urefcount_real(upipe);
    upipe_blksrc_init_src_probe(upipe);
    upipe_blksrc_init_blk_probe(upipe);
    upipe_blksrc_init_bin_input(upipe);
    upipe_blksrc_init_bin_output(upipe);
    upipe_blksrc->flow_def = flow_def;

    upipe_throw_ready(upipe);

    uint64_t duration = 0;
    if (ubase_check(uref_flow_match_def(flow_def, UREF_PIC_FLOW_DEF))) {
        struct urational fps;
        if (unlikely(!ubase_check(uref_pic_flow_get_fps(flow_def, &fps)))) {
            upipe_release(upipe);
            return NULL;
        }
        duration = (uint64_t)UCLOCK_FREQ * fps.den / fps.num;
    }
    else if (ubase_check(uref_flow_match_def(flow_def, UREF_SOUND_FLOW_DEF))) {
        uint64_t samples, rate;
        if (unlikely(!ubase_check(uref_sound_flow_get_samples(flow_def,
                                                              &samples))) ||
            unlikely(!ubase_check(uref_sound_flow_get_rate(flow_def,
                                                           &rate)))) {
            upipe_release(upipe);
            return NULL;
        }
        duration = samples * UCLOCK_FREQ / rate;
    }
    else {
        upipe_warn(upipe, "unsupported flow def");
        upipe_release(upipe);
        return NULL;
    }

    struct uref *src_flow_def = uref_void_flow_alloc_def(flow_def->mgr);
    if (unlikely(!src_flow_def)) {
        upipe_err(upipe, "fail to allocate source pipe flow def");
        upipe_release(upipe);
        return NULL;
    }

    if (unlikely(!ubase_check(uref_clock_set_duration(src_flow_def,
                                                      duration)))) {
        uref_free(src_flow_def);
        upipe_release(upipe);
        return NULL;
    }

    struct upipe_mgr *upipe_voidsrc_mgr = upipe_voidsrc_mgr_alloc();
    if (unlikely(!upipe_voidsrc_mgr)) {
        upipe_err(upipe, "fail to get void source manager");
        uref_free(src_flow_def);
        upipe_release(upipe);
        return NULL;
    }

    struct upipe *src =
        upipe_flow_alloc(upipe_voidsrc_mgr,
                         uprobe_pfx_alloc(
                            uprobe_use(&upipe_blksrc->src_probe),
                                       UPROBE_LOG_VERBOSE,
                                       "src"),
                         src_flow_def);
    upipe_mgr_release(upipe_voidsrc_mgr);
    uref_free(src_flow_def);
    if (unlikely(!src)) {
        upipe_err(upipe, "fail to allocate source pipe");
        upipe_release(upipe);
        return NULL;
    }

    upipe_blksrc_store_bin_input(upipe, src);

    struct upipe_mgr *upipe_blk_mgr = NULL;
    if (ubase_check(uref_flow_match_def(flow_def, UREF_PIC_FLOW_DEF))) {
        upipe_blk_mgr = upipe_vblk_mgr_alloc();
    }
    else if (ubase_check(uref_flow_match_def(flow_def, UREF_SOUND_FLOW_DEF))) {
        upipe_blk_mgr = upipe_ablk_mgr_alloc();
    }

    if (unlikely(!upipe_blk_mgr)) {
        upipe_err(upipe, "fail to get blank generator manager");
        upipe_release(upipe);
        return NULL;
    }

    struct upipe *blk =
        upipe_flow_alloc(upipe_blk_mgr,
                         uprobe_pfx_alloc(
                            uprobe_use(&upipe_blksrc->blk_probe),
                                       UPROBE_LOG_VERBOSE,
                                       "blk"),
                         flow_def);
    upipe_mgr_release(upipe_blk_mgr);
    if (unlikely(!blk)) {
        upipe_err(upipe, "fail to allocate blank generator pipe");
        upipe_release(upipe);
        return NULL;
    }

    upipe_blksrc_store_bin_output(upipe, blk);

    if (unlikely(!ubase_check(upipe_set_output(src, blk)))) {
        upipe_release(upipe);
        return NULL;
    }

    return upipe;
}
Exemplo n.º 22
0
/** @internal @This sets the input flow def.
 *
 * @param upipe description structure of the pipe
 * @param flow_def the flow format to set
 * @return an error code
 */
static int upipe_vblk_set_flow_def(struct upipe *upipe,
                                   struct uref *flow_def)
{
    struct upipe_vblk *upipe_vblk = upipe_vblk_from_upipe(upipe);

    if (!ubase_check(uref_flow_match_def(flow_def, UREF_VOID_FLOW_DEF)) &&
        !ubase_check(upipe_vblk_check_flow_def(upipe, flow_def)))
        return UBASE_ERR_INVALID;

    struct uref *input_flow_def = uref_dup(flow_def);
    if (unlikely(!input_flow_def)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return UBASE_ERR_ALLOC;
    }
    upipe_vblk_store_flow_def_input(upipe, input_flow_def);

    if (ubase_check(uref_flow_match_def(flow_def, UREF_VOID_FLOW_DEF)))
        return UBASE_ERR_NONE;

    uint64_t hsize = 0, vsize = 0;
    UBASE_RETURN(uref_pic_flow_get_hsize(flow_def, &hsize));
    UBASE_RETURN(uref_pic_flow_get_vsize(flow_def, &vsize));

    struct uref *flow_def_dup = uref_dup(flow_def);
    if (unlikely(!flow_def_dup)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return UBASE_ERR_ALLOC;
    }

    struct urational sar;
    uref_pic_flow_clear_format(flow_def_dup);
    uref_pic_flow_copy_format(flow_def_dup, flow_def);
    uref_pic_flow_set_hsize(flow_def_dup, hsize);
    uref_pic_flow_set_vsize(flow_def_dup, vsize);
    if (likely(ubase_check(uref_pic_flow_get_sar(flow_def, &sar)))) {
        uref_pic_flow_set_sar(flow_def_dup, sar);
    } else {
        uref_pic_flow_delete_sar(flow_def_dup);
    }
    bool overscan;
    if (likely(ubase_check(uref_pic_flow_get_overscan(flow_def, &overscan)))) {
        uref_pic_flow_set_overscan(flow_def_dup, overscan);
    } else {
        uref_pic_flow_delete_overscan(flow_def_dup);
    }
    if (likely(ubase_check(uref_pic_get_progressive(flow_def)))) {
        uref_pic_set_progressive(flow_def_dup);
    } else {
        uref_pic_delete_progressive(flow_def_dup);
    }
    upipe_vblk_store_flow_def(upipe, flow_def_dup);

    if (upipe_vblk->ubuf) {
        ubuf_free(upipe_vblk->ubuf);
        upipe_vblk->ubuf = NULL;
    }

    if (upipe_vblk->ubuf_mgr &&
        !ubase_check(ubuf_mgr_check(upipe_vblk->ubuf_mgr, flow_def_dup))) {
        ubuf_mgr_release(upipe_vblk->ubuf_mgr);
        upipe_vblk->ubuf_mgr = NULL;
    }

    return UBASE_ERR_NONE;
}
Exemplo n.º 23
0
static int upipe_m3u_reader_key(struct upipe *upipe,
                                struct uref *flow_def,
                                const char *line)
{
    struct upipe_m3u_reader *upipe_m3u_reader =
        upipe_m3u_reader_from_upipe(upipe);

    if (unlikely(!ubase_check(uref_flow_match_def(flow_def,
                                                  M3U_FLOW_DEF))) &&
        unlikely(!ubase_check(uref_flow_match_def(flow_def,
                                                  PLAYLIST_FLOW_DEF))))
        return UBASE_ERR_INVALID;
    UBASE_RETURN(uref_flow_set_def(flow_def, PLAYLIST_FLOW_DEF));

    struct uref *key = uref_sibling_alloc_control(flow_def);
    if (unlikely(key == NULL)) {
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return UBASE_ERR_ALLOC;
    }

    if (upipe_m3u_reader->key)
        uref_free(upipe_m3u_reader->key);
    upipe_m3u_reader->key = key;

    const char *iterator = line;
    struct ustring name, value;
    while (ubase_check(attribute_iterate(&iterator, &name, &value)) &&
           iterator != NULL) {
        char value_str[value.len + 1];
        int err = ustring_cpy(value, value_str, sizeof (value_str));
        if (unlikely(!ubase_check(err))) {
            upipe_err_va(upipe, "fail to copy ustring %.*s",
                         (int)value.len, value.at);
            continue;
        }

        if (!ustring_cmp_str(name, "METHOD")) {
            err = uref_m3u_playlist_key_set_method(key, value_str);
            if (unlikely(!ubase_check(err)))
                upipe_err_va(upipe, "fail to set key method to %s", value_str);
        }
        else if (!ustring_cmp_str(name, "URI")) {
            err = uref_m3u_playlist_key_set_uri(key, value_str);
            if (unlikely(!ubase_check(err)))
                upipe_err_va(upipe, "fail to set uri to %s", value_str);
        }
        else if (!ustring_cmp_str(name, "IV")) {
            size_t len = strlen(value_str);
            if (unlikely(len > 32)) {
                upipe_warn_va(upipe, "invalid initialization vector %s",
                              value_str);
                continue;
            }
            for (unsigned i = 0; i < len; i += 2) {
                if (unlikely(!isxdigit(value_str[i])) ||
                    unlikely(!isxdigit(value_str[i + 1]))) {
                    upipe_warn_va(upipe, "invalid initialization vector %s",
                                  value_str);
                    continue;
                }
                //FIXME
                //iv[] = value_str[i]
            }

        }
        else {
            upipe_warn_va(upipe, "ignoring attribute %.*s (%.*s)",
                          (int)name.len, name.at, (int)value.len, value.at);
        }
    }

    return UBASE_ERR_NONE;
}