Example #1
0
static void pic_fill_in(struct ubuf *ubuf)
{
    size_t hsize, vsize;
    uint8_t macropixel;
    ubase_assert(ubuf_pic_size(ubuf, &hsize, &vsize, &macropixel));

    const char *chroma = NULL;
    while (ubase_check(ubuf_pic_plane_iterate(ubuf, &chroma)) &&
           chroma != NULL) {
        size_t stride;
        uint8_t hsub, vsub, macropixel_size;
        ubase_assert(ubuf_pic_plane_size(ubuf, chroma, &stride, &hsub, &vsub,
                                         &macropixel_size));
        int hoctets = hsize * macropixel_size / hsub / macropixel;
        uint8_t *buffer;
        ubase_assert(ubuf_pic_plane_write(ubuf, chroma, 0, 0, -1, -1, &buffer));

        for (int y = 0; y < vsize / vsub; y++) {
            for (int x = 0; x < hoctets; x++)
                buffer[x] = 1 + (y * hoctets) + x;
            buffer += stride;
        }
        ubase_assert(ubuf_pic_plane_unmap(ubuf, chroma, 0, 0, -1, -1));
    }
}
Example #2
0
/** @internal @This handles data from pic allocator.
 *
 * @param upipe description structure of the pipe
 * @param uref uref structure
 * @param upump_p reference to pump that generated the buffer
 */
static void upipe_tblk_handle_pic(struct upipe *upipe, struct uref *uref,
                                  struct upump **upump_p)
{
    struct upipe_tblk *upipe_tblk = upipe_tblk_from_upipe(upipe);

    /* Always operate on the first chroma plane. */
    const char *chroma = NULL;
    if (unlikely(uref->ubuf == NULL ||
                 !ubase_check(ubuf_pic_plane_iterate(uref->ubuf, &chroma)) ||
                 chroma == NULL)) {
        uref_free(uref);
        upipe_throw_error(upipe, UBASE_ERR_INVALID);
        return;
    }

    /* First try the ubuf_mem_shared method. */
    struct ubuf *ubuf = ubuf_block_mem_alloc_from_pic(upipe_tblk->ubuf_mgr,
                                                      uref->ubuf, chroma);
    if (unlikely(ubuf == NULL)) {
        /* We have to memcpy the thing. */
        size_t hsize, vsize, stride;
        uint8_t macropixel, hsub, vsub, macropixel_size;
        if (unlikely(!ubase_check(uref_pic_size(uref, NULL, &vsize,
                                                NULL)) ||
                     !ubase_check(uref_pic_plane_size(uref, chroma,
                             &stride, NULL, &vsub, NULL)))) {
            uref_free(uref);
            upipe_throw_error(upipe, UBASE_ERR_INVALID);
            return;
        }

        size_t size = stride * vsize / vsub;
        ubuf = ubuf_block_alloc(upipe_tblk->ubuf_mgr, size);
        if (unlikely(ubuf == NULL)) {
            uref_free(uref);
            upipe_throw_error(upipe, UBASE_ERR_ALLOC);
            return;
        }

        const uint8_t *r;
        if (unlikely(!ubase_check(uref_pic_plane_read(uref, chroma,
                            0, 0, -1, -1, &r)))) {
            ubuf_free(ubuf);
            uref_free(uref);
            upipe_throw_error(upipe, UBASE_ERR_ALLOC);
            return;
        }

        uint8_t *w;
        int end = -1;
        if (unlikely(!ubase_check(ubuf_block_write(ubuf, 0, &end, &w)))) {
            uref_pic_plane_unmap(uref, chroma, 0, 0, -1, -1);
            ubuf_free(ubuf);
            uref_free(uref);
            upipe_throw_error(upipe, UBASE_ERR_ALLOC);
            return;
        }

        memcpy(w, r, size);
        ubuf_block_unmap(ubuf, 0);
        uref_pic_plane_unmap(uref, chroma, 0, 0, -1, -1);
    }

    uref_attach_ubuf(uref, ubuf);
    upipe_tblk_output(upipe, uref, upump_p);
}