Fix oggplay-dump-first-frame
[liboggplay.git] / src / liboggplay / oggplay_private.h
blobac0fce0b03bb5c3af00c1cbf4462af1481f0cc65
1 /*
2 Copyright (C) 2003 Commonwealth Scientific and Industrial Research
3 Organisation (CSIRO) Australia
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions
7 are met:
9 - Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 - Neither the name of CSIRO Australia nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
24 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 * oggplay_private.h
36 * Shane Stephens <shane.stephens@annodex.net>
37 * Michael Martin
39 #ifndef __OGGPLAY_PRIVATE_H__
40 #define __OGGPLAY_PRIVATE_H__
42 #ifdef HAVE_CONFIG_H
43 #include <config.h>
44 #endif
46 #include <oggplay/oggplay.h>
48 #include <oggz/oggz.h>
49 #include <theora/theora.h>
50 #include <fishsound/fishsound.h>
52 #ifdef HAVE_KATE
53 #include <kate/kate.h>
54 #endif
55 #ifdef HAVE_TIGER
56 #include <tiger/tiger.h>
57 #endif
58 #ifdef HAVE_SKELETON
59 #include <skeleton/skeleton.h>
60 #endif
62 #ifdef WIN32
63 #include "config_win32.h"
64 #ifdef HAVE_WINSOCK2
65 #include <winsock2.h>
66 #else
67 #include <winsock.h>
68 #endif
69 #endif
71 // for Win32 <windows.h> has to be included last
72 #include "std_semaphore.h"
74 /**
76 * has_been_presented: 0 until the data has been added as a "required" element,
77 * then 1.
79 struct _OggPlayDataHeader {
80 int lock;
81 struct _OggPlayDataHeader * next;
82 ogg_int64_t presentation_time;
83 ogg_int64_t samples_in_record;
84 int has_been_presented;
87 typedef struct {
88 OggPlayDataHeader header;
89 OggPlayVideoData data;
90 } OggPlayVideoRecord;
92 typedef struct {
93 OggPlayDataHeader header;
94 OggPlayOverlayData data;
95 } OggPlayOverlayRecord;
97 typedef struct {
98 OggPlayDataHeader header;
99 void * data;
100 } OggPlayAudioRecord;
102 typedef struct {
103 OggPlayDataHeader header;
104 char * data;
105 } OggPlayTextRecord;
107 struct _OggPlay;
109 typedef struct {
110 void ** buffer_list;
111 void ** buffer_mirror;
112 int buffer_size;
113 int last_filled;
114 int last_emptied;
115 semaphore frame_sem;
116 } OggPlayBuffer;
118 struct _OggPlayCallbackInfo {
119 OggPlayDataType data_type;
120 int available_records;
121 int required_records;
122 OggPlayStreamInfo stream_info;
123 OggPlayDataHeader ** records;
124 OggPlayBuffer * buffer;
128 * OggPlayDecode
130 * A structure that contains information about a single track within the Ogg
131 * file.
133 * data_list, end_of_data_list: Contain decoded data packets for this track.
134 * These packets are time-ordered, and have a
135 * known presentation time
137 * untimed_data_list: Contains decoded data packets for this track.
138 * These packets are reverse time-ordered, and
139 * have not got a known presentation time. This
140 * list gets constructed when a new Ogg file is
141 * first being read, and gets torn down as soon as
142 * the first packet with a granulepos is processed
144 * granuleperiod The period between adjacent samples in this
145 * track
147 typedef struct {
148 long serialno; /**< identifies the logical bit stream */
149 int content_type;
150 const char * content_type_name;
151 OggPlayDataType decoded_type; /**< type of the track @see OggPlayDataType */
152 ogg_int64_t granuleperiod;
153 ogg_int64_t last_granulepos; /**< last seen granule position */
154 ogg_int64_t offset; /**< */
155 ogg_int64_t current_loc; /**< current location in the stream (in ) */
156 int active; /**< indicates whether the track is active or not */
157 ogg_int64_t final_granulepos; /**< */
158 struct _OggPlay * player; /**< reference to the OggPlay handle */
159 OggPlayDataHeader * data_list;
160 OggPlayDataHeader * end_of_data_list;
161 OggPlayDataHeader * untimed_data_list;
162 OggPlayStreamInfo stream_info; /**< @see OggPlayStreamInfo */
163 int preroll; /**< num. of past content packets to take into account when decoding the current Ogg page */
164 short initialised; /**< */
165 int num_header_packets; /**< number of header packets left to process for the stream.*/
166 } OggPlayDecode;
168 typedef struct {
169 OggPlayDecode decoder;
170 theora_state video_handle;
171 theora_info video_info;
172 theora_comment video_comment;
173 int granulepos_seen;
174 int frame_delta;
175 int y_width;
176 int y_height;
177 int y_stride;
178 int uv_width;
179 int uv_height;
180 int uv_stride;
181 int cached_keyframe;
182 int convert_to_rgb;
183 int swap_rgb;
184 } OggPlayTheoraDecode;
186 typedef struct {
187 OggPlayDecode decoder;
188 FishSound * sound_handle;
189 FishSoundInfo sound_info;
190 } OggPlayAudioDecode;
192 typedef struct {
193 OggPlayDecode decoder;
194 int granuleshift;
195 } OggPlayCmmlDecode;
198 * OggPlaySkeletonDecode
200 typedef struct {
201 OggPlayDecode decoder;
202 #ifdef HAVE_SKELETON
203 OggSkeleton * skeleton;
204 #else
205 ogg_int64_t presentation_time;
206 ogg_int64_t base_time;
207 #endif
208 } OggPlaySkeletonDecode;
210 typedef struct {
211 OggPlayDecode decoder;
212 #ifdef HAVE_KATE
213 int granuleshift;
214 kate_state k_state;
215 kate_info k_info;
216 kate_comment k_comment;
217 int init;
218 #ifdef HAVE_TIGER
219 int use_tiger;
220 int overlay_dest;
221 tiger_renderer *tr;
222 int default_width;
223 int default_height;
224 int swap_rgb;
225 #endif
226 #endif
227 } OggPlayKateDecode;
229 struct OggPlaySeekTrash;
234 typedef struct OggPlaySeekTrash {
235 OggPlayDataHeader * old_data;
236 OggPlayBuffer * old_buffer;
237 struct OggPlaySeekTrash * next;
238 } OggPlaySeekTrash;
243 struct _OggPlay {
244 OggPlayReader * reader; /**< @see OggPlayReader */
245 OGGZ * oggz; /**< @see OGGZ */
246 OggPlayDecode ** decode_data; /**< */
247 OggPlayCallbackInfo * callback_info; /**< */
248 int num_tracks; /**< number of tracks in the Ogg container */
249 int all_tracks_initialised; /**< "= 1" indicates that all tracks are initialised */
250 ogg_int64_t callback_period; /**< */
251 OggPlayDataCallback * callback; /**< */
252 void * callback_user_ptr; /**< */
253 ogg_int64_t target; /**< */
254 int active_tracks; /**< number of active tracks */
255 volatile OggPlayBuffer * buffer; /**< @see OggPlayBuffer */
256 ogg_int64_t presentation_time; /**< */
257 OggPlaySeekTrash * trash; /**< @see OggPlaySeekTrash */
258 int shutdown; /**< "= 1" indicates shutdown event */
259 int pt_update_valid; /**< */
260 ogg_int64_t duration; /**< The value of the duration the last time it was retrieved.*/
263 void
264 oggplay_set_data_callback_force(OggPlay *me, OggPlayDataCallback callback,
265 void *user);
267 void
268 oggplay_take_out_trash(OggPlay *me, OggPlaySeekTrash *trash);
270 OggPlayErrorCode
271 oggplay_seek_cleanup(OggPlay *me, ogg_int64_t milliseconds);
273 typedef struct {
274 void (*init) (void *user_data);
275 int (*callback) (OGGZ * oggz, ogg_packet * op, long serialno,
276 void * user_data);
277 void (*shutdown) (void *user_data);
278 int size;
279 } OggPlayCallbackFunctions;
282 * Conversion function for fixed point 32.32 representation of time.
284 * OGGPLAY_TIME_INT_TO_FP(x)
285 * converts 'x' to a 32.32 fixed point integer
287 * OGGPLAY_TIME_FP_TO_INT
288 * converts 'x' - a 32.32 fixed point integer - back to normal integer representation
289 * + changes the order of magnitude by 1000
290 * e.g. if the fixed point number - 32.32 format - represents seconds
291 * then the macro will convert it to milliseconds.
293 #define OGGPLAY_TIME_INT_TO_FP(x) ((x) << 32)
294 #define OGGPLAY_TIME_FP_TO_INT(x) (((((x) >> 16) * 1000) >> 16) & 0xFFFFFFFF)
296 /* Allocate and free dynamic memory used by ogg.
297 * By default they are the ones from stdlib */
298 #define oggplay_malloc _ogg_malloc
299 #define oggplay_calloc _ogg_calloc
300 #define oggplay_realloc _ogg_realloc
301 #define oggplay_free _ogg_free
304 * macros for obtaining a type's max and min values
305 * http://www.fefe.de/intof.html
307 #define OGGPLAY_TYPE_HALF_MAX_SIGNED(type) ((type)1 << (sizeof(type)*8-2))
308 #define OGGPLAY_TYPE_MAX_SIGNED(type) (OGGPLAY_TYPE_HALF_MAX_SIGNED(type) - 1 + OGGPLAY_TYPE_HALF_MAX_SIGNED(type))
309 #define OGGPLAY_TYPE_MIN_SIGNED(type) (-1 - OGGPLAY_TYPE_MAX_SIGNED(type))
310 #define OGGPLAY_TYPE_MIN(type) ((type)-1 < 1?OGGPLAY_TYPE_MIN_SIGNED(type):(type)0)
311 #define OGGPLAY_TYPE_MAX(type) ((type)~OGGPLAY_TYPE_MIN(type))
313 static inline int
314 oggplay_check_add_overflow (size_t a, long b, size_t* r) {
315 /* we cannot assume that sizeof(size_t) >= sizeof(long) !!! */
316 if (sizeof(size_t) < sizeof(long)) {
317 /* check whether the number fits into a size_t */
320 (b < 0) ?
321 ((OGGPLAY_TYPE_MAX(size_t)+b >= 0) ? 0 : 1) :
322 ((OGGPLAY_TYPE_MAX(size_t)-b >= 0) ? 0 : 1)
325 return E_OGGPLAY_TYPE_OVERFLOW;
328 /* check whether the sum of the 'a' and 'b' fits into a size_t */
331 (b < 0) ?
332 ((OGGPLAY_TYPE_MIN(size_t)-b <= a) ? 0 : 1) :
333 ((OGGPLAY_TYPE_MAX(size_t)-b >= a) ? 0 : 1)
336 return E_OGGPLAY_TYPE_OVERFLOW;
339 /* if 'r' is supplied give back the sum of 'a' and 'b' */
340 if (r != NULL)
341 *r = a+b;
343 return 0;
346 static inline int
347 oggplay_mul_signed_overflow_generic(long a, long b, long *re) {
348 long _a, _b, ah, bh, x, y, r = 0;
349 int sign = 1;
351 _a = a;
352 _b = b;
353 ah = _a >> (sizeof(long)*4);
354 bh = _b >> (sizeof(long)*4);
356 if (a < 0) {
357 _a = -_a;
358 if (_a < 0) {
359 if (_b == 0 || _b == 1) {
360 r = _a*_b;
361 goto ok;
362 } else {
363 goto overflow;
366 sign = -sign;
367 ah = _a >> (sizeof(long)*4);
370 if (_b < 0) {
371 _b = -_b;
372 if (_b < 0) {
373 if (_a == 0 || (_a == 1 && sign == 1)) {
374 r = _a*_b;
375 goto ok;
376 } else {
377 goto overflow;
380 sign = -sign;
381 bh = _b >> (sizeof(long)*4);
384 if (ah != 0 && bh != 0) {
385 goto overflow;
388 if (ah == 0 && bh == 0) {
389 r = _a*_b;
390 if (r < 0)
391 goto overflow;
393 goto ok;
396 if (_a < _b) {
397 x = _a;
398 _a = _b;
399 _b = x;
400 ah = bh;
403 y = ah*_b;
404 if (y >= (1L << (sizeof(long)*4 - 1)))
405 goto overflow;
406 _a &= (1L << sizeof(long)*4) - 1;
407 x = _a*_b;
408 if (x < 0)
409 goto overflow;
410 x += (y << sizeof(long)*4);
411 if (x < 0)
412 goto overflow;
415 if (re != NULL) {
416 *re = sign*r;
419 return 0;
421 overflow:
422 return E_OGGPLAY_TYPE_OVERFLOW;
425 static inline int
426 oggplay_mul_signed_overflow(long a, long b, long *r) {
427 if (sizeof(long) > 4) {
428 return oggplay_mul_signed_overflow_generic (a, b, r);
429 } else {
430 ogg_int64_t c = (ogg_int64_t) a*b;
432 /* check whether the result fits in a long bit */
435 (c < 1) ?
436 ((OGGPLAY_TYPE_MIN (long) > c) ? 1 : 0) :
437 ((OGGPLAY_TYPE_MAX (long) < c) ? 1 : 0)
440 return E_OGGPLAY_TYPE_OVERFLOW;
443 if (r != NULL) {
444 *r = (long)c;
446 return 0;
450 #include "oggplay_callback.h"
451 #include "oggplay_data.h"
452 #include "oggplay_buffer.h"
454 #endif