summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2004-11-17 12:42:43 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2004-11-17 12:42:43 +0000
commit34145af486b399494ddc27c612ab5643356ff568 (patch)
tree84e1bdaf1855716d588e547f257c80824dc780ec /firmware
parent8071de3da00ff6e7323a2ac811d46ba5de71f05b (diff)
downloadrockbox-34145af486b399494ddc27c612ab5643356ff568.tar.gz
rockbox-34145af486b399494ddc27c612ab5643356ff568.zip
Simplified ID3 tag handling, removing the nasty NULL pointer accesses. Correct handling of missing/corrupt tracks in playlists.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5416 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/mpeg.c168
1 files changed, 62 insertions, 106 deletions
diff --git a/firmware/mpeg.c b/firmware/mpeg.c
index e801f9c845..5a199a4169 100644
--- a/firmware/mpeg.c
+++ b/firmware/mpeg.c
@@ -102,11 +102,10 @@ struct id3tag
102{ 102{
103 struct mp3entry id3; 103 struct mp3entry id3;
104 int mempos; 104 int mempos;
105 bool used; 105 int load_ahead_index;
106}; 106};
107 107
108static struct id3tag *id3tags[MAX_ID3_TAGS]; 108static struct id3tag id3tags[MAX_ID3_TAGS];
109static struct id3tag _id3tags[MAX_ID3_TAGS];
110 109
111static bool v1first = false; 110static bool v1first = false;
112 111
@@ -132,71 +131,35 @@ static void debug_tags(void)
132 131
133 for(i = 0;i < MAX_ID3_TAGS;i++) 132 for(i = 0;i < MAX_ID3_TAGS;i++)
134 { 133 {
135 DEBUGF("id3tags[%d]: %08x", i, id3tags[i]); 134 DEBUGF("%d - %s\n", i, id3tags[i].id3.path);
136 if(id3tags[i])
137 DEBUGF(" - %s", id3tags[i]->id3.path);
138 DEBUGF("\n");
139 } 135 }
140 DEBUGF("read: %d, write :%d\n", tag_read_idx, tag_write_idx); 136 DEBUGF("read: %d, write :%d\n", tag_read_idx, tag_write_idx);
141 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory()); 137 DEBUGF("num_tracks_in_memory: %d\n", num_tracks_in_memory());
142#endif /* #ifdef DEBUG_TAGS */ 138#endif /* #ifdef DEBUG_TAGS */
143} 139}
144 140
145static bool append_tag(struct id3tag *tag)
146{
147 if(num_tracks_in_memory() < MAX_ID3_TAGS - 1)
148 {
149 id3tags[tag_write_idx] = tag;
150 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
151 debug_tags();
152 return true;
153 }
154 else
155 {
156 DEBUGF("Tag memory is full\n");
157 return false;
158 }
159}
160
161static void remove_current_tag(void) 141static void remove_current_tag(void)
162{ 142{
163 int oldidx = tag_read_idx;
164
165 if(num_tracks_in_memory() > 0) 143 if(num_tracks_in_memory() > 0)
166 { 144 {
167 /* First move the index, so nobody tries to access the tag */ 145 /* First move the index, so nobody tries to access the tag */
168 tag_read_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; 146 tag_read_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
169
170 /* Now delete it */
171 id3tags[oldidx]->used = false;
172 id3tags[oldidx] = NULL;
173 debug_tags(); 147 debug_tags();
174 } 148 }
149 else
150 {
151 DEBUGF("remove_current_tag: no tracks to remove\n");
152 }
175} 153}
176 154
177static void remove_all_non_current_tags(void) 155static void remove_all_non_current_tags(void)
178{ 156{
179 int i = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
180
181 while (i != tag_write_idx)
182 {
183 id3tags[i]->used = false;
184 id3tags[i] = NULL;
185
186 i = (i+1) & MAX_ID3_TAGS_MASK;
187 }
188
189 tag_write_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; 157 tag_write_idx = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
190 debug_tags(); 158 debug_tags();
191} 159}
192 160
193static void remove_all_tags(void) 161static void remove_all_tags(void)
194{ 162{
195 int i;
196
197 for(i = 0;i < MAX_ID3_TAGS;i++)
198 remove_current_tag();
199
200 tag_write_idx = tag_read_idx; 163 tag_write_idx = tag_read_idx;
201 164
202 debug_tags(); 165 debug_tags();
@@ -511,7 +474,7 @@ static int get_unplayed_space_current_song(void)
511 { 474 {
512 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; 475 int track_offset = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
513 476
514 space = id3tags[track_offset]->mempos - mp3buf_read; 477 space = id3tags[track_offset].mempos - mp3buf_read;
515 } 478 }
516 else 479 else
517 { 480 {
@@ -698,7 +661,7 @@ void rec_tick(void)
698 661
699void playback_tick(void) 662void playback_tick(void)
700{ 663{
701 id3tags[tag_read_idx]->id3.elapsed += 664 id3tags[tag_read_idx].id3.elapsed +=
702 (current_tick - last_dma_tick) * 1000 / HZ; 665 (current_tick - last_dma_tick) * 1000 / HZ;
703 last_dma_tick = current_tick; 666 last_dma_tick = current_tick;
704} 667}
@@ -725,9 +688,9 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
725 mp3buf_read = 0; 688 mp3buf_read = 0;
726 689
727 /* First, check if we are on a track boundary */ 690 /* First, check if we are on a track boundary */
728 if (num_tracks_in_memory() > 0) 691 if (num_tracks_in_memory() > 1)
729 { 692 {
730 if (mp3buf_read == id3tags[track_offset]->mempos) 693 if (mp3buf_read == id3tags[track_offset].mempos)
731 { 694 {
732 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0); 695 queue_post(&mpeg_queue, MPEG_TRACK_CHANGE, 0);
733 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK; 696 track_offset = (track_offset+1) & MAX_ID3_TAGS_MASK;
@@ -754,19 +717,19 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
754 if (num_tracks_in_memory() > 1) 717 if (num_tracks_in_memory() > 1)
755 { 718 {
756 /* will we move across the track boundary? */ 719 /* will we move across the track boundary? */
757 if (( mp3buf_read < id3tags[track_offset]->mempos ) && 720 if (( mp3buf_read < id3tags[track_offset].mempos ) &&
758 ((mp3buf_read+last_dma_chunk_size) > 721 ((mp3buf_read+last_dma_chunk_size) >
759 id3tags[track_offset]->mempos )) 722 id3tags[track_offset].mempos ))
760 { 723 {
761 /* Make sure that we end exactly on the boundary */ 724 /* Make sure that we end exactly on the boundary */
762 last_dma_chunk_size = id3tags[track_offset]->mempos 725 last_dma_chunk_size = id3tags[track_offset].mempos
763 - mp3buf_read; 726 - mp3buf_read;
764 } 727 }
765 } 728 }
766 729
767 *psize = last_dma_chunk_size & 0xffff; 730 *psize = last_dma_chunk_size & 0xffff;
768 *ppbuf = mp3buf + mp3buf_read; 731 *ppbuf = mp3buf + mp3buf_read;
769 id3tags[tag_read_idx]->id3.offset += last_dma_chunk_size; 732 id3tags[tag_read_idx].id3.offset += last_dma_chunk_size;
770 733
771 /* Update the watermark debug level */ 734 /* Update the watermark debug level */
772 if(unplayed_space_left < lowest_watermark_level) 735 if(unplayed_space_left < lowest_watermark_level)
@@ -804,35 +767,24 @@ static void transfer_end(unsigned char** ppbuf, int* psize)
804 767
805static int add_track_to_tag_list(const char *filename) 768static int add_track_to_tag_list(const char *filename)
806{ 769{
807 struct id3tag *t = NULL; 770 if(num_tracks_in_memory() >= MAX_ID3_TAGS)
808 int i;
809
810 /* find a free tag */
811 for (i=0; i < MAX_ID3_TAGS_MASK; i++ )
812 if ( !_id3tags[i].used )
813 t = &_id3tags[i];
814 if(t)
815 { 771 {
816 /* grab id3 tag of new file and 772 DEBUGF("Tag memory is full\n");
817 remember where in memory it starts */ 773 return -1;
818 if(mp3info(&(t->id3), filename, v1first))
819 {
820 DEBUGF("Bad mp3\n");
821 return -1;
822 }
823 t->mempos = mp3buf_write;
824 t->id3.elapsed = 0;
825 if(!append_tag(t))
826 {
827 DEBUGF("Tag list is full\n");
828 }
829 else
830 t->used = true;
831 } 774 }
832 else 775
776 /* grab id3 tag of new file and
777 remember where in memory it starts */
778 if(mp3info(&id3tags[tag_write_idx].id3, filename, v1first))
833 { 779 {
834 DEBUGF("No memory available for id3 tag"); 780 DEBUGF("Bad mp3\n");
781 return -1;
835 } 782 }
783 id3tags[tag_write_idx].mempos = mp3buf_write;
784 id3tags[tag_write_idx].id3.elapsed = 0;
785
786 tag_write_idx = (tag_write_idx+1) & MAX_ID3_TAGS_MASK;
787 debug_tags();
836 return 0; 788 return 0;
837} 789}
838 790
@@ -842,19 +794,20 @@ static int new_file(int steps)
842 int start = 0; 794 int start = 0;
843 int i; 795 int i;
844 796
845 /* Find out how many steps to advance. Each loaded tag has a "steps" member 797 /* Find out how many steps to advance. The load_ahead_index field tells
846 that tells us how many playlist entries it had to skip to get to 798 us how many playlist entries it had to skip to get to a valid one.
847 a valid one. We add those together to find out where to start. */ 799 We add those together to find out where to start. */
848 i = tag_read_idx; 800 if(steps > 0 && num_tracks_in_memory() > 1)
849 while(i != tag_write_idx)
850 { 801 {
851 start += id3tags[i]->id3.index; 802 /* Begin with the song after the currently playing one */
852 i = (i+1) & MAX_ID3_TAGS_MASK; 803 i = (tag_read_idx + 1) & MAX_ID3_TAGS_MASK;
804 while(i != tag_write_idx)
805 {
806 start += id3tags[i].load_ahead_index;
807 i = (i+1) & MAX_ID3_TAGS_MASK;
808 }
853 } 809 }
854 810
855 if (start < 0)
856 start = 0;
857
858 do { 811 do {
859 char *trackname; 812 char *trackname;
860 813
@@ -862,7 +815,7 @@ static int new_file(int steps)
862 if ( !trackname ) 815 if ( !trackname )
863 return -1; 816 return -1;
864 817
865 DEBUGF("playing %s\n", trackname); 818 DEBUGF("Loading %s\n", trackname);
866 819
867 mpeg_file = open(trackname, O_RDONLY); 820 mpeg_file = open(trackname, O_RDONLY);
868 if(mpeg_file < 0) { 821 if(mpeg_file < 0) {
@@ -879,7 +832,10 @@ static int new_file(int steps)
879 if(add_track_to_tag_list(trackname)) 832 if(add_track_to_tag_list(trackname))
880 { 833 {
881 /* Bad mp3 file */ 834 /* Bad mp3 file */
882 steps++; 835 if(steps < 0)
836 steps--;
837 else
838 steps++;
883 close(mpeg_file); 839 close(mpeg_file);
884 mpeg_file = -1; 840 mpeg_file = -1;
885 } 841 }
@@ -887,18 +843,19 @@ static int new_file(int steps)
887 { 843 {
888 /* skip past id3v2 tag */ 844 /* skip past id3v2 tag */
889 lseek(mpeg_file, 845 lseek(mpeg_file,
890 id3tags[new_tag_idx]->id3.first_frame_offset, 846 id3tags[new_tag_idx].id3.first_frame_offset,
891 SEEK_SET); 847 SEEK_SET);
892 id3tags[new_tag_idx]->id3.index = steps; 848 id3tags[new_tag_idx].id3.index = steps;
893 id3tags[new_tag_idx]->id3.offset = 0; 849 id3tags[new_tag_idx].load_ahead_index = steps;
850 id3tags[new_tag_idx].id3.offset = 0;
894 851
895 if(id3tags[new_tag_idx]->id3.vbr) 852 if(id3tags[new_tag_idx].id3.vbr)
896 /* Average bitrate * 1.5 */ 853 /* Average bitrate * 1.5 */
897 recalculate_watermark( 854 recalculate_watermark(
898 (id3tags[new_tag_idx]->id3.bitrate * 3) / 2); 855 (id3tags[new_tag_idx].id3.bitrate * 3) / 2);
899 else 856 else
900 recalculate_watermark( 857 recalculate_watermark(
901 id3tags[new_tag_idx]->id3.bitrate); 858 id3tags[new_tag_idx].id3.bitrate);
902 859
903 } 860 }
904 } 861 }
@@ -930,8 +887,8 @@ static void update_playlist(void)
930 887
931 if (num_tracks_in_memory() > 0) 888 if (num_tracks_in_memory() > 0)
932 { 889 {
933 index = playlist_next(id3tags[tag_read_idx]->id3.index); 890 index = playlist_next(id3tags[tag_read_idx].id3.index);
934 id3tags[tag_read_idx]->id3.index = index; 891 id3tags[tag_read_idx].id3.index = index;
935 } 892 }
936} 893}
937 894
@@ -1133,7 +1090,7 @@ static void mpeg_thread(void)
1133 1090
1134 /* mid-song resume? */ 1091 /* mid-song resume? */
1135 if (start_offset) { 1092 if (start_offset) {
1136 struct mp3entry* id3 = &id3tags[tag_read_idx]->id3; 1093 struct mp3entry* id3 = &id3tags[tag_read_idx].id3;
1137 lseek(mpeg_file, start_offset, SEEK_SET); 1094 lseek(mpeg_file, start_offset, SEEK_SET);
1138 id3->offset = start_offset; 1095 id3->offset = start_offset;
1139 set_elapsed(id3); 1096 set_elapsed(id3);
@@ -1141,7 +1098,7 @@ static void mpeg_thread(void)
1141 else { 1098 else {
1142 /* skip past id3v2 tag */ 1099 /* skip past id3v2 tag */
1143 lseek(mpeg_file, 1100 lseek(mpeg_file,
1144 id3tags[tag_read_idx]->id3.first_frame_offset, 1101 id3tags[tag_read_idx].id3.first_frame_offset,
1145 SEEK_SET); 1102 SEEK_SET);
1146 1103
1147 } 1104 }
@@ -1204,7 +1161,7 @@ static void mpeg_thread(void)
1204 mp3_play_pause(false); 1161 mp3_play_pause(false);
1205 1162
1206 track_change(); 1163 track_change();
1207 mp3buf_read = id3tags[tag_read_idx]->mempos; 1164 mp3buf_read = id3tags[tag_read_idx].mempos;
1208 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song()); 1165 last_dma_chunk_size = MIN(0x2000, get_unplayed_space_current_song());
1209 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end); 1166 mp3_play_data(mp3buf + mp3buf_read, last_dma_chunk_size, transfer_end);
1210 dma_underrun = false; 1167 dma_underrun = false;
@@ -1332,7 +1289,7 @@ static void mpeg_thread(void)
1332 1289
1333 while (i != j) 1290 while (i != j)
1334 { 1291 {
1335 curpos += id3tags[i]->id3.filesize; 1292 curpos += id3tags[i].id3.filesize;
1336 i = (i+1) & MAX_ID3_TAGS_MASK; 1293 i = (i+1) & MAX_ID3_TAGS_MASK;
1337 } 1294 }
1338 } 1295 }
@@ -1437,7 +1394,7 @@ static void mpeg_thread(void)
1437 int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK; 1394 int next = (tag_read_idx+1) & MAX_ID3_TAGS_MASK;
1438 1395
1439 /* Reset the buffer */ 1396 /* Reset the buffer */
1440 mp3buf_write = id3tags[next]->mempos; 1397 mp3buf_write = id3tags[next].mempos;
1441 1398
1442 /* Reset swapwrite unless we're still swapping current 1399 /* Reset swapwrite unless we're still swapping current
1443 track */ 1400 track */
@@ -2031,7 +1988,7 @@ struct mp3entry* mpeg_current_track()
2031 return &taginfo; 1988 return &taginfo;
2032#else 1989#else
2033 if(num_tracks_in_memory()) 1990 if(num_tracks_in_memory())
2034 return &(id3tags[tag_read_idx]->id3); 1991 return &id3tags[tag_read_idx].id3;
2035 else 1992 else
2036 return NULL; 1993 return NULL;
2037#endif /* #ifdef SIMULATOR */ 1994#endif /* #ifdef SIMULATOR */
@@ -2043,7 +2000,7 @@ struct mp3entry* mpeg_next_track()
2043 return &taginfo; 2000 return &taginfo;
2044#else 2001#else
2045 if(num_tracks_in_memory() > 1) 2002 if(num_tracks_in_memory() > 1)
2046 return &(id3tags[(tag_read_idx+1) & MAX_ID3_TAGS_MASK]->id3); 2003 return &(id3tags[(tag_read_idx+1) & MAX_ID3_TAGS_MASK].id3);
2047 else 2004 else
2048 return NULL; 2005 return NULL;
2049#endif /* #ifdef SIMULATOR */ 2006#endif /* #ifdef SIMULATOR */
@@ -2692,7 +2649,6 @@ void mpeg_init(void)
2692 sizeof(mpeg_stack), mpeg_thread_name); 2649 sizeof(mpeg_stack), mpeg_thread_name);
2693 2650
2694 memset(id3tags, sizeof(id3tags), 0); 2651 memset(id3tags, sizeof(id3tags), 0);
2695 memset(_id3tags, sizeof(id3tags), 0);
2696 2652
2697#if CONFIG_HWCODEC == MAS3587F 2653#if CONFIG_HWCODEC == MAS3587F
2698 if(read_hw_mask() & PR_ACTIVE_HIGH) 2654 if(read_hw_mask() & PR_ACTIVE_HIGH)