mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-24 01:00:37 +00:00
1cf3cae5e1
Add an element that converts AYUV video frames to a DVB subpicture stream. It's fairly simple for now. Later it would be good to support input via a stream that contains only GstVideoOverlayComposition meta. The element searches each input video frame for the largest sub-region containing non-transparent pixels and encodes that as a single DVB subpicture region. It can also do palette reduction of the input frames using code taken from libimagequant. There are various FIXME for potential improvements for now, but it works. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-bad/-/merge_requests/1227>
69 lines
1.9 KiB
C
69 lines
1.9 KiB
C
|
|
#include "libimagequant.h"
|
|
#include "mempool.h"
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
#include <assert.h>
|
|
|
|
#define ALIGN_MASK 15UL
|
|
#define MEMPOOL_RESERVED ((sizeof(struct mempool)+ALIGN_MASK) & ~ALIGN_MASK)
|
|
|
|
struct mempool
|
|
{
|
|
unsigned int used, size;
|
|
void *(*malloc) (size_t);
|
|
void (*free) (void *);
|
|
struct mempool *next;
|
|
};
|
|
LIQ_PRIVATE void *
|
|
mempool_create (mempool * mptr, const unsigned int size, unsigned int max_size,
|
|
void *(*malloc) (size_t), void (*free) (void *))
|
|
{
|
|
mempool old;
|
|
uintptr_t mptr_used_start;
|
|
|
|
if (*mptr && ((*mptr)->used + size) <= (*mptr)->size) {
|
|
unsigned int prevused = (*mptr)->used;
|
|
(*mptr)->used += (size + 15UL) & ~0xFUL;
|
|
return ((char *) (*mptr)) + prevused;
|
|
}
|
|
|
|
old = *mptr;
|
|
if (!max_size)
|
|
max_size = (1 << 17);
|
|
max_size = size + ALIGN_MASK > max_size ? size + ALIGN_MASK : max_size;
|
|
|
|
*mptr = malloc (MEMPOOL_RESERVED + max_size);
|
|
if (!*mptr)
|
|
return NULL;
|
|
**mptr = (struct mempool) {
|
|
.malloc = malloc,.free = free,.size = MEMPOOL_RESERVED + max_size,.used =
|
|
sizeof (struct mempool),.next = old,};
|
|
mptr_used_start = (uintptr_t) (*mptr) + (*mptr)->used;
|
|
(*mptr)->used += (ALIGN_MASK + 1 - (mptr_used_start & ALIGN_MASK)) & ALIGN_MASK; // reserve bytes required to make subsequent allocations aligned
|
|
assert (!(((uintptr_t) (*mptr) + (*mptr)->used) & ALIGN_MASK));
|
|
|
|
return mempool_alloc (mptr, size, size);
|
|
}
|
|
|
|
LIQ_PRIVATE void *
|
|
mempool_alloc (mempool * mptr, unsigned int size, unsigned int max_size)
|
|
{
|
|
if (((*mptr)->used + size) <= (*mptr)->size) {
|
|
unsigned int prevused = (*mptr)->used;
|
|
(*mptr)->used += (size + ALIGN_MASK) & ~ALIGN_MASK;
|
|
return ((char *) (*mptr)) + prevused;
|
|
}
|
|
|
|
return mempool_create (mptr, size, max_size, (*mptr)->malloc, (*mptr)->free);
|
|
}
|
|
|
|
LIQ_PRIVATE void
|
|
mempool_destroy (mempool m)
|
|
{
|
|
while (m) {
|
|
mempool next = m->next;
|
|
m->free (m);
|
|
m = next;
|
|
}
|
|
}
|