diff options
author | Michael Giacomelli <giac2000@hotmail.com> | 2010-01-02 20:54:55 +0000 |
---|---|---|
committer | Michael Giacomelli <giac2000@hotmail.com> | 2010-01-02 20:54:55 +0000 |
commit | 008c368c87873615ccbe8bc0b3482d93ae15779d (patch) | |
tree | c93f268e7dba1603a76eaddb7f7002e9291fbb7a /apps | |
parent | 420b4e4be905c0e0930ec74201e680defb091234 (diff) | |
download | rockbox-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
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/libm4a/demux.c | 20 | ||||
-rw-r--r-- | apps/codecs/libm4a/m4a.c | 7 | ||||
-rw-r--r-- | apps/codecs/libm4a/m4a.h | 1 | ||||
-rw-r--r-- | apps/metadata/mp4.c | 13 |
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 | ||
104 | void stream_skip(stream_t *stream, size_t skip) | 104 | void stream_skip(stream_t *stream, size_t skip) |
105 | { | 105 | { |
106 | stream->ci->advance_buffer(skip); | 106 | stream->ci->advance_buffer(skip); |
107 | } | ||
108 | |||
109 | void stream_seek(stream_t *stream, size_t offset) | ||
110 | { | ||
111 | stream->ci->seek_buffer(offset); | ||
107 | } | 112 | } |
108 | 113 | ||
109 | int stream_eof(stream_t *stream) | 114 | int 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); | |||
113 | uint8_t stream_read_uint8(stream_t *stream); | 113 | uint8_t stream_read_uint8(stream_t *stream); |
114 | 114 | ||
115 | void stream_skip(stream_t *stream, size_t skip); | 115 | void stream_skip(stream_t *stream, size_t skip); |
116 | void stream_seek(stream_t *stream, size_t offset); | ||
116 | 117 | ||
117 | int stream_eof(stream_t *stream); | 118 | int 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 | } |