Ejemplo n.º 1
0
/** @internal @This merges a PSI section.
 *
 * @param upipe description structure of the pipe
 * @param uref uref pointing to (part of) a PSI section
 * @param upump_p reference to pump that generated the buffer
 * @return false if the uref has been entirely consumed
 */
static bool upipe_ts_psim_merge(struct upipe *upipe, struct uref *uref,
                                struct upump **upump_p)
{
    struct upipe_ts_psim *upipe_ts_psim = upipe_ts_psim_from_upipe(upipe);
    if (upipe_ts_psim->next_uref != NULL) {
        struct ubuf *ubuf = ubuf_dup(uref->ubuf);
        if (unlikely(ubuf == NULL ||
                     !ubase_check(uref_block_append(upipe_ts_psim->next_uref, ubuf)))) {
            upipe_ts_psim_flush(upipe);
            if (ubuf != NULL)
                ubuf_free(ubuf);
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            return false;
        }
    } else {
        /* Check for stuffing */
        uint8_t table_id;
        if (unlikely(!ubase_check(uref_block_extract(uref, 0, 1, &table_id)) ||
                     table_id == 0xff)) {
            return false;
        }

        upipe_ts_psim->next_uref = uref_dup(uref);
        if (unlikely(upipe_ts_psim->next_uref == NULL)) {
            upipe_throw_fatal(upipe, UBASE_ERR_ALLOC);
            return false;
        }
    }

    size_t size = 0;
    UBASE_FATAL(upipe, uref_block_size(upipe_ts_psim->next_uref, &size))
    if (size < PSI_HEADER_SIZE)
        return false;

    uint8_t buffer[PSI_HEADER_SIZE];
    const uint8_t *psi_header = uref_block_peek(upipe_ts_psim->next_uref,
                                                0, PSI_HEADER_SIZE, buffer);
    assert(psi_header != NULL);

    uint16_t length = psi_get_length(psi_header);
    UBASE_FATAL(upipe, uref_block_peek_unmap(upipe_ts_psim->next_uref, 0,
                buffer, psi_header));

    if (unlikely(!psi_validate(psi_header) ||
                 length + PSI_HEADER_SIZE > PSI_PRIVATE_MAX_SIZE)) {
        upipe_warn(upipe, "wrong PSI header");
        upipe_ts_psim_flush(upipe);
        return false;
    }

    if (length + PSI_HEADER_SIZE > size)
        return false;

    UBASE_FATAL(upipe, uref_block_resize(upipe_ts_psim->next_uref, 0,
                length + PSI_HEADER_SIZE));
    upipe_ts_psim_output(upipe, upipe_ts_psim->next_uref, upump_p);
    upipe_ts_psim->next_uref = NULL;
    if (length + PSI_HEADER_SIZE == size)
        return false;

    size_t uref_size = 0;
    UBASE_FATAL(upipe, uref_block_size(uref, &uref_size))
    UBASE_FATAL(upipe, uref_block_resize(uref, length + PSI_HEADER_SIZE - (size - uref_size), -1));
    return true;
}
Ejemplo n.º 2
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);
}
Ejemplo n.º 3
0
int main(int argc, char **argv)
{
    struct umem_mgr *umem_mgr = umem_alloc_mgr_alloc();
    assert(umem_mgr != NULL);

    struct ubuf_mgr *mgr;
    struct ubuf *ubuf1, *ubuf2;
    const char *channel;
    size_t size;
    uint8_t sample_size;
    uint8_t *w;
    const uint8_t *r;

    /* packed s16 stereo */
    mgr = ubuf_sound_mem_mgr_alloc(UBUF_POOL_DEPTH, UBUF_POOL_DEPTH, umem_mgr,
                                   4, 32);
    assert(mgr != NULL);
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "lr"));

    ubuf1 = ubuf_sound_alloc(mgr, 32);
    assert(ubuf1 != NULL);

    ubase_assert(ubuf_sound_size(ubuf1, &size, &sample_size));
    assert(size == 32);
    assert(sample_size == 4);

    channel = NULL;
    unsigned int nb_planes = 0;
    while (ubase_check(ubuf_sound_plane_iterate(ubuf1, &channel)) &&
           channel != NULL) {
        nb_planes++;
        assert(!strcmp(channel, "lr"));
    }
    assert(nb_planes == 1);

    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "lr", 0, -1, &r));
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "lr", 0, -1));

    fill_in(ubuf1);

    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "lr", 2, 1, &r));
    assert(*r == 'l' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "lr", 2, 1));

    ubuf2 = ubuf_dup(ubuf1);
    assert(ubuf2 != NULL);
    ubase_nassert(ubuf_sound_plane_write_uint8_t(ubuf1, "lr", 0, -1, &w));
    ubuf_free(ubuf2);

    ubase_nassert(ubuf_sound_resize(ubuf1, 0, 33));

    ubase_assert(ubuf_sound_resize(ubuf1, 2, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "lr", 0, -1, &r));
    assert(r[0] == 'l' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "lr", 0, -1));

    ubase_assert(ubuf_sound_resize(ubuf1, 0, 29));

    ubuf_free(ubuf1);

    ubuf_mgr_release(mgr);

    /* planar float 5.1 */
    mgr = ubuf_sound_mem_mgr_alloc(UBUF_POOL_DEPTH, UBUF_POOL_DEPTH, umem_mgr,
                                   sizeof(float), 32);
    assert(mgr != NULL);
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "l"));
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "r"));
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "c"));
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "L"));
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "R"));
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "S"));

    ubuf1 = ubuf_sound_alloc(mgr, 32);
    assert(ubuf1 != NULL);

    ubase_assert(ubuf_sound_size(ubuf1, &size, &sample_size));
    assert(size == 32);
    assert(sample_size == sizeof(float));

    channel = NULL;
    nb_planes = 0;
    while (ubase_check(ubuf_sound_plane_iterate(ubuf1, &channel)) &&
           channel != NULL)
        nb_planes++;
    assert(nb_planes == 6);

    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "l", 0, -1, &r));
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "l", 0, -1));

    fill_in(ubuf1);

    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "l", 2, 1, &r));
    assert(*r == 'l' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "l", 2, 1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "r", 2, 1, &r));
    assert(*r == 'r' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "r", 2, 1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "c", 2, 1, &r));
    assert(*r == 'c' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "c", 2, 1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "L", 2, 1, &r));
    assert(*r == 'L' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "L", 2, 1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "R", 2, 1, &r));
    assert(*r == 'R' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "R", 2, 1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "S", 2, 1, &r));
    assert(*r == 'S' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "S", 2, 1));

    ubuf2 = ubuf_dup(ubuf1);
    assert(ubuf2 != NULL);
    ubase_nassert(ubuf_sound_plane_write_uint8_t(ubuf1, "l", 0, -1, &w));
    ubuf_free(ubuf2);

    ubase_nassert(ubuf_sound_resize(ubuf1, 0, 33));

    ubase_assert(ubuf_sound_resize(ubuf1, 2, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "l", 0, -1, &r));
    assert(r[0] == 'l' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "l", 0, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "r", 0, -1, &r));
    assert(r[0] == 'r' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "r", 0, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "c", 0, -1, &r));
    assert(r[0] == 'c' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "c", 0, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "L", 0, -1, &r));
    assert(r[0] == 'L' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "L", 0, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "R", 0, -1, &r));
    assert(r[0] == 'R' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "R", 0, -1));
    ubase_assert(ubuf_sound_plane_read_uint8_t(ubuf1, "S", 0, -1, &r));
    assert(r[0] == 'S' + 8);
    ubase_assert(ubuf_sound_plane_unmap(ubuf1, "S", 0, -1));

    ubase_assert(ubuf_sound_resize(ubuf1, 0, 29));

    ubuf_free(ubuf1);
    ubuf_mgr_release(mgr);

    /* sound -> block transformation */
    mgr = ubuf_sound_mem_mgr_alloc(UBUF_POOL_DEPTH, UBUF_POOL_DEPTH, umem_mgr,
                                   4, 32);
    assert(mgr != NULL);
    ubase_assert(ubuf_sound_mem_mgr_add_plane(mgr, "lr"));

    ubuf1 = ubuf_sound_alloc(mgr, 32);
    assert(ubuf1 != NULL);
    fill_in(ubuf1);

    struct ubuf_mgr *block_mgr = ubuf_block_mem_mgr_alloc(UBUF_POOL_DEPTH,
            UBUF_POOL_DEPTH, umem_mgr, 0, 0, 0, 0);
    struct ubuf *ubuf_block = ubuf_block_mem_alloc_from_sound(block_mgr,
                                                              ubuf1, "lr");
    assert(ubuf_block != NULL);
    ubase_assert(ubuf_block_size(ubuf_block, &size));
    assert(size == 32 * 4);
    int size2 = -1;
    ubase_assert(ubuf_block_read(ubuf_block, 0, &size2, &r));
    assert(size2 == 32 * 4);
    assert(r[0] == 'l');

    ubuf_free(ubuf_block);
    ubuf_mgr_release(block_mgr);
    ubuf_free(ubuf1);

    ubuf_mgr_release(mgr);
    umem_mgr_release(umem_mgr);
    return 0;
}