update nestegg, remove halloc
This commit is contained in:
parent
0bbb337e1c
commit
7d545960f6
9 changed files with 997 additions and 1038 deletions
6
Makefile
6
Makefile
|
@ -1,5 +1,5 @@
|
||||||
PROG = oxframe
|
PROG = oxframe
|
||||||
SRC = src/oxframe.c src/nestegg.c src/halloc/halloc.c
|
SRC = src/oxframe.c src/nestegg.c
|
||||||
|
|
||||||
PREFIX ?= /usr/local
|
PREFIX ?= /usr/local
|
||||||
BINDIR ?= ${DESTDIR}${PREFIX}/bin
|
BINDIR ?= ${DESTDIR}${PREFIX}/bin
|
||||||
|
@ -9,7 +9,7 @@ CC ?= gcc
|
||||||
CFLAGS ?= -Wall -Wno-parantheses -O3
|
CFLAGS ?= -Wall -Wno-parantheses -O3
|
||||||
FLAGS += -ffast-math -fsigned-char -fforce-addr -fomit-frame-pointer -finline-functions -funroll-loops
|
FLAGS += -ffast-math -fsigned-char -fforce-addr -fomit-frame-pointer -finline-functions -funroll-loops
|
||||||
FLAGS = -DHAVE_VP9=1 ${CFLAGS}
|
FLAGS = -DHAVE_VP9=1 ${CFLAGS}
|
||||||
FLAGS += -I. -Isrc -Isrc/halloc
|
FLAGS += -I. -Isrc
|
||||||
|
|
||||||
INSTALL = install
|
INSTALL = install
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ ${PROG}: ${SRC}
|
||||||
${CC} -std=c99 ${FLAGS} ${INCLUDEFLAGS} -o ${PROG} ${SRC} ${LINKFLAGS}
|
${CC} -std=c99 ${FLAGS} ${INCLUDEFLAGS} -o ${PROG} ${SRC} ${LINKFLAGS}
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-@rm -f ${PROG} *~ core *.core src/*.o src/halloc/src/*.o
|
-@rm -f ${PROG} *~ core *.core src/*.o
|
||||||
|
|
||||||
install: ${PROG}
|
install: ${PROG}
|
||||||
${INSTALL} -c -m 555 -o root -g bin ${PROG} ${BINDIR}
|
${INSTALL} -c -m 555 -o root -g bin ${PROG} ${BINDIR}
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
halloc 1.2.1
|
|
||||||
============
|
|
||||||
|
|
||||||
Hierarchical memory heap interface - an extension to standard
|
|
||||||
malloc/free interface that simplifies tasks of memory disposal
|
|
||||||
when allocated structures exhibit hierarchical properties.
|
|
||||||
|
|
||||||
http://swapped.cc/halloc
|
|
||||||
=
|
|
||||||
To build libhalloc.a with GNU tools run
|
|
||||||
make
|
|
||||||
|
|
||||||
To install in /usr/include and /usr/lib
|
|
||||||
make install
|
|
||||||
|
|
||||||
To cleanup the build files
|
|
||||||
make clean
|
|
||||||
=
|
|
||||||
halloc-1.2.1
|
|
||||||
* fixed a double-free bug in _set_allocator() as per
|
|
||||||
Matthew Gregan comments
|
|
||||||
|
|
||||||
* switched to using NULL instead of 0 where applicable
|
|
||||||
|
|
||||||
halloc-1.2.0
|
|
||||||
* added missing <string.h> include to halloc.c
|
|
||||||
|
|
||||||
* improved standard compliance thanks to the feedback
|
|
||||||
received from Stan Tobias. Two things were fixed -
|
|
||||||
|
|
||||||
- hblock_t structure no longer uses zero-sized 'data'
|
|
||||||
array, which happened to be common, but non-standard
|
|
||||||
extension;
|
|
||||||
|
|
||||||
- secondly, added the code to test the behaviour of
|
|
||||||
realloc(ptr, 0). Standard allows it NOT to act as
|
|
||||||
free(), in which case halloc will use its own version
|
|
||||||
of allocator calling free() when neccessary.
|
|
||||||
|
|
||||||
halloc-1.1.0
|
|
||||||
* initial public release (rewrite of hhmalloc library)
|
|
||||||
|
|
||||||
=============================================================================
|
|
||||||
Copyright (c) 2004-2010, Alex Pankratov (ap@swapped.cc). All rights reserved.
|
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2010 Alex Pankratov. All rights reserved.
|
|
||||||
*
|
|
||||||
* Hierarchical memory allocator, 1.2.1
|
|
||||||
* http://swapped.cc/halloc
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The program is distributed under terms of BSD license.
|
|
||||||
* You can obtain the copy of the license by visiting:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/bsd-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBP_ALIGN_H_
|
|
||||||
#define _LIBP_ALIGN_H_
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
|
||||||
/*
|
|
||||||
* MSVC defines max_align_t as a double.
|
|
||||||
*/
|
|
||||||
typedef double max_align_t;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
/*
|
|
||||||
* a type with the most strict alignment requirements
|
|
||||||
*/
|
|
||||||
union max_align
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
short s;
|
|
||||||
long l;
|
|
||||||
int i;
|
|
||||||
float f;
|
|
||||||
double d;
|
|
||||||
void * v;
|
|
||||||
void (*q)(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef union max_align max_align_t;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,257 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004i-2010 Alex Pankratov. All rights reserved.
|
|
||||||
*
|
|
||||||
* Hierarchical memory allocator, 1.2.1
|
|
||||||
* http://swapped.cc/halloc
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The program is distributed under terms of BSD license.
|
|
||||||
* You can obtain the copy of the license by visiting:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/bsd-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdlib.h> /* realloc */
|
|
||||||
#include <string.h> /* memset & co */
|
|
||||||
|
|
||||||
#include "halloc.h"
|
|
||||||
#include "align.h"
|
|
||||||
#include "hlist.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
* block control header
|
|
||||||
*/
|
|
||||||
typedef struct hblock
|
|
||||||
{
|
|
||||||
#ifndef NDEBUG
|
|
||||||
#define HH_MAGIC 0x20040518L
|
|
||||||
long magic;
|
|
||||||
#endif
|
|
||||||
hlist_item_t siblings; /* 2 pointers */
|
|
||||||
hlist_head_t children; /* 1 pointer */
|
|
||||||
max_align_t data[1]; /* not allocated, see below */
|
|
||||||
|
|
||||||
} hblock_t;
|
|
||||||
|
|
||||||
#define sizeof_hblock offsetof(hblock_t, data)
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
realloc_t halloc_allocator = NULL;
|
|
||||||
|
|
||||||
#define allocator halloc_allocator
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static methods
|
|
||||||
*/
|
|
||||||
int halloc_set_allocator(realloc_t realloc_func);
|
|
||||||
static void * _realloc(void * ptr, size_t n);
|
|
||||||
|
|
||||||
static int _relate(hblock_t * b, hblock_t * p);
|
|
||||||
static void _free_children(hblock_t * p);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Core API
|
|
||||||
*/
|
|
||||||
void * halloc(void * ptr, size_t len)
|
|
||||||
{
|
|
||||||
hblock_t * p;
|
|
||||||
|
|
||||||
/* set up default allocator */
|
|
||||||
if (! allocator)
|
|
||||||
{
|
|
||||||
if (halloc_set_allocator(realloc) == 0)
|
|
||||||
{
|
|
||||||
halloc_set_allocator(_realloc);
|
|
||||||
}
|
|
||||||
assert(allocator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calloc */
|
|
||||||
if (! ptr)
|
|
||||||
{
|
|
||||||
if (! len)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
p = allocator(0, len + sizeof_hblock);
|
|
||||||
if (! p)
|
|
||||||
return NULL;
|
|
||||||
#ifndef NDEBUG
|
|
||||||
p->magic = HH_MAGIC;
|
|
||||||
#endif
|
|
||||||
hlist_init(&p->children);
|
|
||||||
hlist_init_item(&p->siblings);
|
|
||||||
|
|
||||||
return p->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = structof(ptr, hblock_t, data);
|
|
||||||
assert(p->magic == HH_MAGIC);
|
|
||||||
|
|
||||||
/* realloc */
|
|
||||||
if (len)
|
|
||||||
{
|
|
||||||
p = allocator(p, len + sizeof_hblock);
|
|
||||||
if (! p)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
hlist_relink(&p->siblings);
|
|
||||||
hlist_relink_head(&p->children);
|
|
||||||
|
|
||||||
return p->data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* free */
|
|
||||||
_free_children(p);
|
|
||||||
hlist_del(&p->siblings);
|
|
||||||
allocator(p, 0);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void hattach(void * block, void * parent)
|
|
||||||
{
|
|
||||||
hblock_t * b, * p;
|
|
||||||
|
|
||||||
if (! block)
|
|
||||||
{
|
|
||||||
assert(! parent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* detach */
|
|
||||||
b = structof(block, hblock_t, data);
|
|
||||||
assert(b->magic == HH_MAGIC);
|
|
||||||
|
|
||||||
hlist_del(&b->siblings);
|
|
||||||
|
|
||||||
if (! parent)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* attach */
|
|
||||||
p = structof(parent, hblock_t, data);
|
|
||||||
assert(p->magic == HH_MAGIC);
|
|
||||||
|
|
||||||
/* sanity checks */
|
|
||||||
assert(b != p); /* trivial */
|
|
||||||
assert(! _relate(p, b)); /* heavy ! */
|
|
||||||
|
|
||||||
hlist_add(&p->children, &b->siblings);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* malloc/free api
|
|
||||||
*/
|
|
||||||
void * h_malloc(size_t len)
|
|
||||||
{
|
|
||||||
return halloc(0, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void * h_calloc(size_t n, size_t len)
|
|
||||||
{
|
|
||||||
void * ptr = halloc(0, len*=n);
|
|
||||||
return ptr ? memset(ptr, 0, len) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * h_realloc(void * ptr, size_t len)
|
|
||||||
{
|
|
||||||
return halloc(ptr, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
void h_free(void * ptr)
|
|
||||||
{
|
|
||||||
halloc(ptr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char * h_strdup(const char * str)
|
|
||||||
{
|
|
||||||
size_t len = strlen(str);
|
|
||||||
char * ptr = halloc(0, len + 1);
|
|
||||||
return ptr ? (ptr[len] = 0, memcpy(ptr, str, len)) : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static stuff
|
|
||||||
*/
|
|
||||||
int halloc_set_allocator(realloc_t realloc_func)
|
|
||||||
{
|
|
||||||
void * p;
|
|
||||||
assert(! allocator);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the purpose of the test below is to check the behaviour
|
|
||||||
* of realloc(ptr, 0), which is defined in the standard
|
|
||||||
* as an implementation-specific. if it returns zero,
|
|
||||||
* then it's equivalent to free(). it can however return
|
|
||||||
* non-zero, in which case it cannot be used for freeing
|
|
||||||
* memory blocks and we'll need to supply our own version
|
|
||||||
*
|
|
||||||
* Thanks to Stan Tobias for pointing this tricky part out.
|
|
||||||
*/
|
|
||||||
if (! (p = realloc_func(NULL, 1)))
|
|
||||||
/* hmm */
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if ((p = realloc_func(p, 0)))
|
|
||||||
{
|
|
||||||
/* realloc_func cannot be used as free() */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
allocator = realloc_func;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void * _realloc(void * ptr, size_t n)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* free'ing realloc()
|
|
||||||
*/
|
|
||||||
if (n)
|
|
||||||
return realloc(ptr, n);
|
|
||||||
free(ptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _relate(hblock_t * b, hblock_t * p)
|
|
||||||
{
|
|
||||||
hlist_item_t * i;
|
|
||||||
|
|
||||||
if (!b || !p)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* since there is no 'parent' pointer, which would've allowed
|
|
||||||
* O(log(n)) upward traversal, the check must use O(n) downward
|
|
||||||
* iteration of the entire hierarchy; and this can be VERY SLOW
|
|
||||||
*/
|
|
||||||
hlist_for_each(i, &p->children)
|
|
||||||
{
|
|
||||||
hblock_t * q = structof(i, hblock_t, siblings);
|
|
||||||
if (q == b || _relate(b, q))
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _free_children(hblock_t * p)
|
|
||||||
{
|
|
||||||
hlist_item_t * i, * tmp;
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
/*
|
|
||||||
* this catches loops in hierarchy with almost zero
|
|
||||||
* overhead (compared to _relate() running time)
|
|
||||||
*/
|
|
||||||
assert(p && p->magic == HH_MAGIC);
|
|
||||||
p->magic = 0;
|
|
||||||
#endif
|
|
||||||
hlist_for_each_safe(i, tmp, &p->children)
|
|
||||||
{
|
|
||||||
hblock_t * q = structof(i, hblock_t, siblings);
|
|
||||||
_free_children(q);
|
|
||||||
allocator(q, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2010 Alex Pankratov. All rights reserved.
|
|
||||||
*
|
|
||||||
* Hierarchical memory allocator, 1.2.1
|
|
||||||
* http://swapped.cc/halloc
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The program is distributed under terms of BSD license.
|
|
||||||
* You can obtain the copy of the license by visiting:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/bsd-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBP_HALLOC_H_
|
|
||||||
#define _LIBP_HALLOC_H_
|
|
||||||
|
|
||||||
#include <stddef.h> /* size_t */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Core API
|
|
||||||
*/
|
|
||||||
void * halloc (void * block, size_t len);
|
|
||||||
void hattach(void * block, void * parent);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* standard malloc/free api
|
|
||||||
*/
|
|
||||||
void * h_malloc (size_t len);
|
|
||||||
void * h_calloc (size_t n, size_t len);
|
|
||||||
void * h_realloc(void * p, size_t len);
|
|
||||||
void h_free (void * p);
|
|
||||||
char * h_strdup (const char * str);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the underlying allocator
|
|
||||||
*/
|
|
||||||
typedef void * (* realloc_t)(void * ptr, size_t len);
|
|
||||||
|
|
||||||
extern realloc_t halloc_allocator;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,136 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2010 Alex Pankratov. All rights reserved.
|
|
||||||
*
|
|
||||||
* Hierarchical memory allocator, 1.2.1
|
|
||||||
* http://swapped.cc/halloc
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The program is distributed under terms of BSD license.
|
|
||||||
* You can obtain the copy of the license by visiting:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/bsd-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBP_HLIST_H_
|
|
||||||
#define _LIBP_HLIST_H_
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include "macros.h" /* static_inline */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* weak double-linked list w/ tail sentinel
|
|
||||||
*/
|
|
||||||
typedef struct hlist_head hlist_head_t;
|
|
||||||
typedef struct hlist_item hlist_item_t;
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
struct hlist_head
|
|
||||||
{
|
|
||||||
hlist_item_t * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hlist_item
|
|
||||||
{
|
|
||||||
hlist_item_t * next;
|
|
||||||
hlist_item_t ** prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* shared tail sentinel
|
|
||||||
*/
|
|
||||||
struct hlist_item hlist_null;
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define __hlist_init(h) { &hlist_null }
|
|
||||||
#define __hlist_init_item(i) { &hlist_null, &(i).next }
|
|
||||||
|
|
||||||
static_inline void hlist_init(hlist_head_t * h);
|
|
||||||
static_inline void hlist_init_item(hlist_item_t * i);
|
|
||||||
|
|
||||||
/* static_inline void hlist_purge(hlist_head_t * h); */
|
|
||||||
|
|
||||||
/* static_inline bool_t hlist_empty(const hlist_head_t * h); */
|
|
||||||
|
|
||||||
/* static_inline hlist_item_t * hlist_head(const hlist_head_t * h); */
|
|
||||||
|
|
||||||
/* static_inline hlist_item_t * hlist_next(const hlist_item_t * i); */
|
|
||||||
/* static_inline hlist_item_t * hlist_prev(const hlist_item_t * i,
|
|
||||||
const hlist_head_t * h); */
|
|
||||||
|
|
||||||
static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i);
|
|
||||||
|
|
||||||
/* static_inline void hlist_add_prev(hlist_item_t * l, hlist_item_t * i); */
|
|
||||||
/* static_inline void hlist_add_next(hlist_item_t * l, hlist_item_t * i); */
|
|
||||||
|
|
||||||
static_inline void hlist_del(hlist_item_t * i);
|
|
||||||
|
|
||||||
static_inline void hlist_relink(hlist_item_t * i);
|
|
||||||
static_inline void hlist_relink_head(hlist_head_t * h);
|
|
||||||
|
|
||||||
#define hlist_for_each(i, h) \
|
|
||||||
for (i = (h)->next; i != &hlist_null; i = i->next)
|
|
||||||
|
|
||||||
#define hlist_for_each_safe(i, tmp, h) \
|
|
||||||
for (i = (h)->next, tmp = i->next; \
|
|
||||||
i!= &hlist_null; \
|
|
||||||
i = tmp, tmp = i->next)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* static
|
|
||||||
*/
|
|
||||||
static_inline void hlist_init(hlist_head_t * h)
|
|
||||||
{
|
|
||||||
assert(h);
|
|
||||||
h->next = &hlist_null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_inline void hlist_init_item(hlist_item_t * i)
|
|
||||||
{
|
|
||||||
assert(i);
|
|
||||||
i->prev = &i->next;
|
|
||||||
i->next = &hlist_null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i)
|
|
||||||
{
|
|
||||||
hlist_item_t * next;
|
|
||||||
assert(h && i);
|
|
||||||
|
|
||||||
next = i->next = h->next;
|
|
||||||
next->prev = &i->next;
|
|
||||||
h->next = i;
|
|
||||||
i->prev = &h->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_inline void hlist_del(hlist_item_t * i)
|
|
||||||
{
|
|
||||||
hlist_item_t * next;
|
|
||||||
assert(i);
|
|
||||||
|
|
||||||
next = i->next;
|
|
||||||
next->prev = i->prev;
|
|
||||||
*i->prev = next;
|
|
||||||
|
|
||||||
hlist_init_item(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
static_inline void hlist_relink(hlist_item_t * i)
|
|
||||||
{
|
|
||||||
assert(i);
|
|
||||||
*i->prev = i;
|
|
||||||
i->next->prev = &i->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static_inline void hlist_relink_head(hlist_head_t * h)
|
|
||||||
{
|
|
||||||
assert(h);
|
|
||||||
h->next->prev = &h->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2004-2010 Alex Pankratov. All rights reserved.
|
|
||||||
*
|
|
||||||
* Hierarchical memory allocator, 1.2.1
|
|
||||||
* http://swapped.cc/halloc
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The program is distributed under terms of BSD license.
|
|
||||||
* You can obtain the copy of the license by visiting:
|
|
||||||
*
|
|
||||||
* http://www.opensource.org/licenses/bsd-license.php
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _LIBP_MACROS_H_
|
|
||||||
#define _LIBP_MACROS_H_
|
|
||||||
|
|
||||||
#include <stddef.h> /* offsetof */
|
|
||||||
|
|
||||||
/*
|
|
||||||
restore pointer to the structure by a pointer to its field
|
|
||||||
*/
|
|
||||||
#define structof(p,t,f) ((t*)(- (ptrdiff_t) offsetof(t,f) + (char*)(p)))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* redefine for the target compiler
|
|
||||||
*/
|
|
||||||
#ifdef _WIN32
|
|
||||||
#define static_inline static __inline
|
|
||||||
#else
|
|
||||||
#define static_inline static __inline__
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
1117
src/nestegg.c
1117
src/nestegg.c
File diff suppressed because it is too large
Load diff
112
src/nestegg.h
112
src/nestegg.h
|
@ -7,6 +7,7 @@
|
||||||
#if !defined(NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79)
|
#if !defined(NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79)
|
||||||
#define NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
|
#define NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
|
@ -64,11 +65,13 @@ extern "C" {
|
||||||
|
|
||||||
#define NESTEGG_TRACK_VIDEO 0 /**< Track is of type video. */
|
#define NESTEGG_TRACK_VIDEO 0 /**< Track is of type video. */
|
||||||
#define NESTEGG_TRACK_AUDIO 1 /**< Track is of type audio. */
|
#define NESTEGG_TRACK_AUDIO 1 /**< Track is of type audio. */
|
||||||
|
#define NESTEGG_TRACK_UNKNOWN INT_MAX /**< Track is of type unknown. */
|
||||||
|
|
||||||
#define NESTEGG_CODEC_VP8 0 /**< Track uses Google On2 VP8 codec. */
|
#define NESTEGG_CODEC_VP8 0 /**< Track uses Google On2 VP8 codec. */
|
||||||
#define NESTEGG_CODEC_VORBIS 1 /**< Track uses Xiph Vorbis codec. */
|
#define NESTEGG_CODEC_VORBIS 1 /**< Track uses Xiph Vorbis codec. */
|
||||||
#define NESTEGG_CODEC_VP9 2 /**< Track uses Google On2 VP9 codec. */
|
#define NESTEGG_CODEC_VP9 2 /**< Track uses Google On2 VP9 codec. */
|
||||||
#define NESTEGG_CODEC_OPUS 3 /**< Track uses Xiph Opus codec. */
|
#define NESTEGG_CODEC_OPUS 3 /**< Track uses Xiph Opus codec. */
|
||||||
|
#define NESTEGG_CODEC_UNKNOWN INT_MAX /**< Track uses unknown codec. */
|
||||||
|
|
||||||
#define NESTEGG_VIDEO_MONO 0 /**< Track is mono video. */
|
#define NESTEGG_VIDEO_MONO 0 /**< Track is mono video. */
|
||||||
#define NESTEGG_VIDEO_STEREO_LEFT_RIGHT 1 /**< Track is side-by-side stereo video. Left first. */
|
#define NESTEGG_VIDEO_STEREO_LEFT_RIGHT 1 /**< Track is side-by-side stereo video. Left first. */
|
||||||
|
@ -86,6 +89,17 @@ extern "C" {
|
||||||
#define NESTEGG_LOG_ERROR 1000 /**< Error level log message. */
|
#define NESTEGG_LOG_ERROR 1000 /**< Error level log message. */
|
||||||
#define NESTEGG_LOG_CRITICAL 10000 /**< Critical level log message. */
|
#define NESTEGG_LOG_CRITICAL 10000 /**< Critical level log message. */
|
||||||
|
|
||||||
|
#define NESTEGG_ENCODING_COMPRESSION 0 /**< Content encoding type is compression. */
|
||||||
|
#define NESTEGG_ENCODING_ENCRYPTION 1 /**< Content encoding type is encryption. */
|
||||||
|
|
||||||
|
#define NESTEGG_PACKET_HAS_SIGNAL_BYTE_FALSE 0 /**< Packet does not have signal byte */
|
||||||
|
#define NESTEGG_PACKET_HAS_SIGNAL_BYTE_UNENCRYPTED 1 /**< Packet has signal byte and is unencrypted */
|
||||||
|
#define NESTEGG_PACKET_HAS_SIGNAL_BYTE_ENCRYPTED 2 /**< Packet has signal byte and is encrypted */
|
||||||
|
|
||||||
|
#define NESTEGG_PACKET_HAS_KEYFRAME_FALSE 0 /**< Packet contains only keyframes. */
|
||||||
|
#define NESTEGG_PACKET_HAS_KEYFRAME_TRUE 1 /**< Packet does not contain any keyframes */
|
||||||
|
#define NESTEGG_PACKET_HAS_KEYFRAME_UNKNOWN 2 /**< Packet may or may not contain keyframes */
|
||||||
|
|
||||||
typedef struct nestegg nestegg; /**< Opaque handle referencing the stream state. */
|
typedef struct nestegg nestegg; /**< Opaque handle referencing the stream state. */
|
||||||
typedef struct nestegg_packet nestegg_packet; /**< Opaque handle referencing a packet of data. */
|
typedef struct nestegg_packet nestegg_packet; /**< Opaque handle referencing a packet of data. */
|
||||||
|
|
||||||
|
@ -171,7 +185,7 @@ void nestegg_destroy(nestegg * context);
|
||||||
int nestegg_duration(nestegg * context, uint64_t * duration);
|
int nestegg_duration(nestegg * context, uint64_t * duration);
|
||||||
|
|
||||||
/** Query the tstamp scale of the media stream in nanoseconds.
|
/** Query the tstamp scale of the media stream in nanoseconds.
|
||||||
Timecodes presented by nestegg have been scaled by this value
|
@note Timecodes presented by nestegg have been scaled by this value
|
||||||
before presentation to the caller.
|
before presentation to the caller.
|
||||||
@param context Stream context initialized by #nestegg_init.
|
@param context Stream context initialized by #nestegg_init.
|
||||||
@param scale Storage for the queried scale factor.
|
@param scale Storage for the queried scale factor.
|
||||||
|
@ -201,8 +215,8 @@ int nestegg_get_cue_point(nestegg * context, unsigned int cluster_num,
|
||||||
int64_t * end_pos, uint64_t * tstamp);
|
int64_t * end_pos, uint64_t * tstamp);
|
||||||
|
|
||||||
/** Seek to @a offset. Stream will seek directly to offset.
|
/** Seek to @a offset. Stream will seek directly to offset.
|
||||||
Should be used to seek to the start of a resync point, i.e. cluster; the
|
Must be used to seek to the start of a cluster; the parser will not be
|
||||||
parser will not be able to understand other offsets.
|
able to understand other offsets.
|
||||||
@param context Stream context initialized by #nestegg_init.
|
@param context Stream context initialized by #nestegg_init.
|
||||||
@param offset Absolute offset in bytes.
|
@param offset Absolute offset in bytes.
|
||||||
@retval 0 Success.
|
@retval 0 Success.
|
||||||
|
@ -224,6 +238,7 @@ int nestegg_track_seek(nestegg * context, unsigned int track, uint64_t tstamp);
|
||||||
@param track Zero based track number.
|
@param track Zero based track number.
|
||||||
@retval #NESTEGG_TRACK_VIDEO Track type is video.
|
@retval #NESTEGG_TRACK_VIDEO Track type is video.
|
||||||
@retval #NESTEGG_TRACK_AUDIO Track type is audio.
|
@retval #NESTEGG_TRACK_AUDIO Track type is audio.
|
||||||
|
@retval #NESTEGG_TRACK_UNKNOWN Track type is unknown.
|
||||||
@retval -1 Error. */
|
@retval -1 Error. */
|
||||||
int nestegg_track_type(nestegg * context, unsigned int track);
|
int nestegg_track_type(nestegg * context, unsigned int track);
|
||||||
|
|
||||||
|
@ -231,7 +246,10 @@ int nestegg_track_type(nestegg * context, unsigned int track);
|
||||||
@param context Stream context initialized by #nestegg_init.
|
@param context Stream context initialized by #nestegg_init.
|
||||||
@param track Zero based track number.
|
@param track Zero based track number.
|
||||||
@retval #NESTEGG_CODEC_VP8 Track codec is VP8.
|
@retval #NESTEGG_CODEC_VP8 Track codec is VP8.
|
||||||
|
@retval #NESTEGG_CODEC_VP9 Track codec is VP9.
|
||||||
@retval #NESTEGG_CODEC_VORBIS Track codec is Vorbis.
|
@retval #NESTEGG_CODEC_VORBIS Track codec is Vorbis.
|
||||||
|
@retval #NESTEGG_CODEC_OPUS Track codec is Opus.
|
||||||
|
@retval #NESTEGG_CODEC_UNKNOWN Track codec is unknown.
|
||||||
@retval -1 Error. */
|
@retval -1 Error. */
|
||||||
int nestegg_track_codec_id(nestegg * context, unsigned int track);
|
int nestegg_track_codec_id(nestegg * context, unsigned int track);
|
||||||
|
|
||||||
|
@ -277,6 +295,28 @@ int nestegg_track_video_params(nestegg * context, unsigned int track,
|
||||||
int nestegg_track_audio_params(nestegg * context, unsigned int track,
|
int nestegg_track_audio_params(nestegg * context, unsigned int track,
|
||||||
nestegg_audio_params * params);
|
nestegg_audio_params * params);
|
||||||
|
|
||||||
|
/** Query the encoding status for @a track. If a track has multiple encodings
|
||||||
|
the first will be returned.
|
||||||
|
@param context Stream context initialized by #nestegg_init.
|
||||||
|
@param track Zero based track number.
|
||||||
|
@retval #NESTEGG_ENCODING_COMPRESSION The track is compressed, but not encrypted.
|
||||||
|
@retval #NESTEGG_ENCODING_ENCRYPTION The track is encrypted and compressed.
|
||||||
|
@retval -1 Error. */
|
||||||
|
int nestegg_track_encoding(nestegg * context, unsigned int track);
|
||||||
|
|
||||||
|
/** Query the ContentEncKeyId for @a track. Will return an error if the track
|
||||||
|
in not encrypted, or is not recognized.
|
||||||
|
@param context Stream context initialized by #nestegg_init.
|
||||||
|
@param track Zero based track number.
|
||||||
|
@param content_enc_key_id Storage for queried id. The content encryption key used.
|
||||||
|
Owned by nestegg and will be freed separately.
|
||||||
|
@param content_enc_key_id_length Length of the queried ContentEncKeyId in bytes.
|
||||||
|
@retval 0 Success.
|
||||||
|
@retval -1 Error. */
|
||||||
|
int nestegg_track_content_enc_key_id(nestegg * context, unsigned int track,
|
||||||
|
unsigned char const ** content_enc_key_id,
|
||||||
|
size_t * content_enc_key_id_length);
|
||||||
|
|
||||||
/** Query the default frame duration for @a track. For a video track, this
|
/** Query the default frame duration for @a track. For a video track, this
|
||||||
is typically the inverse of the video frame rate.
|
is typically the inverse of the video frame rate.
|
||||||
@param context Stream context initialized by #nestegg_init.
|
@param context Stream context initialized by #nestegg_init.
|
||||||
|
@ -287,6 +327,12 @@ int nestegg_track_audio_params(nestegg * context, unsigned int track,
|
||||||
int nestegg_track_default_duration(nestegg * context, unsigned int track,
|
int nestegg_track_default_duration(nestegg * context, unsigned int track,
|
||||||
uint64_t * duration);
|
uint64_t * duration);
|
||||||
|
|
||||||
|
/** Reset parser state to the last valid state before nestegg_read_packet failed.
|
||||||
|
@param context Stream context initialized by #nestegg_init.
|
||||||
|
@retval 0 Success.
|
||||||
|
@retval -1 Error. */
|
||||||
|
int nestegg_read_reset(nestegg * context);
|
||||||
|
|
||||||
/** Read a packet of media data. A packet consists of one or more chunks of
|
/** Read a packet of media data. A packet consists of one or more chunks of
|
||||||
data associated with a single track. nestegg_read_packet should be
|
data associated with a single track. nestegg_read_packet should be
|
||||||
called in a loop while the return value is 1 to drive the stream parser
|
called in a loop while the return value is 1 to drive the stream parser
|
||||||
|
@ -302,6 +348,14 @@ int nestegg_read_packet(nestegg * context, nestegg_packet ** packet);
|
||||||
@param packet #nestegg_packet to be freed. @see nestegg_read_packet */
|
@param packet #nestegg_packet to be freed. @see nestegg_read_packet */
|
||||||
void nestegg_free_packet(nestegg_packet * packet);
|
void nestegg_free_packet(nestegg_packet * packet);
|
||||||
|
|
||||||
|
/** Query the keyframe status for a given packet.
|
||||||
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
|
@retval #NESTEGG_PACKET_HAS_KEYFRAME_FALSE Packet contains no keyframes.
|
||||||
|
@retval #NESTEGG_PACKET_HAS_KEYFRAME_TRUE Packet contains keyframes.
|
||||||
|
@retval #NESTEGG_PACKET_HAS_KEYFRAME_UNKNOWN Unknown packet keyframe content.
|
||||||
|
@retval -1 Error. */
|
||||||
|
int nestegg_packet_has_keyframe(nestegg_packet * packet);
|
||||||
|
|
||||||
/** Query the track number of @a packet.
|
/** Query the track number of @a packet.
|
||||||
@param packet Packet initialized by #nestegg_read_packet.
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
@param track Storage for the queried zero based track index.
|
@param track Storage for the queried zero based track index.
|
||||||
|
@ -325,7 +379,7 @@ int nestegg_packet_duration(nestegg_packet * packet, uint64_t * duration);
|
||||||
|
|
||||||
/** Query the number of data chunks contained in @a packet.
|
/** Query the number of data chunks contained in @a packet.
|
||||||
@param packet Packet initialized by #nestegg_read_packet.
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
@param count Storage for the queried timestamp in nanoseconds.
|
@param count Storage for the queried chunk count.
|
||||||
@retval 0 Success.
|
@retval 0 Success.
|
||||||
@retval -1 Error. */
|
@retval -1 Error. */
|
||||||
int nestegg_packet_count(nestegg_packet * packet, unsigned int * count);
|
int nestegg_packet_count(nestegg_packet * packet, unsigned int * count);
|
||||||
|
@ -362,28 +416,50 @@ int nestegg_packet_additional_data(nestegg_packet * packet, unsigned int id,
|
||||||
int nestegg_packet_discard_padding(nestegg_packet * packet,
|
int nestegg_packet_discard_padding(nestegg_packet * packet,
|
||||||
int64_t * discard_padding);
|
int64_t * discard_padding);
|
||||||
|
|
||||||
|
/** Query if a packet is encrypted.
|
||||||
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
|
@retval #NESTEGG_PACKET_HAS_SIGNAL_BYTE_FALSE No signal byte, encryption
|
||||||
|
information not read from packet.
|
||||||
|
@retval #NESTEGG_PACKET_HAS_SIGNAL_BYTE_UNENCRYPTED Encrypted bit not
|
||||||
|
set, encryption information not read from packet.
|
||||||
|
@retval #NESTEGG_PACKET_HAS_SIGNAL_BYTE_ENCRYPTED Encrypted bit set,
|
||||||
|
encryption infomation read from packet.
|
||||||
|
@retval -1 Error.*/
|
||||||
|
int nestegg_packet_encryption(nestegg_packet * packet);
|
||||||
|
|
||||||
|
/** Query the IV for an encrypted packet. Expects a packet from an encrypted
|
||||||
|
track, and will return error if given a packet that has no signal btye.
|
||||||
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
|
@param iv Storage for queried iv.
|
||||||
|
@param length Length of returned iv, may be 0.
|
||||||
|
The data is owned by the #nestegg_packet packet.
|
||||||
|
@retval 0 Success.
|
||||||
|
@retval -1 Error.
|
||||||
|
*/
|
||||||
|
int nestegg_packet_iv(nestegg_packet * packet, unsigned char const ** iv,
|
||||||
|
size_t * length);
|
||||||
|
|
||||||
|
/** Returns reference_block given packet
|
||||||
|
@param packet Packet initialized by #nestegg_read_packet.
|
||||||
|
@param reference_block pointer to store reference block in.
|
||||||
|
@retval 0 Success.
|
||||||
|
@retval -1 Error. */
|
||||||
|
int nestegg_packet_reference_block(nestegg_packet * packet,
|
||||||
|
int64_t * reference_block);
|
||||||
|
|
||||||
/** Query the presence of cues.
|
/** Query the presence of cues.
|
||||||
@param context Stream context initialized by #nestegg_init.
|
@param context Stream context initialized by #nestegg_init.
|
||||||
@retval 0 The media has no cues.
|
@retval 0 The media has no cues.
|
||||||
@retval 1 The media has cues. */
|
@retval 1 The media has cues. */
|
||||||
int nestegg_has_cues(nestegg * context);
|
int nestegg_has_cues(nestegg * context);
|
||||||
|
|
||||||
/**
|
/** Try to determine if the buffer looks like the beginning of a WebM file.
|
||||||
* Try to determine if the buffer looks like the beginning of a WebM file.
|
@param buffer A buffer containing the beginning of a media file.
|
||||||
*
|
@param length The size of the buffer.
|
||||||
* @param buffer A buffer containing the beginning of a media file.
|
@retval 0 The file is not a WebM file.
|
||||||
* @param length The size of the buffer.
|
@retval 1 The file is a WebM file. */
|
||||||
* @retval 0 The file is not a WebM file.
|
|
||||||
* @retval 1 The file is a WebM file. */
|
|
||||||
int nestegg_sniff(unsigned char const * buffer, size_t length);
|
int nestegg_sniff(unsigned char const * buffer, size_t length);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the underlying allocation function for library allocations.
|
|
||||||
*
|
|
||||||
* @param realloc_func The desired function.
|
|
||||||
*/
|
|
||||||
void nestegg_set_halloc_func(void * (* realloc_func)(void *, size_t));
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue