~ubuntu-branches/ubuntu/hoary/liboggz/hoary

« back to all changes in this revision

Viewing changes to src/tools/oggzed.c

  • Committer: Bazaar Package Importer
  • Author(s): Jamie Wilkinson
  • Date: 2004-04-13 21:48:13 UTC
  • Revision ID: james.westby@ubuntu.com-20040413214813-oq1cjx1n49vvqrcf
Tags: upstream-0.8.2
ImportĀ upstreamĀ versionĀ 0.8.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2003 Commonwealth Scientific and Industrial Research
 
3
   Organisation (CSIRO) Australia
 
4
 
 
5
   Redistribution and use in source and binary forms, with or without
 
6
   modification, are permitted provided that the following conditions
 
7
   are met:
 
8
 
 
9
   - Redistributions of source code must retain the above copyright
 
10
   notice, this list of conditions and the following disclaimer.
 
11
 
 
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.
 
15
 
 
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.
 
19
 
 
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.
 
31
*/
 
32
 
 
33
#include "config.h"
 
34
 
 
35
#include <stdio.h>
 
36
#include <stdlib.h>
 
37
#include <string.h>
 
38
 
 
39
#include <oggz/oggz.h>
 
40
 
 
41
#ifdef HAVE_VORBIS
 
42
#include <vorbis/codec.h>
 
43
#endif
 
44
 
 
45
#ifdef HAVE_SPEEX
 
46
#include <speex.h>
 
47
#include <speex_header.h>
 
48
#include <speex_callbacks.h>
 
49
#endif
 
50
 
 
51
#ifdef HAVE_THEORA
 
52
#include <theora/theora.h>
 
53
#endif
 
54
 
 
55
typedef struct _ogg_rate ogg_rate;
 
56
 
 
57
struct _ogg_rate {
 
58
  long serialno;
 
59
  long rate_numerator;
 
60
  long rate_denominator;
 
61
  int keyframe_shift;
 
62
  double rate_multiplier;
 
63
};
 
64
 
 
65
#define MAX_STREAMS 16
 
66
ogg_rate rates[MAX_STREAMS];
 
67
 
 
68
static long granule_rate, rate_interval;
 
69
static ogg_int64_t current_granule;
 
70
static long current_serialno;
 
71
 
 
72
static int
 
73
init_stream (long serialno, long rate_numerator, long rate_denominator,
 
74
             int keyframe_shift)
 
75
{
 
76
  int i;
 
77
 
 
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;
 
84
      break;
 
85
    }
 
86
  }
 
87
 
 
88
  if (i == MAX_STREAMS)
 
89
    return -1;
 
90
 
 
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;
 
95
 
 
96
      printf ("(%ld): %ld / %ld = %f\n", rates[i].serialno,
 
97
              rates[i].rate_denominator, rates[i].rate_numerator,
 
98
              rates[i].rate_multiplier);
 
99
    }
 
100
  }
 
101
 
 
102
  return 0;
 
103
}
 
104
 
 
105
static ogg_int64_t
 
106
gp_metric (OGGZ * oggz, long serialno, ogg_int64_t granulepos,
 
107
           void * user_data)
 
108
{
 
109
  int i;
 
110
  ogg_int64_t units;
 
111
 
 
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);
 
119
      }
 
120
 
 
121
      units = (1000 * granulepos * rates[i].rate_multiplier);
 
122
      printf ("%ld\t(%ld * %f)\n", units,
 
123
              (long)granulepos, rates[i].rate_multiplier);
 
124
      return units;
 
125
    }
 
126
  }
 
127
 
 
128
  return -1;
 
129
}
 
130
 
 
131
#ifdef HAVE_THEORA
 
132
static int intlog(int num) {
 
133
  int ret=0;
 
134
  while(num>0){
 
135
    num=num/2;
 
136
    ret=ret+1;
 
137
  }
 
138
  return(ret);
 
139
}
 
140
#endif
 
141
 
 
142
static int
 
143
read_packet (OGGZ * oggz, ogg_packet * op, long serialno, void * user_data)
 
144
{
 
145
#if 0
 
146
  printf ("[%8lx]\t%ld bytes\tgranulepos %lld\n", serialno, op->bytes,
 
147
          op->granulepos);
 
148
#endif
 
149
 
 
150
  current_granule = op->granulepos;
 
151
  current_serialno = serialno;
 
152
 
 
153
  if (op->b_o_s) {
 
154
    if (!strncmp ((char *)&op->packet[1], "vorbis", 6)) {
 
155
#ifdef HAVE_VORBIS
 
156
      struct vorbis_info vi;
 
157
      struct vorbis_comment vc;
 
158
      int ret;
 
159
 
 
160
      vorbis_info_init (&vi);
 
161
      vorbis_comment_init (&vc);
 
162
      
 
163
      if ((ret = vorbis_synthesis_headerin (&vi, &vc, op)) == 0) {
 
164
        if (vi.rate != 0) {
 
165
          printf ("Got vorbis info: version %d\tchannels %d\trate %ld\n",
 
166
                  vi.version, vi.channels, vi.rate);
 
167
          
 
168
          init_stream (serialno, vi.rate, 1, 0);
 
169
        }
 
170
      }
 
171
#endif
 
172
    } else if (!strncmp ((char *)&op->packet[0], "Speex   ", 8)) {
 
173
#ifdef HAVE_SPEEX
 
174
      SpeexHeader * header;
 
175
    
 
176
      header = speex_packet_to_header ((char *)op->packet, op->bytes);
 
177
    
 
178
      if (header) {
 
179
        init_stream (serialno, header->rate, 1, 0);
 
180
 
 
181
        printf ("Got speex samplerate %d\n", header->rate);
 
182
        
 
183
        free (header);
 
184
      }
 
185
#endif
 
186
    } else if (!strncmp ((char *)&op->packet[1], "theora", 5)) {
 
187
#ifdef HAVE_THEORA
 
188
      theora_info t_info;
 
189
      theora_comment t_comment;
 
190
 
 
191
      theora_info_init (&t_info);
 
192
      theora_comment_init (&t_comment);
 
193
 
 
194
      if (theora_decode_header(&t_info, &t_comment, op) >= 0) {
 
195
 
 
196
        printf ("Got theora %d/%d FPS\n",
 
197
                t_info.fps_numerator, t_info.fps_denominator);
 
198
 
 
199
        init_stream (serialno, t_info.fps_numerator,
 
200
                     t_info.fps_denominator,
 
201
                     intlog (t_info.keyframe_frequency_force-1));
 
202
      }
 
203
#endif
 
204
    }
 
205
  }
 
206
 
 
207
  return 0;
 
208
}
 
209
 
 
210
int
 
211
main (int argc, char ** argv)
 
212
{
 
213
  OGGZ * oggz;
 
214
  int i;
 
215
  long n;
 
216
 
 
217
  if (argc < 2) {
 
218
    printf ("usage: %s filename\n", argv[0]);
 
219
  }
 
220
 
 
221
  granule_rate = 1000000;
 
222
  rate_interval = 1;
 
223
 
 
224
  for (i = 0; i < MAX_STREAMS; i++) {
 
225
    rates[i].serialno = -1;
 
226
  }
 
227
 
 
228
  if ((oggz = oggz_open ((char *)argv[1], OGGZ_READ)) == NULL) {
 
229
    printf ("unable to open file %s\n", argv[1]);
 
230
    exit (1);
 
231
  }
 
232
 
 
233
  oggz_set_metric (oggz, -1, gp_metric, NULL);
 
234
 
 
235
  oggz_set_read_callback (oggz, -1, read_packet, NULL);
 
236
  while ((n = oggz_read (oggz, 1024)) > 0);
 
237
 
 
238
  printf ("Last unit: %ld\n",
 
239
          gp_metric (oggz, current_serialno, current_granule, NULL));
 
240
 
 
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);
 
245
 
 
246
  oggz_close (oggz);
 
247
 
 
248
  exit (0);
 
249
}