diff options
author | Jens Arnold <amiconn@rockbox.org> | 2005-09-15 05:29:26 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2005-09-15 05:29:26 +0000 |
commit | ba966c17614fc2de2b443a82071415b194753aa4 (patch) | |
tree | 85b1af551200ab551b4e52a57008ca92ca454e29 | |
parent | 0c1a2c7651c0727f2a5565e1302f50f64202a9f6 (diff) | |
download | rockbox-ba966c17614fc2de2b443a82071415b194753aa4.tar.gz rockbox-ba966c17614fc2de2b443a82071415b194753aa4.zip |
Archos recording/playback: (1) Xing header creation: * Now estimates the framecount from the recording time if the MAS frame counter saturates, so it always writes a valid Xing header. * Reverted my brainless short-xing-header change. This was only valid for layer 3. (2) Xing/VBRI header evaluation: Fixed possible overflow in bitrate calculation. (3) MPEG thread: Avoid double chunk size limiting for the rare case of 8 MB modded Ondios.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@7522 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/codecs.h | 10 | ||||
-rw-r--r-- | apps/plugin.h | 10 | ||||
-rw-r--r-- | apps/plugins/vbrfix.c | 2 | ||||
-rw-r--r-- | firmware/export/mp3data.h | 11 | ||||
-rw-r--r-- | firmware/export/mpeg.h | 2 | ||||
-rw-r--r-- | firmware/mp3data.c | 96 | ||||
-rw-r--r-- | firmware/mpeg.c | 35 |
7 files changed, 89 insertions, 77 deletions
diff --git a/apps/codecs.h b/apps/codecs.h index 517d68ba03..d7242a8330 100644 --- a/apps/codecs.h +++ b/apps/codecs.h | |||
@@ -79,12 +79,12 @@ | |||
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | /* increase this every time the api struct changes */ | 81 | /* increase this every time the api struct changes */ |
82 | #define CODEC_API_VERSION 43 | 82 | #define CODEC_API_VERSION 44 |
83 | 83 | ||
84 | /* update this to latest version if a change to the api struct breaks | 84 | /* update this to latest version if a change to the api struct breaks |
85 | backwards compatibility (and please take the opportunity to sort in any | 85 | backwards compatibility (and please take the opportunity to sort in any |
86 | new function which are "waiting" at the end of the function table) */ | 86 | new function which are "waiting" at the end of the function table) */ |
87 | #define CODEC_MIN_API_VERSION 43 | 87 | #define CODEC_MIN_API_VERSION 44 |
88 | 88 | ||
89 | /* codec return codes */ | 89 | /* codec return codes */ |
90 | enum codec_status { | 90 | enum codec_status { |
@@ -303,9 +303,9 @@ struct codec_api { | |||
303 | bool (*mp3info)(struct mp3entry *entry, const char *filename, bool v1first); | 303 | bool (*mp3info)(struct mp3entry *entry, const char *filename, bool v1first); |
304 | int (*count_mp3_frames)(int fd, int startpos, int filesize, | 304 | int (*count_mp3_frames)(int fd, int startpos, int filesize, |
305 | void (*progressfunc)(int)); | 305 | void (*progressfunc)(int)); |
306 | int (*create_xing_header)(int fd, int startpos, int filesize, | 306 | int (*create_xing_header)(int fd, long startpos, long filesize, |
307 | unsigned char *buf, int num_frames, | 307 | unsigned char *buf, unsigned long num_frames, |
308 | unsigned long header_template, | 308 | unsigned long rec_time, unsigned long header_template, |
309 | void (*progressfunc)(int), bool generate_toc); | 309 | void (*progressfunc)(int), bool generate_toc); |
310 | unsigned long (*find_next_frame)(int fd, long *offset, | 310 | unsigned long (*find_next_frame)(int fd, long *offset, |
311 | long max_offset, unsigned long last_header); | 311 | long max_offset, unsigned long last_header); |
diff --git a/apps/plugin.h b/apps/plugin.h index 01ace98690..5cc9c1b58a 100644 --- a/apps/plugin.h +++ b/apps/plugin.h | |||
@@ -89,12 +89,12 @@ | |||
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | /* increase this every time the api struct changes */ | 91 | /* increase this every time the api struct changes */ |
92 | #define PLUGIN_API_VERSION 50 | 92 | #define PLUGIN_API_VERSION 51 |
93 | 93 | ||
94 | /* update this to latest version if a change to the api struct breaks | 94 | /* update this to latest version if a change to the api struct breaks |
95 | backwards compatibility (and please take the opportunity to sort in any | 95 | backwards compatibility (and please take the opportunity to sort in any |
96 | new function which are "waiting" at the end of the function table) */ | 96 | new function which are "waiting" at the end of the function table) */ |
97 | #define PLUGIN_MIN_API_VERSION 50 | 97 | #define PLUGIN_MIN_API_VERSION 51 |
98 | 98 | ||
99 | /* plugin return codes */ | 99 | /* plugin return codes */ |
100 | enum plugin_status { | 100 | enum plugin_status { |
@@ -404,9 +404,9 @@ struct plugin_api { | |||
404 | bool (*mp3info)(struct mp3entry *entry, const char *filename, bool v1first); | 404 | bool (*mp3info)(struct mp3entry *entry, const char *filename, bool v1first); |
405 | int (*count_mp3_frames)(int fd, int startpos, int filesize, | 405 | int (*count_mp3_frames)(int fd, int startpos, int filesize, |
406 | void (*progressfunc)(int)); | 406 | void (*progressfunc)(int)); |
407 | int (*create_xing_header)(int fd, int startpos, int filesize, | 407 | int (*create_xing_header)(int fd, long startpos, long filesize, |
408 | unsigned char *buf, int num_frames, | 408 | unsigned char *buf, unsigned long num_frames, |
409 | unsigned long header_template, | 409 | unsigned long rec_time, unsigned long header_template, |
410 | void (*progressfunc)(int), bool generate_toc); | 410 | void (*progressfunc)(int), bool generate_toc); |
411 | unsigned long (*find_next_frame)(int fd, long *offset, | 411 | unsigned long (*find_next_frame)(int fd, long *offset, |
412 | long max_offset, unsigned long last_header); | 412 | long max_offset, unsigned long last_header); |
diff --git a/apps/plugins/vbrfix.c b/apps/plugins/vbrfix.c index b821b9c5fa..ca6b9ca096 100644 --- a/apps/plugins/vbrfix.c +++ b/apps/plugins/vbrfix.c | |||
@@ -168,7 +168,7 @@ static bool vbr_fix(char *selected_file) | |||
168 | /* Note: We don't need to pass a template header because it will be | 168 | /* Note: We don't need to pass a template header because it will be |
169 | taken from the mpeg stream */ | 169 | taken from the mpeg stream */ |
170 | framelen = rb->create_xing_header(fd, entry.first_frame_offset, | 170 | framelen = rb->create_xing_header(fd, entry.first_frame_offset, |
171 | flen, xingbuf, num_frames, | 171 | flen, xingbuf, num_frames, 0, |
172 | 0, xingupdate, true); | 172 | 0, xingupdate, true); |
173 | 173 | ||
174 | /* Try to fit the Xing header first in the stream. Replace the existing | 174 | /* Try to fit the Xing header first in the stream. Replace the existing |
diff --git a/firmware/export/mp3data.h b/firmware/export/mp3data.h index 3961664815..f36120a4e5 100644 --- a/firmware/export/mp3data.h +++ b/firmware/export/mp3data.h | |||
@@ -59,17 +59,18 @@ struct mp3info { | |||
59 | #define VBR_TOC_FLAG 0x04 | 59 | #define VBR_TOC_FLAG 0x04 |
60 | #define VBR_QUALITY_FLAG 0x08 | 60 | #define VBR_QUALITY_FLAG 0x08 |
61 | 61 | ||
62 | #define MAX_XING_HEADER_SIZE 288 | 62 | #define MAX_XING_HEADER_SIZE 576 |
63 | 63 | ||
64 | unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header); | 64 | unsigned long find_next_frame(int fd, long *offset, long max_offset, |
65 | unsigned long last_header); | ||
65 | unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, | 66 | unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, |
66 | unsigned long last_header); | 67 | unsigned long last_header); |
67 | int get_mp3file_info(int fd, struct mp3info *info); | 68 | int get_mp3file_info(int fd, struct mp3info *info); |
68 | int count_mp3_frames(int fd, int startpos, int filesize, | 69 | int count_mp3_frames(int fd, int startpos, int filesize, |
69 | void (*progressfunc)(int)); | 70 | void (*progressfunc)(int)); |
70 | int create_xing_header(int fd, int startpos, int filesize, | 71 | int create_xing_header(int fd, long startpos, long filesize, |
71 | unsigned char *buf, int num_frames, | 72 | unsigned char *buf, unsigned long num_frames, |
72 | unsigned long header_template, | 73 | unsigned long rec_time, unsigned long header_template, |
73 | void (*progressfunc)(int), bool generate_toc); | 74 | void (*progressfunc)(int), bool generate_toc); |
74 | 75 | ||
75 | #endif | 76 | #endif |
diff --git a/firmware/export/mpeg.h b/firmware/export/mpeg.h index a0ad3c405c..a7c9cac321 100644 --- a/firmware/export/mpeg.h +++ b/firmware/export/mpeg.h | |||
@@ -41,7 +41,7 @@ | |||
41 | #define MPEG_MAX_PRERECORD_SECONDS 30 | 41 | #define MPEG_MAX_PRERECORD_SECONDS 30 |
42 | 42 | ||
43 | /* For ID3 info and VBR header */ | 43 | /* For ID3 info and VBR header */ |
44 | #define MPEG_RESERVED_HEADER_SPACE (4096 + 288) | 44 | #define MPEG_RESERVED_HEADER_SPACE (4096 + 576) |
45 | 45 | ||
46 | #if (CONFIG_CODEC == MAS3587F) || defined(SIMULATOR) | 46 | #if (CONFIG_CODEC == MAS3587F) || defined(SIMULATOR) |
47 | void mpeg_init_recording(void); | 47 | void mpeg_init_recording(void); |
diff --git a/firmware/mp3data.c b/firmware/mp3data.c index c2d4cd2c37..519bc60b04 100644 --- a/firmware/mp3data.c +++ b/firmware/mp3data.c | |||
@@ -406,7 +406,7 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
406 | /* Is it a VBR file? */ | 406 | /* Is it a VBR file? */ |
407 | info->is_vbr = info->is_xing_vbr = !memcmp(vbrheader, "Xing", 4); | 407 | info->is_vbr = info->is_xing_vbr = !memcmp(vbrheader, "Xing", 4); |
408 | 408 | ||
409 | if(vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */ | 409 | if (vbrheader[7] & VBR_FRAMES_FLAG) /* Is the frame count there? */ |
410 | { | 410 | { |
411 | info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], | 411 | info->frame_count = BYTES2INT(vbrheader[i], vbrheader[i+1], |
412 | vbrheader[i+2], vbrheader[i+3]); | 412 | vbrheader[i+2], vbrheader[i+3]); |
@@ -417,19 +417,24 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
417 | i += 4; | 417 | i += 4; |
418 | } | 418 | } |
419 | 419 | ||
420 | if(vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */ | 420 | if (vbrheader[7] & VBR_BYTES_FLAG) /* Is byte count there? */ |
421 | { | 421 | { |
422 | info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1], | 422 | info->byte_count = BYTES2INT(vbrheader[i], vbrheader[i+1], |
423 | vbrheader[i+2], vbrheader[i+3]); | 423 | vbrheader[i+2], vbrheader[i+3]); |
424 | i += 4; | 424 | i += 4; |
425 | } | 425 | } |
426 | 426 | ||
427 | if(info->file_time && info->byte_count) | 427 | if (info->file_time && info->byte_count) |
428 | info->bitrate = info->byte_count * 8 / info->file_time; | 428 | { |
429 | if (info->byte_count <= (ULONG_MAX/8)) | ||
430 | info->bitrate = info->byte_count * 8 / info->file_time; | ||
431 | else | ||
432 | info->bitrate = info->byte_count / (info->file_time >> 3); | ||
433 | } | ||
429 | else | 434 | else |
430 | info->bitrate = 0; | 435 | info->bitrate = 0; |
431 | 436 | ||
432 | if(vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */ | 437 | if (vbrheader[7] & VBR_TOC_FLAG) /* Is table-of-contents there? */ |
433 | { | 438 | { |
434 | memcpy( info->toc, vbrheader+i, 100 ); | 439 | memcpy( info->toc, vbrheader+i, 100 ); |
435 | i += 100; | 440 | i += 100; |
@@ -492,7 +497,11 @@ int get_mp3file_info(int fd, struct mp3info *info) | |||
492 | info->file_time = info->frame_count * info->ft_num / info->ft_den; | 497 | info->file_time = info->frame_count * info->ft_num / info->ft_den; |
493 | else | 498 | else |
494 | info->file_time = info->frame_count / info->ft_den * info->ft_num; | 499 | info->file_time = info->frame_count / info->ft_den * info->ft_num; |
495 | info->bitrate = info->byte_count * 8 / info->file_time; | 500 | |
501 | if (info->byte_count <= (ULONG_MAX/8)) | ||
502 | info->bitrate = info->byte_count * 8 / info->file_time; | ||
503 | else | ||
504 | info->bitrate = info->byte_count / (info->file_time >> 3); | ||
496 | 505 | ||
497 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ | 506 | /* We don't parse the TOC, since we don't yet know how to (FIXME) */ |
498 | num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]); | 507 | num_offsets = BYTES2INT(0, 0, vbrheader[18], vbrheader[19]); |
@@ -587,37 +596,35 @@ int count_mp3_frames(int fd, int startpos, int filesize, | |||
587 | 596 | ||
588 | static const char cooltext[] = "Rockbox - rocks your box"; | 597 | static const char cooltext[] = "Rockbox - rocks your box"; |
589 | 598 | ||
590 | int create_xing_header(int fd, int startpos, int filesize, | 599 | /* buf needs to be the audio buffer with TOC generation enabled, |
591 | unsigned char *buf, /* must be at least 288 bytes */ | 600 | and at least MAX_XING_HEADER_SIZE bytes otherwise */ |
592 | int num_frames, unsigned long header_template, | 601 | int create_xing_header(int fd, long startpos, long filesize, |
602 | unsigned char *buf, unsigned long num_frames, | ||
603 | unsigned long rec_time, unsigned long header_template, | ||
593 | void (*progressfunc)(int), bool generate_toc) | 604 | void (*progressfunc)(int), bool generate_toc) |
594 | { | 605 | { |
595 | unsigned long header = 0; | ||
596 | struct mp3info info; | 606 | struct mp3info info; |
597 | int pos, last_pos; | 607 | unsigned char toc[100]; |
598 | int i, j; | 608 | unsigned long header = 0; |
599 | long bytes; | 609 | unsigned long xing_header_template = header_template; |
600 | unsigned long filepos; | 610 | unsigned long filepos; |
601 | int x; | 611 | long pos, last_pos; |
612 | long j; | ||
613 | long bytes; | ||
614 | int i; | ||
602 | int index; | 615 | int index; |
603 | unsigned char toc[100]; | ||
604 | unsigned long xing_header_template = 0; | ||
605 | 616 | ||
606 | DEBUGF("create_xing_header()\n"); | 617 | DEBUGF("create_xing_header()\n"); |
607 | 618 | ||
608 | if(header_template) | ||
609 | xing_header_template = header_template; | ||
610 | |||
611 | if(generate_toc) | 619 | if(generate_toc) |
612 | { | 620 | { |
613 | lseek(fd, startpos, SEEK_SET); | 621 | lseek(fd, startpos, SEEK_SET); |
614 | buf_init(); | 622 | buf_init(); |
615 | 623 | ||
616 | /* Generate filepos table */ | 624 | /* Generate filepos table */ |
617 | last_pos = 0; | 625 | last_pos = 0; |
618 | filepos = 0; | 626 | filepos = 0; |
619 | header = 0; | 627 | header = 0; |
620 | x = 0; | ||
621 | for(i = 0;i < 100;i++) { | 628 | for(i = 0;i < 100;i++) { |
622 | /* Calculate the absolute frame number for this seek point */ | 629 | /* Calculate the absolute frame number for this seek point */ |
623 | pos = i * num_frames / 100; | 630 | pos = i * num_frames / 100; |
@@ -654,7 +661,7 @@ int create_xing_header(int fd, int startpos, int filesize, | |||
654 | * the upper 8 bits of the file position are nonzero | 661 | * the upper 8 bits of the file position are nonzero |
655 | * (i.e. files over 16mb in size). | 662 | * (i.e. files over 16mb in size). |
656 | */ | 663 | */ |
657 | if (filepos > 0xFFFFFF) | 664 | if (filepos > (ULONG_MAX/256)) |
658 | { | 665 | { |
659 | /* instead of multiplying filepos by 256, we divide | 666 | /* instead of multiplying filepos by 256, we divide |
660 | * filesize by 256. | 667 | * filesize by 256. |
@@ -673,46 +680,49 @@ int create_xing_header(int fd, int startpos, int filesize, | |||
673 | } | 680 | } |
674 | } | 681 | } |
675 | 682 | ||
676 | /* Check the template header for validity and get some preliminary info. */ | 683 | /* Use the template header and create a new one. |
677 | if (!mp3headerinfo(&info, xing_header_template)) | 684 | We ignore the Protection bit even if the rest of the stream is |
685 | protected. */ | ||
686 | header = xing_header_template & ~(BITRATE_MASK|PROTECTION_MASK|PADDING_MASK); | ||
687 | header |= 8 << 12; /* This gives us plenty of space, 192..576 bytes */ | ||
688 | |||
689 | if (!mp3headerinfo(&info, header)) | ||
678 | return 0; /* invalid header */ | 690 | return 0; /* invalid header */ |
679 | 691 | ||
692 | if (num_frames == 0 && rec_time) { | ||
693 | /* estimate the number of frames based on the recording time */ | ||
694 | if (rec_time <= ULONG_MAX / info.ft_den) | ||
695 | num_frames = rec_time * info.ft_den / info.ft_num; | ||
696 | else | ||
697 | num_frames = rec_time / info.ft_num * info.ft_den; | ||
698 | } | ||
699 | |||
680 | /* Clear the frame */ | 700 | /* Clear the frame */ |
681 | memset(buf, 0, MAX_XING_HEADER_SIZE); | 701 | memset(buf, 0, MAX_XING_HEADER_SIZE); |
682 | 702 | ||
683 | /* Use the template header and create a new one. */ | 703 | /* Write the header to the buffer */ |
684 | header = xing_header_template & ~(BITRATE_MASK | PROTECTION_MASK); | 704 | long2bytes(buf, header); |
685 | 705 | ||
686 | /* Calculate position of VBR header and required frame bitrate */ | 706 | /* Calculate position of VBR header */ |
687 | if (info.version == MPEG_VERSION1) { | 707 | if (info.version == MPEG_VERSION1) { |
688 | header |= 5 << 12; | ||
689 | if (info.channel_mode == 3) /* mono */ | 708 | if (info.channel_mode == 3) /* mono */ |
690 | index = 21; | 709 | index = 21; |
691 | else | 710 | else |
692 | index = 36; | 711 | index = 36; |
693 | } | 712 | } |
694 | else { | 713 | else { |
695 | if (info.version == MPEG_VERSION2) | ||
696 | header |= 8 << 12; | ||
697 | else /* MPEG_VERSION2_5 */ | ||
698 | header |= 4 << 12; | ||
699 | if (info.channel_mode == 3) /* mono */ | 714 | if (info.channel_mode == 3) /* mono */ |
700 | index = 13; | 715 | index = 13; |
701 | else | 716 | else |
702 | index = 21; | 717 | index = 21; |
703 | } | 718 | } |
704 | mp3headerinfo(&info, header); /* Get final header info */ | ||
705 | /* Size is now always one of 192, 208 or 288 bytes */ | ||
706 | |||
707 | /* Write the header to the buffer */ | ||
708 | long2bytes(buf, header); | ||
709 | 719 | ||
710 | /* Create the Xing data */ | 720 | /* Create the Xing data */ |
711 | memcpy(&buf[index], "Xing", 4); | 721 | memcpy(&buf[index], "Xing", 4); |
712 | long2bytes(&buf[index+4], ((num_frames?VBR_FRAMES_FLAG:0) | | 722 | long2bytes(&buf[index+4], (num_frames ? VBR_FRAMES_FLAG : 0) |
713 | (filesize?VBR_BYTES_FLAG:0) | | 723 | | (filesize ? VBR_BYTES_FLAG : 0) |
714 | (generate_toc?VBR_TOC_FLAG:0))); | 724 | | (generate_toc ? VBR_TOC_FLAG : 0)); |
715 | index = index+8; | 725 | index += 8; |
716 | if(num_frames) | 726 | if(num_frames) |
717 | { | 727 | { |
718 | long2bytes(&buf[index], num_frames); | 728 | long2bytes(&buf[index], num_frames); |
diff --git a/firmware/mpeg.c b/firmware/mpeg.c index 8d2d13b6ee..9d1aa3b9d6 100644 --- a/firmware/mpeg.c +++ b/firmware/mpeg.c | |||
@@ -190,6 +190,7 @@ unsigned long record_start_time; /* Value of current_tick when recording | |||
190 | was started */ | 190 | was started */ |
191 | unsigned long pause_start_time; /* Value of current_tick when pause was | 191 | unsigned long pause_start_time; /* Value of current_tick when pause was |
192 | started */ | 192 | started */ |
193 | static unsigned long last_rec_time; | ||
193 | static unsigned long num_rec_bytes; | 194 | static unsigned long num_rec_bytes; |
194 | static unsigned long last_rec_bytes; | 195 | static unsigned long last_rec_bytes; |
195 | static unsigned long frame_count_start; | 196 | static unsigned long frame_count_start; |
@@ -1611,12 +1612,11 @@ static void mpeg_thread(void) | |||
1611 | /* Don't read more than until the end of the buffer */ | 1612 | /* Don't read more than until the end of the buffer */ |
1612 | amount_to_read = MIN(audiobuflen - audiobuf_write, | 1613 | amount_to_read = MIN(audiobuflen - audiobuf_write, |
1613 | amount_to_read); | 1614 | amount_to_read); |
1614 | #if MEM == 8 | ||
1615 | amount_to_read = MIN(0x100000, amount_to_read); | ||
1616 | #endif /* MEM == 8 */ | ||
1617 | #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */ | 1615 | #ifdef HAVE_MMC /* MMC is slow, so don't read too large chunks */ |
1618 | amount_to_read = MIN(0x40000, amount_to_read); | 1616 | amount_to_read = MIN(0x40000, amount_to_read); |
1619 | #endif /* HAVE_MMC */ | 1617 | #elif MEM == 8 |
1618 | amount_to_read = MIN(0x100000, amount_to_read); | ||
1619 | #endif | ||
1620 | 1620 | ||
1621 | /* Read as much mpeg data as we can fit in the buffer */ | 1621 | /* Read as much mpeg data as we can fit in the buffer */ |
1622 | if(mpeg_file >= 0) | 1622 | if(mpeg_file >= 0) |
@@ -1810,7 +1810,7 @@ static void mpeg_thread(void) | |||
1810 | DEBUGF("MPEG_STOP\n"); | 1810 | DEBUGF("MPEG_STOP\n"); |
1811 | 1811 | ||
1812 | stop_recording(); | 1812 | stop_recording(); |
1813 | 1813 | ||
1814 | /* Save the remaining data in the buffer */ | 1814 | /* Save the remaining data in the buffer */ |
1815 | save_endpos = audiobuf_write; | 1815 | save_endpos = audiobuf_write; |
1816 | saving_status = STOP_RECORDING; | 1816 | saving_status = STOP_RECORDING; |
@@ -1848,7 +1848,7 @@ static void mpeg_thread(void) | |||
1848 | 1848 | ||
1849 | case MPEG_NEW_FILE: | 1849 | case MPEG_NEW_FILE: |
1850 | /* Bail out when a more important save is happening */ | 1850 | /* Bail out when a more important save is happening */ |
1851 | if (saving_status > NEW_FILE) | 1851 | if (saving_status > NEW_FILE) |
1852 | break; | 1852 | break; |
1853 | 1853 | ||
1854 | /* Make sure we have at least one complete frame | 1854 | /* Make sure we have at least one complete frame |
@@ -1865,6 +1865,11 @@ static void mpeg_thread(void) | |||
1865 | mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, | 1865 | mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, |
1866 | &frame_count_end, 1); | 1866 | &frame_count_end, 1); |
1867 | 1867 | ||
1868 | last_rec_time = current_tick - record_start_time; | ||
1869 | record_start_time = current_tick; | ||
1870 | if (paused) | ||
1871 | pause_start_time = record_start_time; | ||
1872 | |||
1868 | /* capture all values at one point */ | 1873 | /* capture all values at one point */ |
1869 | level = set_irq_level(HIGHEST_IRQ_LEVEL); | 1874 | level = set_irq_level(HIGHEST_IRQ_LEVEL); |
1870 | save_endpos = audiobuf_write; | 1875 | save_endpos = audiobuf_write; |
@@ -1916,11 +1921,10 @@ static void mpeg_thread(void) | |||
1916 | 1921 | ||
1917 | amount_to_save = MIN(amount_to_save, | 1922 | amount_to_save = MIN(amount_to_save, |
1918 | audiobuflen - audiobuf_read); | 1923 | audiobuflen - audiobuf_read); |
1919 | #if MEM == 8 | ||
1920 | amount_to_save = MIN(0x100000, amount_to_save); | ||
1921 | #endif | ||
1922 | #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */ | 1924 | #ifdef HAVE_MMC /* MMC is slow, so don't save too large chunks at once */ |
1923 | amount_to_save = MIN(0x40000, amount_to_save); | 1925 | amount_to_save = MIN(0x40000, amount_to_save); |
1926 | #elif MEM == 8 | ||
1927 | amount_to_save = MIN(0x100000, amount_to_save); | ||
1924 | #endif | 1928 | #endif |
1925 | rc = write(mpeg_file, audiobuf + audiobuf_read, | 1929 | rc = write(mpeg_file, audiobuf + audiobuf_read, |
1926 | amount_to_save); | 1930 | amount_to_save); |
@@ -2210,7 +2214,7 @@ void mpeg_record(const char *filename) | |||
2210 | 2214 | ||
2211 | strncpy(recording_filename, filename, MAX_PATH - 1); | 2215 | strncpy(recording_filename, filename, MAX_PATH - 1); |
2212 | recording_filename[MAX_PATH - 1] = 0; | 2216 | recording_filename[MAX_PATH - 1] = 0; |
2213 | 2217 | ||
2214 | queue_post(&mpeg_queue, MPEG_RECORD, NULL); | 2218 | queue_post(&mpeg_queue, MPEG_RECORD, NULL); |
2215 | } | 2219 | } |
2216 | 2220 | ||
@@ -2274,7 +2278,8 @@ static void update_header(void) | |||
2274 | 2278 | ||
2275 | /* saved_header is saved right before stopping the MAS */ | 2279 | /* saved_header is saved right before stopping the MAS */ |
2276 | framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer, | 2280 | framelen = create_xing_header(fd, 0, last_rec_bytes, xing_buffer, |
2277 | frames, saved_header, NULL, false); | 2281 | frames, last_rec_time * (1000/HZ), |
2282 | saved_header, NULL, false); | ||
2278 | 2283 | ||
2279 | lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET); | 2284 | lseek(fd, MPEG_RESERVED_HEADER_SPACE - framelen, SEEK_SET); |
2280 | write(fd, xing_buffer, framelen); | 2285 | write(fd, xing_buffer, framelen); |
@@ -2350,7 +2355,7 @@ static void start_recording(void) | |||
2350 | record_start_time = current_tick; | 2355 | record_start_time = current_tick; |
2351 | 2356 | ||
2352 | pause_start_time = 0; | 2357 | pause_start_time = 0; |
2353 | 2358 | ||
2354 | demand_irq_enable(true); | 2359 | demand_irq_enable(true); |
2355 | } | 2360 | } |
2356 | 2361 | ||
@@ -2398,6 +2403,7 @@ static void stop_recording(void) | |||
2398 | 2403 | ||
2399 | last_rec_bytes = num_rec_bytes; | 2404 | last_rec_bytes = num_rec_bytes; |
2400 | mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1); | 2405 | mas_readmem(MAS_BANK_D0, MAS_D0_MPEG_FRAME_COUNT, &frame_count_end, 1); |
2406 | last_rec_time = current_tick - record_start_time; | ||
2401 | 2407 | ||
2402 | /* Start monitoring */ | 2408 | /* Start monitoring */ |
2403 | shadow_io_control_main |= (1 << 10); | 2409 | shadow_io_control_main |= (1 << 10); |
@@ -2524,11 +2530,6 @@ void mpeg_new_file(const char *filename) | |||
2524 | strncpy(recording_filename, filename, MAX_PATH - 1); | 2530 | strncpy(recording_filename, filename, MAX_PATH - 1); |
2525 | recording_filename[MAX_PATH - 1] = 0; | 2531 | recording_filename[MAX_PATH - 1] = 0; |
2526 | 2532 | ||
2527 | /* Store the current time */ | ||
2528 | record_start_time = current_tick; | ||
2529 | if(paused) | ||
2530 | pause_start_time = record_start_time; | ||
2531 | |||
2532 | queue_post(&mpeg_queue, MPEG_NEW_FILE, NULL); | 2533 | queue_post(&mpeg_queue, MPEG_NEW_FILE, NULL); |
2533 | } | 2534 | } |
2534 | 2535 | ||