summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2005-09-15 05:29:26 +0000
committerJens Arnold <amiconn@rockbox.org>2005-09-15 05:29:26 +0000
commitba966c17614fc2de2b443a82071415b194753aa4 (patch)
tree85b1af551200ab551b4e52a57008ca92ca454e29
parent0c1a2c7651c0727f2a5565e1302f50f64202a9f6 (diff)
downloadrockbox-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.h10
-rw-r--r--apps/plugin.h10
-rw-r--r--apps/plugins/vbrfix.c2
-rw-r--r--firmware/export/mp3data.h11
-rw-r--r--firmware/export/mpeg.h2
-rw-r--r--firmware/mp3data.c96
-rw-r--r--firmware/mpeg.c35
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 */
90enum codec_status { 90enum 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 */
100enum plugin_status { 100enum 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
64unsigned long find_next_frame(int fd, long *offset, long max_offset, unsigned long last_header); 64unsigned long find_next_frame(int fd, long *offset, long max_offset,
65 unsigned long last_header);
65unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset, 66unsigned long mem_find_next_frame(int startpos, long *offset, long max_offset,
66 unsigned long last_header); 67 unsigned long last_header);
67int get_mp3file_info(int fd, struct mp3info *info); 68int get_mp3file_info(int fd, struct mp3info *info);
68int count_mp3_frames(int fd, int startpos, int filesize, 69int count_mp3_frames(int fd, int startpos, int filesize,
69 void (*progressfunc)(int)); 70 void (*progressfunc)(int));
70int create_xing_header(int fd, int startpos, int filesize, 71int 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)
47void mpeg_init_recording(void); 47void 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
588static const char cooltext[] = "Rockbox - rocks your box"; 597static const char cooltext[] = "Rockbox - rocks your box";
589 598
590int 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, 601int 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 */
191unsigned long pause_start_time; /* Value of current_tick when pause was 191unsigned long pause_start_time; /* Value of current_tick when pause was
192 started */ 192 started */
193static unsigned long last_rec_time;
193static unsigned long num_rec_bytes; 194static unsigned long num_rec_bytes;
194static unsigned long last_rec_bytes; 195static unsigned long last_rec_bytes;
195static unsigned long frame_count_start; 196static 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