static void pic_fill_in(struct ubuf *ubuf) { size_t hsize, vsize; uint8_t macropixel; ubase_assert(ubuf_pic_size(ubuf, &hsize, &vsize, ¯opixel)); 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, ¯opixel_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)); } }
/** @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); }