~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/ADM_libMad/timer.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libmad - MPEG audio decoder library
 
3
 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
18
 *
 
19
 * $Id: timer.c,v 1.18 2004/01/23 09:41:33 rob Exp $
 
20
 */
 
21
 
 
22
# ifdef HAVE_CONFIG_H
 
23
#  include "config.h"
 
24
# endif
 
25
 
 
26
# include "global.h"
 
27
 
 
28
# include <stdio.h>
 
29
 
 
30
# ifdef HAVE_ASSERT_H
 
31
#  include <assert.h>
 
32
# endif
 
33
 
 
34
# include "timer.h"
 
35
 
 
36
mad_timer_t const mad_timer_zero = { 0, 0 };
 
37
 
 
38
/*
 
39
 * NAME:        timer->compare()
 
40
 * DESCRIPTION: indicate relative order of two timers
 
41
 */
 
42
int mad_timer_compare(mad_timer_t timer1, mad_timer_t timer2)
 
43
{
 
44
  signed long diff;
 
45
 
 
46
  diff = timer1.seconds - timer2.seconds;
 
47
  if (diff < 0)
 
48
    return -1;
 
49
  else if (diff > 0)
 
50
    return +1;
 
51
 
 
52
  diff = timer1.fraction - timer2.fraction;
 
53
  if (diff < 0)
 
54
    return -1;
 
55
  else if (diff > 0)
 
56
    return +1;
 
57
 
 
58
  return 0;
 
59
}
 
60
 
 
61
/*
 
62
 * NAME:        timer->negate()
 
63
 * DESCRIPTION: invert the sign of a timer
 
64
 */
 
65
void mad_timer_negate(mad_timer_t *timer)
 
66
{
 
67
  timer->seconds = -timer->seconds;
 
68
 
 
69
  if (timer->fraction) {
 
70
    timer->seconds -= 1;
 
71
    timer->fraction = MAD_TIMER_RESOLUTION - timer->fraction;
 
72
  }
 
73
}
 
74
 
 
75
/*
 
76
 * NAME:        timer->abs()
 
77
 * DESCRIPTION: return the absolute value of a timer
 
78
 */
 
79
mad_timer_t mad_timer_abs(mad_timer_t timer)
 
80
{
 
81
  if (timer.seconds < 0)
 
82
    mad_timer_negate(&timer);
 
83
 
 
84
  return timer;
 
85
}
 
86
 
 
87
/*
 
88
 * NAME:        reduce_timer()
 
89
 * DESCRIPTION: carry timer fraction into seconds
 
90
 */
 
91
static
 
92
void reduce_timer(mad_timer_t *timer)
 
93
{
 
94
  timer->seconds  += timer->fraction / MAD_TIMER_RESOLUTION;
 
95
  timer->fraction %= MAD_TIMER_RESOLUTION;
 
96
}
 
97
 
 
98
/*
 
99
 * NAME:        gcd()
 
100
 * DESCRIPTION: compute greatest common denominator
 
101
 */
 
102
static
 
103
unsigned long gcd(unsigned long num1, unsigned long num2)
 
104
{
 
105
  unsigned long tmp;
 
106
 
 
107
  while (num2) {
 
108
    tmp  = num2;
 
109
    num2 = num1 % num2;
 
110
    num1 = tmp;
 
111
  }
 
112
 
 
113
  return num1;
 
114
}
 
115
 
 
116
/*
 
117
 * NAME:        reduce_rational()
 
118
 * DESCRIPTION: convert rational expression to lowest terms
 
119
 */
 
120
static
 
121
void reduce_rational(unsigned long *numer, unsigned long *denom)
 
122
{
 
123
  unsigned long factor;
 
124
 
 
125
  factor = gcd(*numer, *denom);
 
126
 
 
127
  assert(factor != 0);
 
128
 
 
129
  *numer /= factor;
 
130
  *denom /= factor;
 
131
}
 
132
 
 
133
/*
 
134
 * NAME:        scale_rational()
 
135
 * DESCRIPTION: solve numer/denom == ?/scale avoiding overflowing
 
136
 */
 
137
static
 
138
unsigned long scale_rational(unsigned long numer, unsigned long denom,
 
139
                             unsigned long scale)
 
140
{
 
141
  reduce_rational(&numer, &denom);
 
142
  reduce_rational(&scale, &denom);
 
143
 
 
144
  assert(denom != 0);
 
145
 
 
146
  if (denom < scale)
 
147
    return numer * (scale / denom) + numer * (scale % denom) / denom;
 
148
  if (denom < numer)
 
149
    return scale * (numer / denom) + scale * (numer % denom) / denom;
 
150
 
 
151
  return numer * scale / denom;
 
152
}
 
153
 
 
154
/*
 
155
 * NAME:        timer->set()
 
156
 * DESCRIPTION: set timer to specific (positive) value
 
157
 */
 
158
void mad_timer_set(mad_timer_t *timer, unsigned long seconds,
 
159
                   unsigned long numer, unsigned long denom)
 
160
{
 
161
  timer->seconds = seconds;
 
162
  if (numer >= denom && denom > 0) {
 
163
    timer->seconds += numer / denom;
 
164
    numer %= denom;
 
165
  }
 
166
 
 
167
  switch (denom) {
 
168
  case 0:
 
169
  case 1:
 
170
    timer->fraction = 0;
 
171
    break;
 
172
 
 
173
  case MAD_TIMER_RESOLUTION:
 
174
    timer->fraction = numer;
 
175
    break;
 
176
 
 
177
  case 1000:
 
178
    timer->fraction = numer * (MAD_TIMER_RESOLUTION /  1000);
 
179
    break;
 
180
 
 
181
  case 8000:
 
182
    timer->fraction = numer * (MAD_TIMER_RESOLUTION /  8000);
 
183
    break;
 
184
 
 
185
  case 11025:
 
186
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 11025);
 
187
    break;
 
188
 
 
189
  case 12000:
 
190
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 12000);
 
191
    break;
 
192
 
 
193
  case 16000:
 
194
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 16000);
 
195
    break;
 
196
 
 
197
  case 22050:
 
198
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 22050);
 
199
    break;
 
200
 
 
201
  case 24000:
 
202
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 24000);
 
203
    break;
 
204
 
 
205
  case 32000:
 
206
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 32000);
 
207
    break;
 
208
 
 
209
  case 44100:
 
210
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 44100);
 
211
    break;
 
212
 
 
213
  case 48000:
 
214
    timer->fraction = numer * (MAD_TIMER_RESOLUTION / 48000);
 
215
    break;
 
216
 
 
217
  default:
 
218
    timer->fraction = scale_rational(numer, denom, MAD_TIMER_RESOLUTION);
 
219
    break;
 
220
  }
 
221
 
 
222
  if (timer->fraction >= MAD_TIMER_RESOLUTION)
 
223
    reduce_timer(timer);
 
224
}
 
225
 
 
226
/*
 
227
 * NAME:        timer->add()
 
228
 * DESCRIPTION: add one timer to another
 
229
 */
 
230
void mad_timer_add(mad_timer_t *timer, mad_timer_t incr)
 
231
{
 
232
  timer->seconds  += incr.seconds;
 
233
  timer->fraction += incr.fraction;
 
234
 
 
235
  if (timer->fraction >= MAD_TIMER_RESOLUTION)
 
236
    reduce_timer(timer);
 
237
}
 
238
 
 
239
/*
 
240
 * NAME:        timer->multiply()
 
241
 * DESCRIPTION: multiply a timer by a scalar value
 
242
 */
 
243
void mad_timer_multiply(mad_timer_t *timer, signed long scalar)
 
244
{
 
245
  mad_timer_t addend;
 
246
  unsigned long factor;
 
247
 
 
248
  factor = scalar;
 
249
  if (scalar < 0) {
 
250
    factor = -scalar;
 
251
    mad_timer_negate(timer);
 
252
  }
 
253
 
 
254
  addend = *timer;
 
255
  *timer = mad_timer_zero;
 
256
 
 
257
  while (factor) {
 
258
    if (factor & 1)
 
259
      mad_timer_add(timer, addend);
 
260
 
 
261
    mad_timer_add(&addend, addend);
 
262
    factor >>= 1;
 
263
  }
 
264
}
 
265
 
 
266
/*
 
267
 * NAME:        timer->count()
 
268
 * DESCRIPTION: return timer value in selected units
 
269
 */
 
270
signed long mad_timer_count(mad_timer_t timer, enum mad_units units)
 
271
{
 
272
  switch (units) {
 
273
  case MAD_UNITS_HOURS:
 
274
    return timer.seconds / 60 / 60;
 
275
 
 
276
  case MAD_UNITS_MINUTES:
 
277
    return timer.seconds / 60;
 
278
 
 
279
  case MAD_UNITS_SECONDS:
 
280
    return timer.seconds;
 
281
 
 
282
  case MAD_UNITS_DECISECONDS:
 
283
  case MAD_UNITS_CENTISECONDS:
 
284
  case MAD_UNITS_MILLISECONDS:
 
285
 
 
286
  case MAD_UNITS_8000_HZ:
 
287
  case MAD_UNITS_11025_HZ:
 
288
  case MAD_UNITS_12000_HZ:
 
289
  case MAD_UNITS_16000_HZ:
 
290
  case MAD_UNITS_22050_HZ:
 
291
  case MAD_UNITS_24000_HZ:
 
292
  case MAD_UNITS_32000_HZ:
 
293
  case MAD_UNITS_44100_HZ:
 
294
  case MAD_UNITS_48000_HZ:
 
295
 
 
296
  case MAD_UNITS_24_FPS:
 
297
  case MAD_UNITS_25_FPS:
 
298
  case MAD_UNITS_30_FPS:
 
299
  case MAD_UNITS_48_FPS:
 
300
  case MAD_UNITS_50_FPS:
 
301
  case MAD_UNITS_60_FPS:
 
302
  case MAD_UNITS_75_FPS:
 
303
    return timer.seconds * (signed long) units +
 
304
      (signed long) scale_rational(timer.fraction, MAD_TIMER_RESOLUTION,
 
305
                                   units);
 
306
 
 
307
  case MAD_UNITS_23_976_FPS:
 
308
  case MAD_UNITS_24_975_FPS:
 
309
  case MAD_UNITS_29_97_FPS:
 
310
  case MAD_UNITS_47_952_FPS:
 
311
  case MAD_UNITS_49_95_FPS:
 
312
  case MAD_UNITS_59_94_FPS:
 
313
    return (mad_timer_count(timer, -units) + 1) * 1000 / 1001;
 
314
  }
 
315
 
 
316
  /* unsupported units */
 
317
  return 0;
 
318
}
 
319
 
 
320
/*
 
321
 * NAME:        timer->fraction()
 
322
 * DESCRIPTION: return fractional part of timer in arbitrary terms
 
323
 */
 
324
unsigned long mad_timer_fraction(mad_timer_t timer, unsigned long denom)
 
325
{
 
326
  timer = mad_timer_abs(timer);
 
327
 
 
328
  switch (denom) {
 
329
  case 0:
 
330
    return timer.fraction ?
 
331
      MAD_TIMER_RESOLUTION / timer.fraction : MAD_TIMER_RESOLUTION + 1;
 
332
 
 
333
  case MAD_TIMER_RESOLUTION:
 
334
    return timer.fraction;
 
335
 
 
336
  default:
 
337
    return scale_rational(timer.fraction, MAD_TIMER_RESOLUTION, denom);
 
338
  }
 
339
}
 
340
 
 
341
/*
 
342
 * NAME:        timer->string()
 
343
 * DESCRIPTION: write a string representation of a timer using a template
 
344
 */
 
345
void mad_timer_string(mad_timer_t timer,
 
346
                      char *dest, char const *format, enum mad_units units,
 
347
                      enum mad_units fracunits, unsigned long subparts)
 
348
{
 
349
  unsigned long hours, minutes, seconds, sub;
 
350
  unsigned int frac;
 
351
 
 
352
  timer = mad_timer_abs(timer);
 
353
 
 
354
  seconds = timer.seconds;
 
355
  frac = sub = 0;
 
356
 
 
357
  switch (fracunits) {
 
358
  case MAD_UNITS_HOURS:
 
359
  case MAD_UNITS_MINUTES:
 
360
  case MAD_UNITS_SECONDS:
 
361
    break;
 
362
 
 
363
  case MAD_UNITS_DECISECONDS:
 
364
  case MAD_UNITS_CENTISECONDS:
 
365
  case MAD_UNITS_MILLISECONDS:
 
366
 
 
367
  case MAD_UNITS_8000_HZ:
 
368
  case MAD_UNITS_11025_HZ:
 
369
  case MAD_UNITS_12000_HZ:
 
370
  case MAD_UNITS_16000_HZ:
 
371
  case MAD_UNITS_22050_HZ:
 
372
  case MAD_UNITS_24000_HZ:
 
373
  case MAD_UNITS_32000_HZ:
 
374
  case MAD_UNITS_44100_HZ:
 
375
  case MAD_UNITS_48000_HZ:
 
376
 
 
377
  case MAD_UNITS_24_FPS:
 
378
  case MAD_UNITS_25_FPS:
 
379
  case MAD_UNITS_30_FPS:
 
380
  case MAD_UNITS_48_FPS:
 
381
  case MAD_UNITS_50_FPS:
 
382
  case MAD_UNITS_60_FPS:
 
383
  case MAD_UNITS_75_FPS:
 
384
    {
 
385
      unsigned long denom;
 
386
 
 
387
      denom = MAD_TIMER_RESOLUTION / fracunits;
 
388
 
 
389
      frac = timer.fraction / denom;
 
390
      sub  = scale_rational(timer.fraction % denom, denom, subparts);
 
391
    }
 
392
    break;
 
393
 
 
394
  case MAD_UNITS_23_976_FPS:
 
395
  case MAD_UNITS_24_975_FPS:
 
396
  case MAD_UNITS_29_97_FPS:
 
397
  case MAD_UNITS_47_952_FPS:
 
398
  case MAD_UNITS_49_95_FPS:
 
399
  case MAD_UNITS_59_94_FPS:
 
400
    /* drop-frame encoding */
 
401
    /* N.B. this is only well-defined for MAD_UNITS_29_97_FPS */
 
402
    {
 
403
      unsigned long frame, cycle, d, m;
 
404
 
 
405
      frame = mad_timer_count(timer, fracunits);
 
406
 
 
407
      cycle = -fracunits * 60 * 10 - (10 - 1) * 2;
 
408
 
 
409
      d = frame / cycle;
 
410
      m = frame % cycle;
 
411
      frame += (10 - 1) * 2 * d;
 
412
      if (m > 2)
 
413
        frame += 2 * ((m - 2) / (cycle / 10));
 
414
 
 
415
      frac    = frame % -fracunits;
 
416
      seconds = frame / -fracunits;
 
417
    }
 
418
    break;
 
419
  }
 
420
 
 
421
  switch (units) {
 
422
  case MAD_UNITS_HOURS:
 
423
    minutes = seconds / 60;
 
424
    hours   = minutes / 60;
 
425
 
 
426
    sprintf(dest, format,
 
427
            hours,
 
428
            (unsigned int) (minutes % 60),
 
429
            (unsigned int) (seconds % 60),
 
430
            frac, sub);
 
431
    break;
 
432
 
 
433
  case MAD_UNITS_MINUTES:
 
434
    minutes = seconds / 60;
 
435
 
 
436
    sprintf(dest, format,
 
437
            minutes,
 
438
            (unsigned int) (seconds % 60),
 
439
            frac, sub);
 
440
    break;
 
441
 
 
442
  case MAD_UNITS_SECONDS:
 
443
    sprintf(dest, format,
 
444
            seconds,
 
445
            frac, sub);
 
446
    break;
 
447
 
 
448
  case MAD_UNITS_23_976_FPS:
 
449
  case MAD_UNITS_24_975_FPS:
 
450
  case MAD_UNITS_29_97_FPS:
 
451
  case MAD_UNITS_47_952_FPS:
 
452
  case MAD_UNITS_49_95_FPS:
 
453
  case MAD_UNITS_59_94_FPS:
 
454
    if (fracunits < 0) {
 
455
      /* not yet implemented */
 
456
      sub = 0;
 
457
    }
 
458
 
 
459
    /* fall through */
 
460
 
 
461
  case MAD_UNITS_DECISECONDS:
 
462
  case MAD_UNITS_CENTISECONDS:
 
463
  case MAD_UNITS_MILLISECONDS:
 
464
 
 
465
  case MAD_UNITS_8000_HZ:
 
466
  case MAD_UNITS_11025_HZ:
 
467
  case MAD_UNITS_12000_HZ:
 
468
  case MAD_UNITS_16000_HZ:
 
469
  case MAD_UNITS_22050_HZ:
 
470
  case MAD_UNITS_24000_HZ:
 
471
  case MAD_UNITS_32000_HZ:
 
472
  case MAD_UNITS_44100_HZ:
 
473
  case MAD_UNITS_48000_HZ:
 
474
 
 
475
  case MAD_UNITS_24_FPS:
 
476
  case MAD_UNITS_25_FPS:
 
477
  case MAD_UNITS_30_FPS:
 
478
  case MAD_UNITS_48_FPS:
 
479
  case MAD_UNITS_50_FPS:
 
480
  case MAD_UNITS_60_FPS:
 
481
  case MAD_UNITS_75_FPS:
 
482
    sprintf(dest, format, mad_timer_count(timer, units), sub);
 
483
    break;
 
484
  }
 
485
}