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
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.
39
#include <oggz/oggz.h>
42
#include <vorbis/codec.h>
47
#include <speex_header.h>
48
#include <speex_callbacks.h>
52
#include <theora/theora.h>
55
typedef struct _ogg_rate ogg_rate;
60
long rate_denominator;
62
double rate_multiplier;
65
#define MAX_STREAMS 16
66
ogg_rate rates[MAX_STREAMS];
68
static long granule_rate, rate_interval;
69
static ogg_int64_t current_granule;
70
static long current_serialno;
73
init_stream (long serialno, long rate_numerator, long rate_denominator,
78
for (i = 0; i < MAX_STREAMS; i++) {
79
if (rates[i].serialno == -1) {
80
rates[i].serialno = serialno;
81
rates[i].rate_numerator = rate_numerator;
82
rates[i].rate_denominator = rate_denominator;
83
rates[i].keyframe_shift = keyframe_shift;
91
for (i = 0; i < MAX_STREAMS; i++) {
92
if (rates[i].serialno != -1) {
93
rates[i].rate_multiplier =
94
(double)rates[i].rate_denominator / (double)rates[i].rate_numerator;
96
printf ("(%ld): %ld / %ld = %f\n", rates[i].serialno,
97
rates[i].rate_denominator, rates[i].rate_numerator,
98
rates[i].rate_multiplier);
106
gp_metric (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
112
for (i = 0; i < MAX_STREAMS; i++) {
113
if (rates[i].serialno == serialno) {
114
if (rates[i].keyframe_shift) {
115
ogg_int64_t iframe, pframe;
116
iframe= granulepos >> rates[i].keyframe_shift;
117
pframe= granulepos - (iframe << rates[i].keyframe_shift);
118
granulepos = (iframe + pframe);
121
units = (1000 * granulepos * rates[i].rate_multiplier);
122
printf ("%ld\t(%ld * %f)\n", units,
123
(long)granulepos, rates[i].rate_multiplier);
132
static int intlog(int num) {
143
read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
146
printf ("[%8lx]\t%ld bytes\tgranulepos %lld\n", serialno, op->bytes,
150
current_granule = op->granulepos;
151
current_serialno = serialno;
154
if (!strncmp ((char *)&op->packet[1], "vorbis", 6)) {
156
struct vorbis_info vi;
157
struct vorbis_comment vc;
160
vorbis_info_init (&vi);
161
vorbis_comment_init (&vc);
163
if ((ret = vorbis_synthesis_headerin (&vi, &vc, op)) == 0) {
165
printf ("Got vorbis info: version %d\tchannels %d\trate %ld\n",
166
vi.version, vi.channels, vi.rate);
168
init_stream (serialno, vi.rate, 1, 0);
172
} else if (!strncmp ((char *)&op->packet[0], "Speex ", 8)) {
174
SpeexHeader * header;
176
header = speex_packet_to_header ((char *)op->packet, op->bytes);
179
init_stream (serialno, header->rate, 1, 0);
181
printf ("Got speex samplerate %d\n", header->rate);
186
} else if (!strncmp ((char *)&op->packet[1], "theora", 5)) {
189
theora_comment t_comment;
191
theora_info_init (&t_info);
192
theora_comment_init (&t_comment);
194
if (theora_decode_header(&t_info, &t_comment, op) >= 0) {
196
printf ("Got theora %d/%d FPS\n",
197
t_info.fps_numerator, t_info.fps_denominator);
199
init_stream (serialno, t_info.fps_numerator,
200
t_info.fps_denominator,
201
intlog (t_info.keyframe_frequency_force-1));
211
main (int argc, char ** argv)
218
printf ("usage: %s filename\n", argv[0]);
221
granule_rate = 1000000;
224
for (i = 0; i < MAX_STREAMS; i++) {
225
rates[i].serialno = -1;
228
if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ)) == NULL) {
229
printf ("unable to open file %s\n", argv[1]);
233
oggz_set_metric (oggz, -1, gp_metric, NULL);
235
oggz_set_read_callback (oggz, -1, read_packet, NULL);
236
while ((n = oggz_read (oggz, 1024)) > 0);
238
printf ("Last unit: %ld\n",
239
gp_metric (oggz, current_serialno, current_granule, NULL));
241
oggz_seek (oggz, 10000, SEEK_SET);
242
oggz_seek (oggz, 20000, SEEK_SET);
243
oggz_seek (oggz, 30000, SEEK_SET);
244
oggz_seek (oggz, 10000, SEEK_SET);