1/*  libasf - An Advanced Systems Format media file parser
2 *  Copyright (C) 2006-2010 Juho V��h��-Herttua
3 *
4 *  This library is free software; you can redistribute it and/or
5 *  modify it under the terms of the GNU Lesser General Public
6 *  License as published by the Free Software Foundation; either
7 *  version 2.1 of the License, or (at your option) any later version.
8 *
9 *  This library is distributed in the hope that it will be useful,
10 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 *  Lesser General Public License for more details.
13 *
14 *  You should have received a copy of the GNU Lesser General Public
15 *  License along with this library; if not, write to the Free Software
16 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19#ifndef ASF_H
20#define ASF_H
21
22/* used int types for different platforms */
23#if defined(WIN32) && !defined(__MINGW_H)
24typedef char int8_t;
25typedef unsigned char uint8_t;
26typedef short int16_t;
27typedef unsigned short uint16_t;
28typedef long int32_t;
29typedef unsigned long uint32_t;
30
31typedef __int64 int64_t;
32typedef unsigned __int64 uint64_t;
33#else
34#include <stdint.h>
35#endif
36
37#if defined(WIN32) && defined(DLL_EXPORT)
38# define LIBASF_API __declspec(dllexport)
39#else
40# define LIBASF_API
41#endif
42
43
44
45
46typedef enum {
47	/* fatal errors related to library function */
48	ASF_ERROR_INTERNAL            = -100,  /* incorrect input to API calls */
49	ASF_ERROR_OUTOFMEM            = -101,  /* some malloc inside program failed */
50
51	/* errors related to reading data from stream */
52	ASF_ERROR_NEEDS_BYTES         = -200,  /* not enough data from read */
53	ASF_ERROR_EOF                 = -201,  /* end of file reached */
54	ASF_ERROR_IO                  = -202,  /* error reading or writing to file */
55
56	/* errors related to file being corrupted */
57	ASF_ERROR_INVALID_LENGTH      = -300,  /* length value conflict in input data */
58	ASF_ERROR_INVALID_VALUE       = -301,  /* other value conflict in input data */
59	ASF_ERROR_INVALID_OBJECT      = -302,  /* ASF object missing or in wrong place */
60	ASF_ERROR_INVALID_OBJECT_SIZE = -303,  /* invalid ASF object size (too small) */
61
62	/* errors related to seeking, usually non-fatal */
63	ASF_ERROR_SEEKABLE            = -400,  /* file not seekable */
64	ASF_ERROR_SEEK                = -401   /* file is seekable but seeking failed */
65} asf_error_t;
66
67typedef enum {
68	ASF_STREAM_TYPE_NONE     = 0x00,
69	ASF_STREAM_TYPE_AUDIO    = 0x01,
70	ASF_STREAM_TYPE_VIDEO    = 0x02,
71	ASF_STREAM_TYPE_COMMAND  = 0x03,
72	ASF_STREAM_TYPE_UNKNOWN  = 0xff
73} asf_stream_type_t;
74
75#define ASF_STREAM_FLAG_NONE       0x0000
76#define ASF_STREAM_FLAG_AVAILABLE  0x0001
77#define ASF_STREAM_FLAG_HIDDEN     0x0002
78#define ASF_STREAM_FLAG_EXTENDED   0x0004
79
80
81/* waveformatex fields specified in Microsoft documentation:
82   http://msdn2.microsoft.com/en-us/library/ms713497.aspx */
83struct asf_waveformatex_s {
84	uint16_t wFormatTag;
85	uint16_t nChannels;
86	uint32_t nSamplesPerSec;
87	uint32_t nAvgBytesPerSec;
88	uint16_t nBlockAlign;
89	uint16_t wBitsPerSample;
90	uint16_t cbSize;
91	uint8_t *data;
92};
93typedef struct asf_waveformatex_s asf_waveformatex_t;
94
95#define ASF_BITMAPINFOHEADER_SIZE 40
96/* bitmapinfoheader fields specified in Microsoft documentation:
97   http://msdn2.microsoft.com/en-us/library/ms532290.aspx */
98struct asf_bitmapinfoheader_s {
99	uint32_t biSize;
100	uint32_t biWidth;
101	uint32_t biHeight;
102	uint16_t biPlanes;
103	uint16_t biBitCount;
104	uint32_t biCompression;
105	uint32_t biSizeImage;
106	uint32_t biXPelsPerMeter;
107	uint32_t biYPelsPerMeter;
108	uint32_t biClrUsed;
109	uint32_t biClrImportant;
110	uint8_t *data;
111};
112typedef struct asf_bitmapinfoheader_s asf_bitmapinfoheader_t;
113
114
115struct asf_iostream_s {
116	/* read function, returns -1 on error, 0 on EOF and read bytes
117	 * otherwise */
118	int32_t (*read)(void *opaque, void *buffer, int32_t size);
119
120	/* write function, returns -1 on error, 0 on EOF and written
121	 * bytes otherwise */
122	int32_t (*write)(void *opaque, void *buffer, int32_t size);
123
124	/* seek function, seeks to offset from beginning of the file,
125	 * returns -1 on error, 0 on EOF */
126	int64_t (*seek)(void *opaque, int64_t offset);
127
128	/* opaque data pointer passed to each of the stream handling
129	 * callbacks */
130	void *opaque;
131};
132typedef struct asf_iostream_s asf_iostream_t;
133
134struct asf_metadata_entry_s {
135	char *key;	/* key of extended metadata entry */
136	char *value;	/* value of extended metadata entry */
137};
138typedef struct asf_metadata_entry_s asf_metadata_entry_t;
139
140/* all metadata entries are presented in UTF-8 character encoding */
141struct asf_metadata_s {
142	char *title;		/* title of the stream */
143	char *artist;		/* artist of the stream */
144	char *copyright;	/* copyright holder */
145	char *description;	/* description of the stream */
146	char *rating;		/* rating of the stream */
147	uint16_t extended_count;	/* number of extended entries */
148	asf_metadata_entry_t *extended; /* array of extended entries */
149};
150typedef struct asf_metadata_s asf_metadata_t;
151
152struct asf_payload_s {
153	uint8_t stream_number;	/* the stream number this payload belongs to */
154	uint8_t key_frame;	/* a flag indicating if this payload contains a key frame  */
155
156	uint32_t media_object_number;	/* number of media object this payload is part of */
157	uint32_t media_object_offset;	/* byte offset from beginning of media object */
158
159	uint32_t replicated_length;	/* length of some replicated data of a media object... */
160	uint8_t *replicated_data;	/* the replicated data mentioned */
161
162	uint32_t datalen;	/* length of the actual payload data */
163	uint8_t *data;		/* the actual payload data to decode */
164
165	uint32_t pts;		/* presentation time of this payload */
166};
167typedef struct asf_payload_s asf_payload_t;
168
169struct asf_packet_s {
170	uint8_t ec_length;	/* error correction data length */
171	uint8_t *ec_data;	/* error correction data array */
172
173	uint32_t length;		/* length of this packet, usually constant per stream */
174	uint32_t sequence;              /* sequence value reserved for future use, should be ignored */
175	uint32_t padding_length;	/* length of the padding after the data in this packet */
176	uint32_t send_time;		/* send time of this packet in milliseconds */
177	uint16_t duration;		/* duration of this packet in milliseconds */
178
179	uint16_t payload_count;		/* number of payloads contained in this packet */
180	asf_payload_t *payloads;	/* an array of payloads in this packet */
181	uint16_t payloads_size;		/* for internal library use, not to be modified by applications! */
182
183	uint32_t payload_data_len;	/* length of the raw payload data of this packet */
184	uint8_t *payload_data;		/* the raw payload data of this packet, usually not useful */
185
186	uint8_t *data;		/* for internal library use, not to be modified by applications! */
187	uint32_t data_size;	/* for internal library use, not to be modified by applications! */
188};
189typedef struct asf_packet_s asf_packet_t;
190
191struct asf_stream_extended_properties_s {
192	uint64_t start_time;
193	uint64_t end_time;
194	uint32_t data_bitrate;
195	uint32_t buffer_size;
196	uint32_t initial_buf_fullness;
197	uint32_t data_bitrate2;
198	uint32_t buffer_size2;
199	uint32_t initial_buf_fullness2;
200	uint32_t max_obj_size;
201	uint32_t flags;
202	uint16_t stream_num;
203	uint16_t lang_idx;
204	uint64_t avg_time_per_frame;
205	uint16_t stream_name_count;
206	uint16_t num_payload_ext;
207};
208typedef struct asf_stream_extended_properties_s asf_stream_extended_properties_t;
209
210struct asf_stream_s {
211	asf_stream_type_t type;	/* type of this current stream */
212	uint16_t flags;         /* possible flags related to this stream */
213
214	/* pointer to type specific data (ie. waveformatex or bitmapinfoheader)
215	 * only available if ASF_STREAM_FLAG_AVAILABLE flag is set, otherwise NULL */
216	void *properties;
217
218	/* pointer to extended properties of the stream if they specified
219	 * only available if ASF_STREAM_FLAG_EXTENDED flag is set, otherwise NULL */
220	asf_stream_extended_properties_t *extended_properties;
221};
222typedef struct asf_stream_s asf_stream_t;
223
224typedef struct asf_file_s asf_file_t;
225
226
227/* initialize the library using file on a local filesystem */
228LIBASF_API asf_file_t *asf_open_file(const char *filename);
229
230/* initialize the library using callbacks defined on a stream structure,
231   the stream structure can be freed after calling this function */
232LIBASF_API asf_file_t *asf_open_cb(asf_iostream_t *iostream);
233
234/* close the library handle and free all allocated memory */
235LIBASF_API void asf_close(asf_file_t *file);
236
237
238/* initialize the library and read all header information of the ASF file */
239LIBASF_API int asf_init(asf_file_t *file);
240
241
242/* create a packet structure for reading data packets */
243LIBASF_API asf_packet_t *asf_packet_create();
244
245/* free the packet structure allocated earlier, need to be called only once */
246LIBASF_API void asf_packet_destroy(asf_packet_t *packet);
247
248/* get next packet from the stream to the specified packet structure */
249LIBASF_API int asf_get_packet(asf_file_t *file, asf_packet_t *packet);
250
251/* seek to the closest (key frame) packet specified by milliseconds position */
252LIBASF_API int64_t asf_seek_to_msec(asf_file_t *file, int64_t msec);
253
254
255/* get metadata information of the ASF file handle */
256LIBASF_API asf_metadata_t *asf_header_get_metadata(asf_file_t *file);
257
258/* free metadata structure received from the library */
259LIBASF_API void asf_metadata_destroy(asf_metadata_t *metadata);
260
261/* free all header information from the ASF file structure
262 * WARNING: after calling this function all asf_header_*
263 *          functions will return NULL or failure!!! */
264LIBASF_API void asf_header_destroy(asf_file_t *file);
265
266
267/* calculate how many streams are available in current ASF file */
268LIBASF_API uint8_t asf_get_stream_count(asf_file_t *file);
269
270/* get info of a stream, the resulting pointer and its contents should NOT be freed */
271LIBASF_API asf_stream_t *asf_get_stream(asf_file_t *file, uint8_t track);
272
273
274/* return non-zero if the file is broadcasted, 0 otherwise */
275LIBASF_API int asf_is_broadcast(asf_file_t *file);
276
277/* return non-zero if the file is seekable, 0 otherwise */
278LIBASF_API int asf_is_seekable(asf_file_t *file);
279
280/* get size of the ASF file in bytes */
281LIBASF_API uint64_t asf_get_file_size(asf_file_t *file);
282
283/* get creation date in 100-nanosecond units since Jan 1, 1601 GMT
284   this value should be ignored for broadcasts */
285LIBASF_API uint64_t asf_get_creation_date(asf_file_t *file);
286
287/* get number of data packets available in this file
288   this value should be ignored for broadcasts */
289LIBASF_API uint64_t asf_get_data_packets(asf_file_t *file);
290
291/* get play duration of the file in 100-nanosecond units,
292   this value should be ignored for broadcasts */
293LIBASF_API uint64_t asf_get_duration(asf_file_t *file);
294
295/* maximum bitrate as bits per second in the entire file */
296LIBASF_API uint32_t asf_get_max_bitrate(asf_file_t *file);
297
298#endif
299