Exemple #1
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;
}
Exemple #2
0
/** @internal @This provides a ubuf_mgr request.
 *
 * @param upipe description structure of the pipe
 * @param flow_format amended flow format
 * @return an error code
 */
static int upipe_audiobar_check_ubuf_mgr(struct upipe *upipe,
                                         struct uref *flow_format)
{
    struct upipe_audiobar *upipe_audiobar = upipe_audiobar_from_upipe(upipe);
    if (flow_format == NULL)
        return UBASE_ERR_NONE;

    upipe_audiobar_store_flow_def(upipe, flow_format);
    UBASE_RETURN(uref_pic_flow_get_hsize(flow_format, &upipe_audiobar->hsize))
    UBASE_RETURN(uref_pic_flow_get_vsize(flow_format, &upipe_audiobar->vsize))
    upipe_audiobar->chan_width =
        upipe_audiobar->hsize / upipe_audiobar->channels;
    upipe_audiobar->chan_width -= upipe_audiobar->chan_width % 2;
    if (unlikely(upipe_audiobar->chan_width < 16)) {
        upipe_warn_va(upipe,
                "channel width is too small to have a separation (%"PRIu64")",
                upipe_audiobar->chan_width);
    }
    upipe_audiobar->sep_width = upipe_audiobar->chan_width / 4;
    upipe_audiobar->sep_width -= upipe_audiobar->sep_width % 4;
    upipe_audiobar->pad_width = upipe_audiobar->hsize -
        upipe_audiobar->chan_width * upipe_audiobar->channels;
    upipe_notice_va(upipe,
            "setting up chan %"PRIu64" sep %"PRIu64" pad %"PRIu64,
            upipe_audiobar->chan_width, upipe_audiobar->sep_width,
            upipe_audiobar->pad_width);

    bool was_buffered = !upipe_audiobar_check_input(upipe);
    upipe_audiobar_output_input(upipe);
    upipe_audiobar_unblock_input(upipe);
    if (was_buffered && upipe_audiobar_check_input(upipe)) {
        /* All packets have been output, release again the pipe that has been
         * used in @ref upipe_audiobar_input. */
        upipe_release(upipe);
    }
    return UBASE_ERR_NONE;
}
Exemple #3
0
/** avcdec callback */
static int avcdec_catch(struct uprobe *uprobe, struct upipe *upipe,
                        int event, va_list args)
{
    if (event != UPROBE_NEED_OUTPUT)
        return uprobe_throw_next(uprobe, upipe, event, args);

    struct uref *flow_def = va_arg(args, struct uref *);

    uint64_t hsize, vsize, wanted_hsize;
    struct urational sar;
    bool progressive;
    if (unlikely(!ubase_check(uref_pic_flow_get_hsize(flow_def, &hsize)) ||
                 !ubase_check(uref_pic_flow_get_vsize(flow_def, &vsize)) ||
                 !ubase_check(uref_pic_flow_get_sar(flow_def, &sar)))) {
        upipe_err_va(upipe, "incompatible flow def");
        upipe_release(upipe_source);
        return UBASE_ERR_UNHANDLED;
    }
    wanted_hsize = (hsize * sar.num / sar.den / 2) * 2;
    progressive = ubase_check(uref_pic_get_progressive(flow_def));

    struct uref *flow_def2 = uref_dup(flow_def);
    upipe_use(upipe);

    if (!progressive) {
        uref_pic_set_progressive(flow_def2);
        struct upipe *deint = upipe_void_alloc_output(upipe,
                upipe_filter_blend_mgr,
                uprobe_pfx_alloc(uprobe_use(logger),
                                 loglevel, "deint"));
        assert(deint != NULL);
        upipe_release(upipe);
        upipe = deint;
    }

    if (wanted_hsize != hsize) {
        uref_pic_flow_set_hsize(flow_def2, wanted_hsize);
        struct upipe *sws = upipe_flow_alloc_output(upipe, upipe_sws_mgr,
                uprobe_pfx_alloc_va(uprobe_use(logger),
                                    loglevel, "sws"), flow_def2);
        assert(sws != NULL);
        upipe_release(upipe);
        upipe = sws;
    }

    uref_pic_flow_clear_format(flow_def2);
    uref_flow_set_def(flow_def2, "block.mjpeg.pic.");
    struct upipe *jpegenc = upipe_flow_alloc_output(upipe, upipe_avcenc_mgr,
            uprobe_pfx_alloc_va(uprobe_use(logger),
                                loglevel, "jpeg"), flow_def2);
    assert(jpegenc != NULL);
    upipe_release(upipe);
    upipe_set_option(jpegenc, "qmax", "2");
    upipe = jpegenc;

    struct upipe *urefprobe = upipe_void_alloc_output(upipe,
            upipe_probe_uref_mgr,
            uprobe_pfx_alloc_va(uprobe_use(&uprobe_uref),
                                loglevel, "urefprobe"));
    assert(urefprobe != NULL);
    upipe_release(upipe);
    upipe = urefprobe;

    struct upipe *fsink = upipe_void_alloc_output(upipe, upipe_fsink_mgr,
            uprobe_pfx_alloc_va(uprobe_use(logger),
            ((loglevel > UPROBE_LOG_DEBUG) ? UPROBE_LOG_WARNING : loglevel),
            "jpegsink"));
    assert(fsink != NULL);
    upipe_release(upipe);
    upipe_fsink_set_path(fsink, dstpath, UPIPE_FSINK_OVERWRITE);
    upipe = fsink;

    uref_free(flow_def2);
    upipe_release(upipe);
    return UBASE_ERR_NONE;
}
Exemple #4
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;
}
Exemple #5
0
/** @internal @This handles the input uref.
 *
 * @param upipe description structure of the pipe
 * @param uref input uref
 * @param upump_p reference to pump that generated the buffer
 */
static void upipe_vblk_input(struct upipe *upipe,
                             struct uref *uref,
                             struct upump **upump_p)
{
    struct upipe_vblk *upipe_vblk = upipe_vblk_from_upipe(upipe);
    struct uref *flow_def = upipe_vblk->flow_def;
    struct uref *input_flow_def = upipe_vblk->input_flow_def;

    if (uref->ubuf) {
        upipe_vblk_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");
        uref_free(uref);
        return;
    }

    if (unlikely(!upipe_vblk->ubuf_mgr)) {
        upipe_warn(upipe, "no ubuf manager set");
        uref_free(uref);
        return;
    }

    if (unlikely(!upipe_vblk->ubuf)) {
        upipe_verbose(upipe, "allocate blank picture");

        uint64_t hsize, vsize;
        ubase_assert(uref_pic_flow_get_hsize(upipe_vblk->flow_def, &hsize));
        ubase_assert(uref_pic_flow_get_vsize(upipe_vblk->flow_def, &vsize));

        upipe_vblk->ubuf = ubuf_pic_alloc(upipe_vblk->ubuf_mgr, hsize, vsize);
        if (unlikely(!upipe_vblk->ubuf)) {
            upipe_err(upipe, "fail to allocate picture");
            uref_free(uref);
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            return;
        }
        ubuf_pic_clear(upipe_vblk->ubuf, 0, 0, -1, -1, 1);
    }

    struct ubuf *ubuf = ubuf_dup(upipe_vblk->ubuf);
    if (unlikely(!ubuf)) {
        upipe_err(upipe, "fail to duplicate blank picture");
        uref_free(uref);
        upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
        return;
    }

    uref_attach_ubuf(uref, ubuf);
    if (ubase_check(uref_pic_get_progressive(flow_def)))
        uref_pic_set_progressive(uref);

    upipe_vblk_output(upipe, uref, upump_p);
}