~ubuntu-branches/ubuntu/lucid/mpg123/lucid

« back to all changes in this revision

Viewing changes to readers.c

Tags: upstream-0.60
ImportĀ upstreamĀ versionĀ 0.60

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <stdlib.h>
2
 
 
3
 
#include <sys/types.h>
4
 
#include <sys/stat.h>
5
 
#include <fcntl.h>
6
 
 
7
 
#include "mpg123.h"
8
 
#include "buffer.h"
9
 
#include "common.h"
10
 
 
11
 
#ifdef READ_MMAP
12
 
#include <sys/mman.h>
13
 
#ifndef MAP_FAILED
14
 
#define MAP_FAILED ( (void *) -1 )
15
 
#endif
16
 
#endif
17
 
 
18
 
static int get_fileinfo(struct reader *,char *buf);
19
 
 
20
 
 
21
 
/*******************************************************************
22
 
 * stream based operation
23
 
 */
24
 
static int fullread(int fd,unsigned char *buf,int count)
25
 
{
26
 
  int ret,cnt=0;
27
 
 
28
 
  while(cnt < count) {
29
 
    ret = read(fd,buf+cnt,count-cnt);
30
 
    if(ret < 0)
31
 
      return ret;
32
 
    if(ret == 0)
33
 
      break;
34
 
    cnt += ret;
35
 
  } 
36
 
 
37
 
  return cnt;
38
 
}
39
 
 
40
 
static int default_init(struct reader *rds)
41
 
{
42
 
  char buf[128];
43
 
 
44
 
  rds->filepos = 0;
45
 
  rds->filelen = get_fileinfo(rds,buf);
46
 
  
47
 
  if(rds->filelen > 0) {
48
 
    if(!strncmp(buf,"TAG",3)) {
49
 
      rds->flags |= READER_ID3TAG;
50
 
      memcpy(rds->id3buf,buf,128);
51
 
    }
52
 
  }
53
 
  return 0;
54
 
}
55
 
 
56
 
void stream_close(struct reader *rds)
57
 
{
58
 
    if (rds->flags & READER_FD_OPENED)
59
 
        close(rds->filept);
60
 
}
61
 
 
62
 
/**************************************** 
63
 
 * HACK,HACK,HACK: step back <num> frames 
64
 
 * can only work if the 'stream' isn't a real stream but a file
65
 
 */
66
 
static int stream_back_bytes(struct reader *rds,int bytes)
67
 
{
68
 
  if(lseek(rds->filept,-bytes,SEEK_CUR) < 0)
69
 
    return -1;
70
 
  if(param.usebuffer)
71
 
          buffer_resync();
72
 
  return 0;
73
 
}
74
 
 
75
 
static int stream_back_frame(struct reader *rds,struct frame *fr,int num)
76
 
{
77
 
        long bytes;
78
 
        unsigned char buf[4];
79
 
        unsigned long newhead;
80
 
 
81
 
        if(!firsthead)
82
 
                return 0;
83
 
 
84
 
        bytes = (fr->framesize+8)*(num+2);
85
 
 
86
 
        /* Skipping back/forth requires a bit more work in buffered mode. 
87
 
         * See mapped_back_frame(). 
88
 
         */
89
 
        if(param.usebuffer)
90
 
                bytes += (long)(xfermem_get_usedspace(buffermem) /
91
 
                        (buffermem->buf[0] * buffermem->buf[1]
92
 
                                * (buffermem->buf[2] & AUDIO_FORMAT_MASK ?
93
 
                                        16.0 : 8.0 ))
94
 
                                * (tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] << 10));
95
 
/*
96
 
                bytes += (long)(compute_buffer_offset(fr)*compute_bpf(fr));
97
 
*/      
98
 
        if(lseek(rds->filept,-bytes,SEEK_CUR) < 0)
99
 
                return -1;
100
 
 
101
 
        if(fullread(rds->filept,buf,4) != 4)
102
 
                return -1;
103
 
 
104
 
        newhead = (buf[0]<<24) + (buf[1]<<16) + (buf[2]<<8) + buf[3];
105
 
        
106
 
        while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
107
 
                if(fullread(rds->filept,buf,1) != 1)
108
 
                        return -1;
109
 
                newhead <<= 8;
110
 
                newhead |= buf[0];
111
 
                newhead &= 0xffffffff;
112
 
        }
113
 
 
114
 
        if( lseek(rds->filept,-4,SEEK_CUR) < 0)
115
 
                return -1;
116
 
        
117
 
        read_frame(fr);
118
 
        read_frame(fr);
119
 
 
120
 
        if(fr->lay == 3) {
121
 
                set_pointer(512);
122
 
        }
123
 
 
124
 
        if(param.usebuffer)
125
 
                buffer_resync();
126
 
        
127
 
        return 0;
128
 
}
129
 
 
130
 
static int stream_head_read(struct reader *rds,unsigned long *newhead)
131
 
{
132
 
  unsigned char hbuf[4];
133
 
 
134
 
  if(fullread(rds->filept,hbuf,4) != 4)
135
 
    return FALSE;
136
 
  
137
 
  *newhead = ((unsigned long) hbuf[0] << 24) |
138
 
    ((unsigned long) hbuf[1] << 16) |
139
 
    ((unsigned long) hbuf[2] << 8)  |
140
 
    (unsigned long) hbuf[3];
141
 
  
142
 
  return TRUE;
143
 
}
144
 
 
145
 
static int stream_head_shift(struct reader *rds,unsigned long *head)
146
 
{
147
 
  unsigned char hbuf;
148
 
 
149
 
  if(fullread(rds->filept,&hbuf,1) != 1)
150
 
    return 0;
151
 
  *head <<= 8;
152
 
  *head |= hbuf;
153
 
  *head &= 0xffffffff;
154
 
  return 1;
155
 
}
156
 
 
157
 
static int stream_skip_bytes(struct reader *rds,int len)
158
 
{
159
 
  if (!param.usebuffer)
160
 
        return lseek(rds->filept,len,SEEK_CUR);
161
 
 
162
 
  else {
163
 
 
164
 
        int ret = lseek(rds->filept,len,SEEK_CUR);
165
 
        buffer_resync();
166
 
        return ret;
167
 
 
168
 
  }
169
 
}
170
 
 
171
 
static int stream_read_frame_body(struct reader *rds,unsigned char *buf,
172
 
                                  int size)
173
 
{
174
 
  long l;
175
 
 
176
 
  if( (l=fullread(rds->filept,buf,size)) != size)
177
 
  {
178
 
    if(l <= 0)
179
 
      return 0;
180
 
    memset(buf+l,0,size-l);
181
 
  }
182
 
 
183
 
  return 1;
184
 
}
185
 
 
186
 
static long stream_tell(struct reader *rds)
187
 
{
188
 
  return lseek(rds->filept,0,SEEK_CUR);
189
 
}
190
 
 
191
 
static void stream_rewind(struct reader *rds)
192
 
{
193
 
  lseek(rds->filept,0,SEEK_SET);
194
 
  if(param.usebuffer) 
195
 
          buffer_resync();
196
 
}
197
 
 
198
 
/*
199
 
 * returns length of a file (if filept points to a file)
200
 
 * reads the last 128 bytes information into buffer
201
 
 */
202
 
static int get_fileinfo(struct reader *rds,char *buf)
203
 
{
204
 
        int len;
205
 
 
206
 
        if((len=lseek(rds->filept,0,SEEK_END)) < 0) {
207
 
                return -1;
208
 
        }
209
 
        if(lseek(rds->filept,-128,SEEK_END) < 0)
210
 
                return -1;
211
 
        if(fullread(rds->filept,(unsigned char *)buf,128) != 128) {
212
 
                return -1;
213
 
        }
214
 
        if(!strncmp(buf,"TAG",3)) {
215
 
                len -= 128;
216
 
        }
217
 
        if(lseek(rds->filept,0,SEEK_SET) < 0)
218
 
                return -1;
219
 
        if(len <= 0)
220
 
                return -1;
221
 
        return len;
222
 
}
223
 
 
224
 
 
225
 
#ifdef READ_MMAP
226
 
/*********************************************************+
227
 
 * memory mapped operation 
228
 
 *
229
 
 */
230
 
static unsigned char *mapbuf;
231
 
static unsigned char *mappnt;
232
 
static unsigned char *mapend;
233
 
 
234
 
static int mapped_init(struct reader *rds) 
235
 
{
236
 
        long len;
237
 
        char buf[128];
238
 
 
239
 
        len = get_fileinfo(rds,buf);
240
 
        if(len < 0)
241
 
                return -1;
242
 
 
243
 
        if(!strncmp(buf,"TAG",3)) {
244
 
          rds->flags |= READER_ID3TAG;
245
 
          memcpy(rds->id3buf,buf,128);
246
 
        }
247
 
 
248
 
        mappnt = mapbuf = (unsigned char *)
249
 
                mmap(NULL, len, PROT_READ, MAP_SHARED , rds->filept, 0);
250
 
        if(!mapbuf || mapbuf == MAP_FAILED)
251
 
                return -1;
252
 
 
253
 
        mapend = mapbuf + len;
254
 
        
255
 
        if(param.verbose > 1)
256
 
                fprintf(stderr,"Using memory mapped IO for this stream.\n");
257
 
 
258
 
        rds->filelen = len;
259
 
        return 0;
260
 
}
261
 
 
262
 
static void mapped_rewind(struct reader *rds)
263
 
{
264
 
        mappnt = mapbuf;
265
 
        if (param.usebuffer) 
266
 
                buffer_resync();        
267
 
}
268
 
 
269
 
static void mapped_close(struct reader *rds)
270
 
{
271
 
        munmap((void *)mapbuf,mapend-mapbuf);
272
 
        if (rds->flags & READER_FD_OPENED)
273
 
                close(rds->filept);
274
 
}
275
 
 
276
 
static int mapped_head_read(struct reader *rds,unsigned long *newhead) 
277
 
{
278
 
        unsigned long nh;
279
 
 
280
 
        if(mappnt + 4 > mapend)
281
 
                return FALSE;
282
 
 
283
 
        nh = (*mappnt++)  << 24;
284
 
        nh |= (*mappnt++) << 16;
285
 
        nh |= (*mappnt++) << 8;
286
 
        nh |= (*mappnt++) ;
287
 
 
288
 
        *newhead = nh;
289
 
        return TRUE;
290
 
}
291
 
 
292
 
static int mapped_head_shift(struct reader *rds,unsigned long *head)
293
 
{
294
 
  if(mappnt + 1 > mapend)
295
 
    return FALSE;
296
 
  *head <<= 8;
297
 
  *head |= *mappnt++;
298
 
  *head &= 0xffffffff;
299
 
  return TRUE;
300
 
}
301
 
 
302
 
static int mapped_skip_bytes(struct reader *rds,int len)
303
 
{
304
 
  if(mappnt + len > mapend)
305
 
    return FALSE;
306
 
  mappnt += len;
307
 
  if (param.usebuffer)
308
 
          buffer_resync();
309
 
  return TRUE;
310
 
}
311
 
 
312
 
static int mapped_read_frame_body(struct reader *rds,unsigned char *buf,
313
 
                                  int size)
314
 
{
315
 
  if(size <= 0) {
316
 
    fprintf(stderr,"Ouch. Read_frame called with size <= 0\n");
317
 
    return FALSE;
318
 
  }
319
 
  if(mappnt + size > mapend)
320
 
    return FALSE;
321
 
  memcpy(buf,mappnt,size);
322
 
  mappnt += size;
323
 
 
324
 
  return TRUE;
325
 
}
326
 
 
327
 
static int mapped_back_bytes(struct reader *rds,int bytes)
328
 
{
329
 
    if( (mappnt - bytes) < mapbuf || (mappnt - bytes + 4) > mapend)
330
 
        return -1;
331
 
    mappnt -= bytes;
332
 
    if(param.usebuffer)
333
 
            buffer_resync();
334
 
    return 0;
335
 
}
336
 
 
337
 
static int mapped_back_frame(struct reader *rds,struct frame *fr,int num)
338
 
{
339
 
    long bytes;
340
 
    unsigned long newhead;
341
 
 
342
 
 
343
 
    if(!firsthead)
344
 
        return 0;
345
 
 
346
 
    bytes = (fr->framesize+8)*(num+2);
347
 
 
348
 
    /* Buffered mode is a bit trickier. From the size of the buffered
349
 
     * output audio stream we have to make a guess at the number of frames
350
 
     * this corresponds to.
351
 
     */
352
 
    if(param.usebuffer) 
353
 
                bytes += (long)(xfermem_get_usedspace(buffermem) /
354
 
                        (buffermem->buf[0] * buffermem->buf[1] 
355
 
                                * (buffermem->buf[2] & AUDIO_FORMAT_MASK ?
356
 
                        16.0 : 8.0 )) 
357
 
                        * (tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index] << 10));
358
 
/*
359
 
                bytes += (long)(compute_buffer_offset(fr)*compute_bpf(fr));  
360
 
*/
361
 
 
362
 
    if( (mappnt - bytes) < mapbuf || (mappnt - bytes + 4) > mapend)
363
 
        return -1;
364
 
    mappnt -= bytes;
365
 
 
366
 
    newhead = (mappnt[0]<<24) + (mappnt[1]<<16) + (mappnt[2]<<8) + mappnt[3];
367
 
    mappnt += 4;
368
 
 
369
 
    while( (newhead & HDRCMPMASK) != (firsthead & HDRCMPMASK) ) {
370
 
        if(mappnt + 1 > mapend)
371
 
            return -1;
372
 
        newhead <<= 8;
373
 
        newhead |= *mappnt++;
374
 
        newhead &= 0xffffffff;
375
 
    }
376
 
    mappnt -= 4;
377
 
 
378
 
    read_frame(fr);
379
 
    read_frame(fr);
380
 
 
381
 
    if(fr->lay == 3)
382
 
        set_pointer(512);
383
 
 
384
 
    if(param.usebuffer)
385
 
            buffer_resync();
386
 
    
387
 
    return 0;
388
 
}
389
 
 
390
 
static long mapped_tell(struct reader *rds)
391
 
{
392
 
  return mappnt - mapbuf;
393
 
}
394
 
 
395
 
#endif
396
 
 
397
 
/*****************************************************************
398
 
 * read frame helper
399
 
 */
400
 
 
401
 
struct reader *rd;
402
 
struct reader readers[] = {
403
 
#ifdef READ_SYSTEM
404
 
 { system_init,
405
 
   NULL,        /* filled in by system_init() */
406
 
   NULL,
407
 
   NULL,
408
 
   NULL,
409
 
   NULL,
410
 
   NULL,
411
 
   NULL,
412
 
   NULL } ,
413
 
#endif
414
 
#ifdef READ_MMAP
415
 
 { mapped_init,
416
 
   mapped_close,
417
 
   mapped_head_read,
418
 
   mapped_head_shift,
419
 
   mapped_skip_bytes,
420
 
   mapped_read_frame_body,
421
 
   mapped_back_bytes,
422
 
   mapped_back_frame,
423
 
   mapped_tell,
424
 
   mapped_rewind } , 
425
 
#endif 
426
 
 { default_init,
427
 
   stream_close,
428
 
   stream_head_read,
429
 
   stream_head_shift,
430
 
   stream_skip_bytes,
431
 
   stream_read_frame_body,
432
 
   stream_back_bytes,
433
 
   stream_back_frame,
434
 
   stream_tell,
435
 
   stream_rewind } ,
436
 
 { NULL, }
437
 
};
438
 
 
439
 
 
440
 
/* open the device to read the bit stream from it */
441
 
 
442
 
void open_stream(char *bs_filenam,int fd)
443
 
{
444
 
    int i;
445
 
    int filept_opened = 1;
446
 
    int filept;
447
 
 
448
 
    if (!bs_filenam) {
449
 
                if(fd < 0) {
450
 
                        filept = 0;
451
 
                        filept_opened = 0;
452
 
                }
453
 
                else
454
 
                        filept = fd;
455
 
        }
456
 
        else if (!strncmp(bs_filenam, "http://", 7)) 
457
 
                filept = http_open(bs_filenam);
458
 
#ifndef O_BINARY
459
 
#define O_BINARY (0)
460
 
#endif
461
 
        else if ( (filept = open(bs_filenam, O_RDONLY|O_BINARY)) < 0) {
462
 
                perror (bs_filenam);
463
 
                exit(1);
464
 
        }
465
 
 
466
 
    rd = NULL;
467
 
    for(i=0;;i++) {
468
 
      readers[i].filelen = -1;
469
 
      readers[i].filept  = filept;
470
 
      readers[i].flags = 0;
471
 
      if(filept_opened)
472
 
        readers[i].flags |= READER_FD_OPENED;
473
 
      if(!readers[i].init) {
474
 
        fprintf(stderr,"Fatal error!\n");
475
 
        exit(1);
476
 
      }
477
 
      if(readers[i].init(readers+i) >= 0) {
478
 
        rd = &readers[i];
479
 
        break;
480
 
      }
481
 
    }
482
 
 
483
 
    if(rd && rd->flags & READER_ID3TAG) {
484
 
      print_id3_tag(rd->id3buf);
485
 
    }
486
 
}
487
 
 
488