diff options
author | Linus Nielsen Feltzing <linus@haxx.se> | 2003-04-19 01:59:23 +0000 |
---|---|---|
committer | Linus Nielsen Feltzing <linus@haxx.se> | 2003-04-19 01:59:23 +0000 |
commit | 7fdef57d572a5f81f5efec4fd6f73a4f797cc823 (patch) | |
tree | f686ce671a0b1d1bce0418a7bbb3400789fb6094 /apps | |
parent | 1c32bd0f48605b9ee4623418812c30bc9ca4ba1b (diff) | |
download | rockbox-7fdef57d572a5f81f5efec4fd6f73a4f797cc823.tar.gz rockbox-7fdef57d572a5f81f5efec4fd6f73a4f797cc823.zip |
Better generation of Xing headers, now they contain the correct MPEG version and sample rate info.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@3567 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/onplay.c | 130 |
1 files changed, 65 insertions, 65 deletions
diff --git a/apps/onplay.c b/apps/onplay.c index ceaae2c238..3ba4c1b49c 100644 --- a/apps/onplay.c +++ b/apps/onplay.c | |||
@@ -210,14 +210,15 @@ static const unsigned char empty_id3_header[] = | |||
210 | 210 | ||
211 | static bool vbr_fix(void) | 211 | static bool vbr_fix(void) |
212 | { | 212 | { |
213 | unsigned char xingbuf[417]; | 213 | unsigned char xingbuf[1500]; |
214 | struct mp3entry entry; | 214 | struct mp3entry entry; |
215 | int fd; | 215 | int fd; |
216 | int rc; | 216 | int rc; |
217 | int flen; | 217 | int flen; |
218 | int num_frames; | 218 | int num_frames; |
219 | int fpos; | ||
220 | int numbytes; | 219 | int numbytes; |
220 | int framelen; | ||
221 | int unused_space; | ||
221 | 222 | ||
222 | if(mpeg_status()) { | 223 | if(mpeg_status()) { |
223 | splash(HZ*2, 0, true, str(LANG_VBRFIX_STOP_PLAY)); | 224 | splash(HZ*2, 0, true, str(LANG_VBRFIX_STOP_PLAY)); |
@@ -250,26 +251,45 @@ static bool vbr_fix(void) | |||
250 | flen, xingupdate); | 251 | flen, xingupdate); |
251 | 252 | ||
252 | if(num_frames) { | 253 | if(num_frames) { |
253 | create_xing_header(fd, entry.first_frame_offset, | 254 | /* Note: We don't need to pass any values for mpeg_version and |
254 | flen, xingbuf, num_frames, xingupdate, true); | 255 | sample_rate because they will be extracted from the mpeg stream */ |
256 | framelen = create_xing_header(fd, entry.first_frame_offset, | ||
257 | flen, xingbuf, num_frames, | ||
258 | 0, 0, xingupdate, true); | ||
255 | 259 | ||
256 | /* Try to fit the Xing header first in the stream. Replace the existing | 260 | /* Try to fit the Xing header first in the stream. Replace the existing |
257 | Xing header if there is one, else see if there is room between the | 261 | VBR header if there is one, else see if there is room between the |
258 | ID3 tag and the first MP3 frame. */ | 262 | ID3 tag and the first MP3 frame. */ |
259 | if(entry.vbr_header_pos) { | 263 | if(entry.first_frame_offset - entry.id3v2len >= |
260 | /* Reuse existing Xing header */ | 264 | (unsigned int)framelen) { |
261 | fpos = entry.vbr_header_pos; | 265 | DEBUGF("Using existing space between ID3 and first frame\n"); |
262 | 266 | ||
263 | DEBUGF("Reusing Xing header at %d\n", fpos); | 267 | /* Seek to the beginning of the unused space */ |
264 | 268 | rc = lseek(fd, entry.id3v2len, SEEK_SET); | |
265 | rc = lseek(fd, entry.vbr_header_pos, SEEK_SET); | ||
266 | if(rc < 0) { | 269 | if(rc < 0) { |
267 | close(fd); | 270 | close(fd); |
268 | fileerror(rc); | 271 | fileerror(rc); |
269 | return true; | 272 | return true; |
270 | } | 273 | } |
274 | |||
275 | unused_space = | ||
276 | entry.first_frame_offset - entry.id3v2len - framelen; | ||
271 | 277 | ||
272 | rc = write(fd, xingbuf, 417); | 278 | /* Fill the unused space with 0's (using the MP3 buffer) |
279 | and write it to the file */ | ||
280 | if(unused_space) | ||
281 | { | ||
282 | memset(mp3buf, 0, unused_space); | ||
283 | rc = write(fd, mp3buf, unused_space); | ||
284 | if(rc < 0) { | ||
285 | close(fd); | ||
286 | fileerror(rc); | ||
287 | return true; | ||
288 | } | ||
289 | } | ||
290 | |||
291 | /* Then write the Xing header */ | ||
292 | rc = write(fd, xingbuf, framelen); | ||
273 | if(rc < 0) { | 293 | if(rc < 0) { |
274 | close(fd); | 294 | close(fd); |
275 | fileerror(rc); | 295 | fileerror(rc); |
@@ -278,61 +298,41 @@ static bool vbr_fix(void) | |||
278 | 298 | ||
279 | close(fd); | 299 | close(fd); |
280 | } else { | 300 | } else { |
281 | /* Any room between ID3 tag and first MP3 frame? */ | 301 | /* If not, insert some space. If there is an ID3 tag in the |
282 | if(entry.first_frame_offset - entry.id3v2len > 417) { | 302 | file we only insert just enough to squeeze the Xing header |
283 | DEBUGF("Using existing space between ID3 and first frame\n"); | 303 | in. If not, we insert an additional empty ID3 tag of 4K. */ |
284 | rc = lseek(fd, entry.first_frame_offset - 417, SEEK_SET); | 304 | |
285 | if(rc < 0) { | 305 | close(fd); |
286 | close(fd); | 306 | |
287 | fileerror(rc); | 307 | /* Nasty trick alert! The insert_data_in_file() function |
288 | return true; | 308 | uses the MP3 buffer when copying the data. We assume |
289 | } | 309 | that the ID3 tag isn't longer than 1MB so the xing |
290 | 310 | buffer won't be overwritten. */ | |
291 | rc = write(fd, xingbuf, 417); | 311 | |
292 | if(rc < 0) { | 312 | if(entry.first_frame_offset) { |
293 | close(fd); | 313 | DEBUGF("Inserting %d bytes\n", framelen); |
294 | fileerror(rc); | 314 | numbytes = framelen; |
295 | return true; | ||
296 | } | ||
297 | |||
298 | close(fd); | ||
299 | } else { | 315 | } else { |
300 | /* If not, insert some space. If there is an ID3 tag in the | 316 | DEBUGF("Inserting 4096+%d bytes\n", framelen); |
301 | file we only insert just enough to squeeze the Xing header | 317 | numbytes = 4096 + framelen; |
302 | in. If not, we insert an additional empty ID3 tag of 4K. */ | ||
303 | |||
304 | close(fd); | ||
305 | |||
306 | /* Nasty trick alert! The insert_data_in_file() function | ||
307 | uses the MP3 buffer when copying the data. We assume | ||
308 | that the ID3 tag isn't longer than 1MB so the xing | ||
309 | buffer won't be overwritten. */ | ||
310 | |||
311 | if(entry.first_frame_offset) { | ||
312 | DEBUGF("Inserting 417 bytes\n"); | ||
313 | numbytes = 417; | ||
314 | } else { | ||
315 | DEBUGF("Inserting 4096+417 bytes\n"); | ||
316 | numbytes = 4096 + 417; | ||
317 | |||
318 | memset(mp3buf + 0x100000, 0, numbytes); | ||
319 | |||
320 | /* Insert the ID3 header */ | ||
321 | memcpy(mp3buf + 0x100000, empty_id3_header, | ||
322 | sizeof(empty_id3_header)); | ||
323 | } | ||
324 | |||
325 | /* Copy the Xing header */ | ||
326 | memcpy(mp3buf + 0x100000 + numbytes - 417, xingbuf, 417); | ||
327 | 318 | ||
328 | rc = insert_data_in_file(selected_file, | 319 | memset(mp3buf + 0x100000, 0, numbytes); |
329 | entry.first_frame_offset, | ||
330 | mp3buf + 0x100000, numbytes); | ||
331 | 320 | ||
332 | if(rc < 0) { | 321 | /* Insert the ID3 header */ |
333 | fileerror(rc); | 322 | memcpy(mp3buf + 0x100000, empty_id3_header, |
334 | return true; | 323 | sizeof(empty_id3_header)); |
335 | } | 324 | } |
325 | |||
326 | /* Copy the Xing header */ | ||
327 | memcpy(mp3buf + 0x100000 + numbytes - framelen, xingbuf, framelen); | ||
328 | |||
329 | rc = insert_data_in_file(selected_file, | ||
330 | entry.first_frame_offset, | ||
331 | mp3buf + 0x100000, numbytes); | ||
332 | |||
333 | if(rc < 0) { | ||
334 | fileerror(rc); | ||
335 | return true; | ||
336 | } | 336 | } |
337 | } | 337 | } |
338 | 338 | ||