summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Giacomelli <giac2000@hotmail.com>2010-01-02 20:54:55 +0000
committerMichael Giacomelli <giac2000@hotmail.com>2010-01-02 20:54:55 +0000
commit008c368c87873615ccbe8bc0b3482d93ae15779d (patch)
treec93f268e7dba1603a76eaddb7f7002e9291fbb7a
parent420b4e4be905c0e0930ec74201e680defb091234 (diff)
downloadrockbox-008c368c87873615ccbe8bc0b3482d93ae15779d.tar.gz
rockbox-008c368c87873615ccbe8bc0b3482d93ae15779d.zip
Commit first part of FS#10832 by Juliusz Chroboczek. Allows playback of unstreamable AAC/ALAC files by stepping through the file to find the index, potientially rebuffering. This is likely to impose a battery life hit on files which are unstreamable and not much smaller then the buffer, but should not impact streamable files at all.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24147 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/codecs/libm4a/demux.c20
-rw-r--r--apps/codecs/libm4a/m4a.c7
-rw-r--r--apps/codecs/libm4a/m4a.h1
-rw-r--r--apps/metadata/mp4.c13
4 files changed, 25 insertions, 16 deletions
diff --git a/apps/codecs/libm4a/demux.c b/apps/codecs/libm4a/demux.c
index 00fd3132aa..9f887b6b83 100644
--- a/apps/codecs/libm4a/demux.c
+++ b/apps/codecs/libm4a/demux.c
@@ -746,7 +746,10 @@ int qtmovie_read(stream_t *file, demux_res_t *demux_res)
746 chunk_len = stream_read_uint32(qtmovie.stream); 746 chunk_len = stream_read_uint32(qtmovie.stream);
747 if (stream_eof(qtmovie.stream)) 747 if (stream_eof(qtmovie.stream))
748 { 748 {
749 return 0; 749 if(qtmovie.res->mdat_offset == 0 || qtmovie.res->format == 0)
750 return 0;
751 stream_seek(qtmovie.stream, qtmovie.res->mdat_offset);
752 return 1;
750 } 753 }
751 754
752 if (chunk_len == 1) 755 if (chunk_len == 1)
@@ -767,20 +770,19 @@ int qtmovie_read(stream_t *file, demux_res_t *demux_res)
767 return 0; 770 return 0;
768 } 771 }
769 break; 772 break;
770 /* once we hit mdat we stop reading and return.
771 * this is on the assumption that there is no furhter interesting
772 * stuff in the stream. if there is stuff will fail (:()).
773 * But we need the read pointer to be at the mdat stuff
774 * for the decoder. And we don't want to rely on fseek/ftell,
775 * as they may not always be avilable */
776 case MAKEFOURCC('m','d','a','t'): 773 case MAKEFOURCC('m','d','a','t'):
777 read_chunk_mdat(&qtmovie, chunk_len); 774 read_chunk_mdat(&qtmovie, chunk_len);
778 /* Keep track of start of stream in file - used for seeking */ 775 /* Keep track of start of stream in file - used for seeking */
779 qtmovie.res->mdat_offset=stream_tell(qtmovie.stream); 776 qtmovie.res->mdat_offset=stream_tell(qtmovie.stream);
780 /* There can be empty mdats before the real one. If so, skip them */ 777 /* There can be empty mdats before the real one. If so, skip them */
781 if (qtmovie.res->mdat_len > 0) { 778 if (qtmovie.res->mdat_len == 0)
779 break;
780 /* If we've already seen the format, assume there's nothing
781 interesting after the mdat chunk (the file is "streamable").
782 This avoids having to seek, which might cause rebuffering. */
783 if(qtmovie.res->format > 0)
782 return 1; 784 return 1;
783 } 785 stream_skip(qtmovie.stream, chunk_len - 8);
784 break; 786 break;
785 787
786 /* these following atoms can be skipped !!!! */ 788 /* these following atoms can be skipped !!!! */
diff --git a/apps/codecs/libm4a/m4a.c b/apps/codecs/libm4a/m4a.c
index 92e619db35..42295e76ee 100644
--- a/apps/codecs/libm4a/m4a.c
+++ b/apps/codecs/libm4a/m4a.c
@@ -103,7 +103,12 @@ uint8_t stream_read_uint8(stream_t *stream)
103 103
104void stream_skip(stream_t *stream, size_t skip) 104void stream_skip(stream_t *stream, size_t skip)
105{ 105{
106 stream->ci->advance_buffer(skip); 106 stream->ci->advance_buffer(skip);
107}
108
109void stream_seek(stream_t *stream, size_t offset)
110{
111 stream->ci->seek_buffer(offset);
107} 112}
108 113
109int stream_eof(stream_t *stream) 114int stream_eof(stream_t *stream)
diff --git a/apps/codecs/libm4a/m4a.h b/apps/codecs/libm4a/m4a.h
index e2d4376d12..066f54b722 100644
--- a/apps/codecs/libm4a/m4a.h
+++ b/apps/codecs/libm4a/m4a.h
@@ -113,6 +113,7 @@ int8_t stream_read_int8(stream_t *stream);
113uint8_t stream_read_uint8(stream_t *stream); 113uint8_t stream_read_uint8(stream_t *stream);
114 114
115void stream_skip(stream_t *stream, size_t skip); 115void stream_skip(stream_t *stream, size_t skip);
116void stream_seek(stream_t *stream, size_t offset);
116 117
117int stream_eof(stream_t *stream); 118int stream_eof(stream_t *stream);
118 119
diff --git a/apps/metadata/mp4.c b/apps/metadata/mp4.c
index 44bc68eb5c..c5a525d9c5 100644
--- a/apps/metadata/mp4.c
+++ b/apps/metadata/mp4.c
@@ -548,6 +548,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
548 uint32_t type; 548 uint32_t type;
549 uint32_t handler = 0; 549 uint32_t handler = 0;
550 bool rc = true; 550 bool rc = true;
551 bool done = false;
551 552
552 do 553 do
553 { 554 {
@@ -681,6 +682,10 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
681 682
682 case MP4_mdat: 683 case MP4_mdat:
683 id3->filesize = size; 684 id3->filesize = size;
685 if(id3->samples > 0) {
686 /* We've already seen the moov chunk. */
687 done = true;
688 }
684 break; 689 break;
685 690
686 case MP4_chpl: 691 case MP4_chpl:
@@ -708,15 +713,11 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
708 } 713 }
709 714
710 /* Skip final seek. */ 715 /* Skip final seek. */
711 if (id3->filesize == 0) 716 if (!done)
712 { 717 {
713 lseek(fd, size, SEEK_CUR); 718 lseek(fd, size, SEEK_CUR);
714 } 719 }
715 } 720 } while (rc && (size_left > 0) && (errno == 0) && !done);
716 while (rc && (size_left > 0) && (errno == 0) && (id3->filesize == 0));
717 /* Break on non-zero filesize, since Rockbox currently doesn't support
718 * metadata after the mdat atom (which sets the filesize field).
719 */
720 721
721 return rc; 722 return rc;
722} 723}