| #ifndef __TARKIN_H |
| #define __TARKIN_H |
| |
| #include <stdio.h> |
| #include "wavelet.h" |
| #include <ogg/ogg.h> |
| |
| |
| #define BUG(x...) \ |
| do { \ |
| printf("BUG in %s (%s: line %i): ", __FUNCTION__, __FILE__, __LINE__); \ |
| printf(#x); \ |
| printf("\n"); \ |
| exit (-1); \ |
| } while (0); |
| |
| |
| /* Theses determine what infos the packet comes with */ |
| #define TARKIN_PACK_EXAMPLE 1 |
| |
| typedef struct { |
| uint8_t *data; |
| uint32_t data_len; |
| uint32_t storage; |
| } TarkinPacket; |
| |
| |
| typedef enum { |
| TARKIN_GRAYSCALE, |
| TARKIN_RGB24, /* tight packed RGB */ |
| TARKIN_RGB32, /* 32bit, no alphachannel */ |
| TARKIN_RGBA, /* dito w/ alphachannel */ |
| TARKIN_YUV2, /* 16 bits YUV */ |
| TARKIN_YUV12, /* 12 bits YUV */ |
| TARKIN_FYUV, /* Tarkin's Fast YUV-like? */ |
| } TarkinColorFormat; |
| |
| #define TARKIN_INTERNAL_FORMAT TARKIN_FYUV |
| |
| typedef enum { |
| TARKIN_OK = 0, |
| TARKIN_IO_ERROR, |
| TARKIN_SIGNATURE_NOT_FOUND, |
| TARKIN_INVALID_LAYER, |
| TARKIN_INVALID_COLOR_FORMAT, |
| TARKIN_VERSION, |
| TARKIN_BAD_HEADER, |
| TARKIN_NOT_TARKIN, |
| TARKIN_FAULT, |
| TARKIN_UNUSED, |
| TARKIN_NEED_MORE, |
| TARKIN_NOT_IMPLEMENTED |
| } TarkinError; |
| |
| |
| |
| typedef struct { |
| uint32_t width; |
| uint32_t height; |
| uint32_t a_moments; |
| uint32_t s_moments; |
| uint32_t frames_per_buf; |
| uint32_t bitstream_len; /* for all color components, bytes */ |
| TarkinColorFormat format; |
| } TarkinVideoLayerDesc; |
| |
| |
| typedef struct { |
| TarkinVideoLayerDesc desc; |
| uint32_t n_comp; /* number of color components */ |
| Wavelet3DBuf **waveletbuf; |
| TarkinPacket *packet; |
| uint32_t current_frame_in_buf; |
| uint32_t frameno; |
| |
| void (*color_fwd_xform) (uint8_t *rgba, Wavelet3DBuf *yuva [], uint32_t count); |
| void (*color_inv_xform) (Wavelet3DBuf *yuva [], uint8_t *rgba, uint32_t count); |
| } TarkinVideoLayer; |
| |
| typedef struct { |
| uint32_t numerator; |
| uint32_t denominator; |
| } TarkinTime; /* Let's say the unit is 1 second */ |
| |
| typedef struct TarkinInfo { |
| int version; |
| int n_layers; |
| TarkinVideoLayer *layer; |
| TarkinTime inter; /* numerator == O if per-frame time info. */ |
| int frames_per_block; |
| int comp_per_block; /* AKA "packets per block" for now */ |
| uint32_t max_bitstream_len; |
| |
| /* The below bitrate declarations are *hints*. |
| Combinations of the three values carry the following implications: |
| |
| all three set to the same value: |
| implies a fixed rate bitstream |
| only nominal set: |
| implies a VBR stream that averages the nominal bitrate. No hard |
| upper/lower limit |
| upper and or lower set: |
| implies a VBR bitstream that obeys the bitrate limits. nominal |
| may also be set to give a nominal rate. |
| none set: |
| the coder does not care to speculate. |
| */ |
| |
| long bitrate_upper; |
| long bitrate_nominal; |
| long bitrate_lower; |
| long bitrate_window; |
| } TarkinInfo; |
| |
| /* This is used for encoding */ |
| typedef struct { |
| unsigned char *header; |
| unsigned char *header1; |
| unsigned char *header2; |
| } tarkin_header_store; |
| |
| |
| |
| |
| /* Some of the fields in TarkinStream are redundent with TarkinInfo ones |
| * and will probably get deleted, namely n_layers and frames_per_buf */ |
| typedef struct TarkinStream { |
| uint32_t n_layers; |
| TarkinVideoLayer *layer; |
| uint32_t current_frame; |
| uint32_t current_frame_in_buf; |
| ogg_int64_t packetno; |
| uint32_t frames_per_buf; |
| uint32_t max_bitstream_len; |
| TarkinInfo *ti; |
| tarkin_header_store headers; |
| /* These callbacks are only used for encoding */ |
| TarkinError (*free_frame)(void *tarkinstream, void *ptr); |
| /* These thing allows not to buffer but it needs global var in caller. */ |
| TarkinError (*packet_out)(void *tarkinstream, ogg_packet *ptr); |
| void * user_ptr; |
| } TarkinStream; |
| |
| |
| typedef struct TarkinComment{ |
| /* unlimited user comment fields. libtarkin writes 'libtarkin' |
| whatever vendor is set to in encode */ |
| char **user_comments; |
| int *comment_lengths; |
| int comments; |
| char *vendor; |
| |
| } TarkinComment; |
| |
| /* Tarkin PRIMITIVES: general ***************************************/ |
| |
| /* The Tarkin header is in three packets, the initial small packet in |
| the first page that identifies basic parameters, that is a TarkinInfo |
| structure, a second packet with bitstream comments and a third packet |
| that holds the layers description structures. */ |
| |
| |
| /* Theses are the very same than Vorbis versions, they could be shared. */ |
| extern TarkinStream* tarkin_stream_new (); |
| extern void tarkin_stream_destroy (TarkinStream *s); |
| extern void tarkin_info_init(TarkinInfo *vi); |
| extern void tarkin_info_clear(TarkinInfo *vi); |
| extern void tarkin_comment_init(TarkinComment *vc); |
| extern void tarkin_comment_add(TarkinComment *vc, char *comment); |
| extern void tarkin_comment_add_tag(TarkinComment *vc, |
| char *tag, char *contents); |
| extern char *tarkin_comment_query(TarkinComment *vc, char *tag, int count); |
| extern int tarkin_comment_query_count(TarkinComment *vc, char *tag); |
| extern void tarkin_comment_clear(TarkinComment *vc); |
| |
| /* Tarkin PRIMITIVES: analysis layer ****************************/ |
| /* Tarkin encoding is done this way : you init it passing a fresh |
| * TarkinStream and a fresh TarkinInfo which has at least the rate_num |
| * field renseigned. You also pass it two callback functions: free_frame() |
| * is called when the lib doesn't need a frame anymore, and packet_out |
| * is called when a packet is ready. The pointers given as arguments to |
| * these callback functions are of course only valid at the function call |
| * time. The user_ptr is stored in s and can be used by packet_out(). */ |
| extern int tarkin_analysis_init(TarkinStream *s, |
| TarkinInfo *ti, |
| TarkinError (*free_frame)(void *tarkinstream, void *ptr), |
| TarkinError (*packet_out)(void *tarkinstream, ogg_packet *ptr), |
| void *user_ptr |
| ); |
| /* Then you need to add at least a layer in your stream, passing a |
| * TarkinVideoLayerDesc renseigned at least on the width, height and |
| * format parameters. */ |
| extern int tarkin_analysis_add_layer(TarkinStream *s, |
| TarkinVideoLayerDesc *tvld); |
| /* At that point you are ready to get headers out the lib by calling |
| * tarkin_analysis_headerout() passing it a renseigned TarkinComment |
| * structure. It does fill your 3 ogg_packet headers, which are valid |
| * till next call */ |
| extern int TarkinCommentheader_out(TarkinComment *vc, ogg_packet *op); |
| extern TarkinError tarkin_analysis_headerout(TarkinStream *s, |
| TarkinComment *vc, |
| ogg_packet *op, |
| ogg_packet *op_comm, |
| ogg_packet *op_code); |
| /* You are now ready to pass in frames to the codec, however don't free |
| * them before the codec told you so. It'll tell you when packets are |
| * ready to be taken out. When you have no more frame, simply pass NULL. |
| * If you encode multiple layers you have to do it synchronously, putting |
| * one frame from each layer at a time. */ |
| extern uint32_t tarkin_analysis_framein(TarkinStream *s, |
| uint8_t *frame, /* NULL for EOS */ |
| uint32_t layer, |
| TarkinTime *date); |
| |
| /* Tarkin PRIMITIVES: synthesis layer *******************************/ |
| /* For decoding, you needs first to give the three first packet of the |
| * stream to tarkin_synthesis_headerin() which will fill for you blank |
| * TarkinInfo and TarkinComment. */ |
| extern TarkinError tarkin_synthesis_headerin(TarkinInfo *vi,TarkinComment *vc, |
| ogg_packet *op); |
| /* Then you can init your stream with your TarkinInfo struct. */ |
| extern TarkinError tarkin_synthesis_init(TarkinStream *s,TarkinInfo *ti); |
| /* All subsequent packets are to this be passed to tarkin_synthesis_packetin*/ |
| extern TarkinError tarkin_synthesis_packetin(TarkinStream *s, ogg_packet *op); |
| /* and then tarkin_synthesis_frameout gives you ptr on next frame, or NULL. It |
| * also fills for you date. */ |
| extern TarkinError tarkin_synthesis_frameout(TarkinStream *s, |
| uint8_t **frame, uint32_t layer_id, TarkinTime *date); |
| /* When you're done with a frame, tell it to the codec with this. */ |
| extern int tarkin_synthesis_freeframe(TarkinStream *s, uint8_t *frame); |
| |
| |
| #endif |
| |
| |
| |
| |
| |
| |