update nestegg, remove halloc

This commit is contained in:
j 2016-08-29 14:37:33 +02:00
parent 0bbb337e1c
commit 7d545960f6
9 changed files with 997 additions and 1038 deletions

View file

@ -1,5 +1,5 @@
PROG = oxframe
SRC = src/oxframe.c src/nestegg.c src/halloc/halloc.c
SRC = src/oxframe.c src/nestegg.c
PREFIX ?= /usr/local
BINDIR ?= ${DESTDIR}${PREFIX}/bin
@ -9,7 +9,7 @@ CC ?= gcc
CFLAGS ?= -Wall -Wno-parantheses -O3
FLAGS += -ffast-math -fsigned-char -fforce-addr -fomit-frame-pointer -finline-functions -funroll-loops
FLAGS = -DHAVE_VP9=1 ${CFLAGS}
FLAGS += -I. -Isrc -Isrc/halloc
FLAGS += -I. -Isrc
INSTALL = install
@ -27,7 +27,7 @@ ${PROG}: ${SRC}
${CC} -std=c99 ${FLAGS} ${INCLUDEFLAGS} -o ${PROG} ${SRC} ${LINKFLAGS}
clean:
-@rm -f ${PROG} *~ core *.core src/*.o src/halloc/src/*.o
-@rm -f ${PROG} *~ core *.core src/*.o
install: ${PROG}
${INSTALL} -c -m 555 -o root -g bin ${PROG} ${BINDIR}

View file

@ -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.

View file

@ -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

View file

@ -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);
}
}

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -7,6 +7,7 @@
#if !defined(NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79)
#define NESTEGG_671cac2a_365d_ed69_d7a3_4491d3538d79
#include <limits.h>
#include <stdint.h>
#if defined(__cplusplus)
@ -64,11 +65,13 @@ extern "C" {
#define NESTEGG_TRACK_VIDEO 0 /**< Track is of type video. */
#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_VORBIS 1 /**< Track uses Xiph Vorbis 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_UNKNOWN INT_MAX /**< Track uses unknown codec. */
#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. */
@ -86,6 +89,17 @@ extern "C" {
#define NESTEGG_LOG_ERROR 1000 /**< Error 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_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);
/** 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.
@param context Stream context initialized by #nestegg_init.
@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);
/** 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
parser will not be able to understand other offsets.
Must be used to seek to the start of a cluster; the parser will not be
able to understand other offsets.
@param context Stream context initialized by #nestegg_init.
@param offset Absolute offset in bytes.
@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.
@retval #NESTEGG_TRACK_VIDEO Track type is video.
@retval #NESTEGG_TRACK_AUDIO Track type is audio.
@retval #NESTEGG_TRACK_UNKNOWN Track type is unknown.
@retval -1 Error. */
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 track Zero based track number.
@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_OPUS Track codec is Opus.
@retval #NESTEGG_CODEC_UNKNOWN Track codec is unknown.
@retval -1 Error. */
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,
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
is typically the inverse of the video frame rate.
@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,
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
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
@ -302,6 +348,14 @@ int nestegg_read_packet(nestegg * context, nestegg_packet ** packet);
@param packet #nestegg_packet to be freed. @see nestegg_read_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.
@param packet Packet initialized by #nestegg_read_packet.
@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.
@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 -1 Error. */
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,
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.
@param context Stream context initialized by #nestegg_init.
@retval 0 The media has no cues.
@retval 1 The media has cues. */
int nestegg_has_cues(nestegg * context);
/**
* 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.
* @retval 0 The file is not a WebM file.
* @retval 1 The file is 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.
@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);
/**
* 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)
}
#endif