forked from len0rd/rockbox
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
This commit is contained in:
parent
420b4e4be9
commit
008c368c87
4 changed files with 25 additions and 16 deletions
|
@ -746,7 +746,10 @@ int qtmovie_read(stream_t *file, demux_res_t *demux_res)
|
||||||
chunk_len = stream_read_uint32(qtmovie.stream);
|
chunk_len = stream_read_uint32(qtmovie.stream);
|
||||||
if (stream_eof(qtmovie.stream))
|
if (stream_eof(qtmovie.stream))
|
||||||
{
|
{
|
||||||
return 0;
|
if(qtmovie.res->mdat_offset == 0 || qtmovie.res->format == 0)
|
||||||
|
return 0;
|
||||||
|
stream_seek(qtmovie.stream, qtmovie.res->mdat_offset);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chunk_len == 1)
|
if (chunk_len == 1)
|
||||||
|
@ -767,20 +770,19 @@ int qtmovie_read(stream_t *file, demux_res_t *demux_res)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
/* once we hit mdat we stop reading and return.
|
|
||||||
* this is on the assumption that there is no furhter interesting
|
|
||||||
* stuff in the stream. if there is stuff will fail (:()).
|
|
||||||
* But we need the read pointer to be at the mdat stuff
|
|
||||||
* for the decoder. And we don't want to rely on fseek/ftell,
|
|
||||||
* as they may not always be avilable */
|
|
||||||
case MAKEFOURCC('m','d','a','t'):
|
case MAKEFOURCC('m','d','a','t'):
|
||||||
read_chunk_mdat(&qtmovie, chunk_len);
|
read_chunk_mdat(&qtmovie, chunk_len);
|
||||||
/* Keep track of start of stream in file - used for seeking */
|
/* Keep track of start of stream in file - used for seeking */
|
||||||
qtmovie.res->mdat_offset=stream_tell(qtmovie.stream);
|
qtmovie.res->mdat_offset=stream_tell(qtmovie.stream);
|
||||||
/* There can be empty mdats before the real one. If so, skip them */
|
/* There can be empty mdats before the real one. If so, skip them */
|
||||||
if (qtmovie.res->mdat_len > 0) {
|
if (qtmovie.res->mdat_len == 0)
|
||||||
|
break;
|
||||||
|
/* If we've already seen the format, assume there's nothing
|
||||||
|
interesting after the mdat chunk (the file is "streamable").
|
||||||
|
This avoids having to seek, which might cause rebuffering. */
|
||||||
|
if(qtmovie.res->format > 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
stream_skip(qtmovie.stream, chunk_len - 8);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* these following atoms can be skipped !!!! */
|
/* these following atoms can be skipped !!!! */
|
||||||
|
|
|
@ -103,7 +103,12 @@ uint8_t stream_read_uint8(stream_t *stream)
|
||||||
|
|
||||||
void stream_skip(stream_t *stream, size_t skip)
|
void stream_skip(stream_t *stream, size_t skip)
|
||||||
{
|
{
|
||||||
stream->ci->advance_buffer(skip);
|
stream->ci->advance_buffer(skip);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stream_seek(stream_t *stream, size_t offset)
|
||||||
|
{
|
||||||
|
stream->ci->seek_buffer(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_eof(stream_t *stream)
|
int stream_eof(stream_t *stream)
|
||||||
|
|
|
@ -113,6 +113,7 @@ int8_t stream_read_int8(stream_t *stream);
|
||||||
uint8_t stream_read_uint8(stream_t *stream);
|
uint8_t stream_read_uint8(stream_t *stream);
|
||||||
|
|
||||||
void stream_skip(stream_t *stream, size_t skip);
|
void stream_skip(stream_t *stream, size_t skip);
|
||||||
|
void stream_seek(stream_t *stream, size_t offset);
|
||||||
|
|
||||||
int stream_eof(stream_t *stream);
|
int stream_eof(stream_t *stream);
|
||||||
|
|
||||||
|
|
|
@ -548,6 +548,7 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
|
||||||
uint32_t type;
|
uint32_t type;
|
||||||
uint32_t handler = 0;
|
uint32_t handler = 0;
|
||||||
bool rc = true;
|
bool rc = true;
|
||||||
|
bool done = false;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
@ -681,6 +682,10 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
|
||||||
|
|
||||||
case MP4_mdat:
|
case MP4_mdat:
|
||||||
id3->filesize = size;
|
id3->filesize = size;
|
||||||
|
if(id3->samples > 0) {
|
||||||
|
/* We've already seen the moov chunk. */
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP4_chpl:
|
case MP4_chpl:
|
||||||
|
@ -708,15 +713,11 @@ static bool read_mp4_container(int fd, struct mp3entry* id3,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip final seek. */
|
/* Skip final seek. */
|
||||||
if (id3->filesize == 0)
|
if (!done)
|
||||||
{
|
{
|
||||||
lseek(fd, size, SEEK_CUR);
|
lseek(fd, size, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
} while (rc && (size_left > 0) && (errno == 0) && !done);
|
||||||
while (rc && (size_left > 0) && (errno == 0) && (id3->filesize == 0));
|
|
||||||
/* Break on non-zero filesize, since Rockbox currently doesn't support
|
|
||||||
* metadata after the mdat atom (which sets the filesize field).
|
|
||||||
*/
|
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue