-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First alpha of experimental VP9 support in VDPAU VA-API Wrapper
- Loading branch information
Showing
8 changed files
with
984 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.