annotate decoders/libmpg123/index.c @ 562:7e08477b0fc1

MP3 decoder upgrade work. Ripped out SMPEG and mpglib support, replaced it with "mpg123.c" and libmpg123. libmpg123 is a much better version of mpglib, so it should solve all the problems about MP3's not seeking, or most modern MP3's not playing at all, etc. Since you no longer have to make a tradeoff with SMPEG for features, and SMPEG is basically rotting, I removed it from the project. There is still work to be done with libmpg123...there are MMX, 3DNow, SSE, Altivec, etc decoders which we don't have enabled at the moment, and the build system could use some work to make this compile more cleanly, etc. Still: huge win.
author Ryan C. Gordon <icculus@icculus.org>
date Fri, 30 Jan 2009 02:44:47 -0500
parents
children
rev   line source
562
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
1 /*
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
2 index: frame index data structure and functions
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
3
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
4 copyright 2007-8 by the mpg123 project - free software under the terms of the LGPL 2.1
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
6 initially written by Thomas Orgis
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
7 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
8
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
9 #include "index.h"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
10 #include "debug.h"
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
11
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
12 /* The next expected frame offset, one step ahead. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
13 static off_t fi_next(struct frame_index *fi)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
14 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
15 return (off_t)fi->fill*fi->step;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
16 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
17
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
18 /* Shrink down the used index to the half.
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
19 Be careful with size = 1 ... there's no shrinking possible there. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
20 static void fi_shrink(struct frame_index *fi)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
21 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
22 if(fi->fill < 2) return; /* Won't shrink below 1. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
23 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
24 { /* Double the step, half the fill. Should work as well for fill%2 = 1 */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
25 size_t c;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
26 debug2("shrink index with fill %lu and step %lu", (unsigned long)fi->fill, (unsigned long)fi->step);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
27 fi->step *= 2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
28 fi->fill /= 2;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
29 /* Move the data down. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
30 for(c = 0; c < fi->fill; ++c)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
31 fi->data[c] = fi->data[2*c];
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
32 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
33
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
34 fi->next = fi_next(fi);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
35 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
36
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
37 void fi_init(struct frame_index *fi)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
38 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
39 fi->data = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
40 fi->step = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
41 fi->fill = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
42 fi->size = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
43 fi->grow_size = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
44 fi->next = fi_next(fi);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
45 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
46
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
47 void fi_exit(struct frame_index *fi)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
48 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
49 debug2("fi_exit: %p and %lu", (void*)fi->data, (unsigned long)fi->size);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
50 if(fi->size && fi->data != NULL) free(fi->data);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
51
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
52 fi_init(fi); /* Be prepared for further fun, still. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
53 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
54
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
55 int fi_resize(struct frame_index *fi, size_t newsize)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
56 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
57 off_t *newdata = NULL;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
58 if(newsize == fi->size) return 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
59
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
60 if(newsize > 0 && newsize < fi->size)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
61 { /* When we reduce buffer size a bit, shrink stuff. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
62 while(fi->fill > newsize){ fi_shrink(fi); }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
63 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
64
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
65 newdata = safe_realloc(fi->data, newsize*sizeof(off_t));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
66 if(newsize == 0 || newdata != NULL)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
67 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
68 fi->data = newdata;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
69 fi->size = newsize;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
70 if(fi->fill > fi->size) fi->fill = fi->size;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
71
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
72 fi->next = fi_next(fi);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
73 debug2("new index of size %lu at %p", (unsigned long)fi->size, (void*)fi->data);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
74 return 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
75 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
76 else
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
77 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
78 error("failed to resize index!");
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
79 return -1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
80 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
81 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
82
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
83 void fi_add(struct frame_index *fi, off_t pos)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
84 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
85 debug3("wanting to add to fill %lu, step %lu, size %lu", (unsigned long)fi->fill, (unsigned long)fi->step, (unsigned long)fi->size);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
86 if(fi->fill == fi->size)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
87 { /* Index is full, we need to shrink... or grow. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
88 /* Store the current frame number to check later if we still want it. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
89 off_t framenum = fi->fill*fi->step;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
90 /* If we want not / cannot grow, we shrink. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
91 if( !(fi->grow_size && fi_resize(fi, fi->size+fi->grow_size)==0) )
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
92 fi_shrink(fi);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
93
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
94 /* Now check if we still want to add this frame (could be that not, because of changed step). */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
95 if(fi->next != framenum) return;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
96 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
97 /* When we are here, we want that frame. */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
98 if(fi->fill < fi->size) /* safeguard for size=1, or just generally */
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
99 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
100 debug1("adding to index at %p", (void*)(fi->data+fi->fill));
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
101 fi->data[fi->fill] = pos;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
102 ++fi->fill;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
103 fi->next = fi_next(fi);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
104 debug3("added pos %li to index with fill %lu and step %lu", (long) pos, (unsigned long)fi->fill, (unsigned long)fi->step);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
105 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
106 }
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
107
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
108 void fi_reset(struct frame_index *fi)
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
109 {
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
110 debug1("reset with size %zu", fi->size);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
111 fi->fill = 0;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
112 fi->step = 1;
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
113 fi->next = fi_next(fi);
7e08477b0fc1 MP3 decoder upgrade work.
Ryan C. Gordon <icculus@icculus.org>
parents:
diff changeset
114 }