Skip to content

Commit

Permalink
First alpha of experimental VP9 support in VDPAU VA-API Wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
xtknight committed Dec 21, 2019
1 parent 1d22f93 commit 894fe2e
Show file tree
Hide file tree
Showing 8 changed files with 984 additions and 14 deletions.
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ source_h = \
vdpau_mixer.h \
vdpau_subpic.h \
vdpau_video.h \
map.h \
$(source_glx_h) \
$(source_x11_h)

Expand All @@ -55,6 +56,7 @@ source_c = \
vdpau_mixer.c \
vdpau_subpic.c \
vdpau_video.c \
map.c \
$(source_glx_c) \
$(source_x11_c)

Expand All @@ -75,6 +77,7 @@ EXTRA_DIST = \
install-data-hook:
cd $(DESTDIR)$(LIBVA_DRIVERS_PATH) ; \
for drv in $(DRIVERS); do \
rm -f $${drv}_drv_video.so; \
ln -s vdpau_drv_video.so $${drv}_drv_video.so; \
done

Expand Down
264 changes: 264 additions & 0 deletions src/map.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
/**
* Copyright (c) 2014 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See LICENSE for details.
*/

#include <stdlib.h>
#include <string.h>
#include "map.h"

struct map_node_t {
unsigned hash;
void *value;
map_node_t *next;
/* int key[]; */
/* char value[]; */
};

/*
static unsigned map_hash(const char *str) {
unsigned hash = 5381;
while (*str) {
hash = ((hash << 5) + hash) ^ *str++;
}
return hash;
}
*/

static unsigned map_hash(int key) {
return (unsigned)key;
}

static map_node_t *map_newnode(int key, void *value, int vsize) {
map_node_t *node;
int ksize = sizeof(int);
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
node = malloc(sizeof(*node) + voffset + vsize);
if (!node) return NULL;
memcpy(node + 1, (void*)&key, ksize);
node->hash = map_hash(key);
node->value = ((char*) (node + 1)) + voffset;
memcpy(node->value, value, vsize);
return node;
}

/*
static map_node_t *map_newnode(const char *key, void *value, int vsize) {
map_node_t *node;
int ksize = strlen(key) + 1;
int voffset = ksize + ((sizeof(void*) - ksize) % sizeof(void*));
node = malloc(sizeof(*node) + voffset + vsize);
if (!node) return NULL;
memcpy(node + 1, key, ksize);
node->hash = map_hash(key);
node->value = ((char*) (node + 1)) + voffset;
memcpy(node->value, value, vsize);
return node;
}*/


static int map_bucketidx(map_base_t *m, unsigned hash) {
/* If the implementation is changed to allow a non-power-of-2 bucket count,
* the line below should be changed to use mod instead of AND */
return hash & (m->nbuckets - 1);
}


static void map_addnode(map_base_t *m, map_node_t *node) {
int n = map_bucketidx(m, node->hash);
node->next = m->buckets[n];
m->buckets[n] = node;
}


static int map_resize(map_base_t *m, int nbuckets) {
map_node_t *nodes, *node, *next;
map_node_t **buckets;
int i;
/* Chain all nodes together */
nodes = NULL;
i = m->nbuckets;
while (i--) {
node = (m->buckets)[i];
while (node) {
next = node->next;
node->next = nodes;
nodes = node;
node = next;
}
}
/* Reset buckets */
buckets = realloc(m->buckets, sizeof(*m->buckets) * nbuckets);
if (buckets != NULL) {
m->buckets = buckets;
m->nbuckets = nbuckets;
}
if (m->buckets) {
memset(m->buckets, 0, sizeof(*m->buckets) * m->nbuckets);
/* Re-add nodes to buckets */
node = nodes;
while (node) {
next = node->next;
map_addnode(m, node);
node = next;
}
}
/* Return error code if realloc() failed */
return (buckets == NULL) ? -1 : 0;
}

/*
static map_node_t **map_getref(map_base_t *m, const char *key) {
unsigned hash = map_hash(key);
map_node_t **next;
if (m->nbuckets > 0) {
next = &m->buckets[map_bucketidx(m, hash)];
while (*next) {
if ((*next)->hash == hash && !strcmp((char*) (*next + 1), key)) {
return next;
}
next = &(*next)->next;
}
}
return NULL;
}*/

static map_node_t **map_getref(map_base_t *m, int key) {
unsigned hash = map_hash(key);
map_node_t **next;
if (m->nbuckets > 0) {
next = &m->buckets[map_bucketidx(m, hash)];
while (*next) {
if ((*next)->hash == hash && *((int*)((char*)(*next + 1))) == key) {
return next;
}
next = &(*next)->next;
}
}
return NULL;
}

void map_deinit_(map_base_t *m) {
map_node_t *next, *node;
int i;
i = m->nbuckets;
while (i--) {
node = m->buckets[i];
while (node) {
next = node->next;
free(node);
node = next;
}
}
free(m->buckets);
}

/*
void *map_get_(map_base_t *m, const char *key) {
map_node_t **next = map_getref(m, key);
return next ? (*next)->value : NULL;
}
*/

void *map_get_(map_base_t *m, int key) {
map_node_t **next = map_getref(m, key);
return next ? (*next)->value : NULL;
}
/*
int map_set_(map_base_t *m, const char *key, void *value, int vsize) {
int n, err;
map_node_t **next, *node;
next = map_getref(m, key);
if (next) {
memcpy((*next)->value, value, vsize);
return 0;
}
node = map_newnode(key, value, vsize);
if (node == NULL) goto fail;
if (m->nnodes >= m->nbuckets) {
n = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1;
err = map_resize(m, n);
if (err) goto fail;
}
map_addnode(m, node);
m->nnodes++;
return 0;
fail:
if (node) free(node);
return -1;
}
*/

int map_set_(map_base_t *m, int key, void *value, int vsize) {
int n, err;
map_node_t **next, *node;
/* Find & replace existing node */
next = map_getref(m, key);
if (next) {
memcpy((*next)->value, value, vsize);
return 0;
}
/* Add new node */
node = map_newnode(key, value, vsize);
if (node == NULL) goto fail;
if (m->nnodes >= m->nbuckets) {
n = (m->nbuckets > 0) ? (m->nbuckets << 1) : 1;
err = map_resize(m, n);
if (err) goto fail;
}
map_addnode(m, node);
m->nnodes++;
return 0;
fail:
if (node) free(node);
return -1;
}

/*
void map_remove_(map_base_t *m, const char *key) {
map_node_t *node;
map_node_t **next = map_getref(m, key);
if (next) {
node = *next;
*next = (*next)->next;
free(node);
m->nnodes--;
}
}*/

void map_remove_(map_base_t *m, int key) {
map_node_t *node;
map_node_t **next = map_getref(m, key);
if (next) {
node = *next;
*next = (*next)->next;
free(node);
m->nnodes--;
}
}

map_iter_t map_iter_(void) {
map_iter_t iter;
iter.bucketidx = -1;
iter.node = NULL;
return iter;
}


const char *map_next_(map_base_t *m, map_iter_t *iter) {
if (iter->node) {
iter->node = iter->node->next;
if (iter->node == NULL) goto nextBucket;
} else {
nextBucket:
do {
if (++iter->bucketidx >= m->nbuckets) {
return NULL;
}
iter->node = m->buckets[iter->bucketidx];
} while (iter->node == NULL);
}
return (char*) (iter->node + 1);
}
83 changes: 83 additions & 0 deletions src/map.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/**
* Copyright (c) 2014 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See LICENSE for details.
*/

#ifndef MAP_H
#define MAP_H

#include <string.h>

#define MAP_VERSION "0.1.0"

struct map_node_t;
typedef struct map_node_t map_node_t;

typedef struct {
map_node_t **buckets;
unsigned nbuckets, nnodes;
} map_base_t;

typedef struct {
unsigned bucketidx;
map_node_t *node;
} map_iter_t;


#define map_t(T)\
struct { map_base_t base; T *ref; T tmp; }


#define map_init(m)\
memset(m, 0, sizeof(*(m)))


#define map_deinit(m)\
map_deinit_(&(m)->base)


#define map_get(m, key)\
( (m)->ref = map_get_(&(m)->base, key) )


#define map_set(m, key, value)\
( (m)->tmp = (value),\
map_set_(&(m)->base, key, &(m)->tmp, sizeof((m)->tmp)) )


#define map_remove(m, key)\
map_remove_(&(m)->base, key)


#define map_iter(m)\
map_iter_()


#define map_next(m, iter)\
map_next_(&(m)->base, iter)


/*void map_deinit_(map_base_t *m);
void *map_get_(map_base_t *m, const char *key);
int map_set_(map_base_t *m, const char *key, void *value, int vsize);
void map_remove_(map_base_t *m, const char *key);
map_iter_t map_iter_(void);
const char *map_next_(map_base_t *m, map_iter_t *iter);*/

void map_deinit_(map_base_t *m);
void *map_get_(map_base_t *m, int key);
int map_set_(map_base_t *m, int key, void *value, int vsize);
void map_remove_(map_base_t *m, int key);
map_iter_t map_iter_(void);
const char *map_next_(map_base_t *m, map_iter_t *iter);

typedef map_t(void*) map_void_t;
typedef map_t(char*) map_str_t;
typedef map_t(int) map_int_t;
typedef map_t(char) map_char_t;
typedef map_t(float) map_float_t;
typedef map_t(double) map_double_t;

#endif
Loading

0 comments on commit 894fe2e

Please sign in to comment.