aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2011-04-12 16:37:54 +0300
committerMartin Storsjö <martin@martin.st>2011-04-12 23:08:55 +0300
commit578d6861a753eb0b9d277f7ec17d1502eb2bb35a (patch)
treeebf5893e44d2d65355ee4d53cfc6f5452bc872de
parentf3e3f28e802a108120a1244744ddc1689d26be7a (diff)
downloadffmpeg-578d6861a753eb0b9d277f7ec17d1502eb2bb35a.tar.gz
flvdec: Allow parsing keyframes metadata without seeking in most cases
Stop the avio input at a point where amf_parse_object can continue parsing the end of the object seamlessly, when all data is available. If unsupported data is encountered within the keyframes object, try seeking to the start of the keyframes object - if the seek back was successful, the caller can continue parsing the rest of the AMF data. Signed-off-by: Martin Storsjö <martin@martin.st>
-rw-r--r--libavformat/flvdec.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 94159be3c4..e7ec0b107f 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -135,7 +135,7 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
char str_val[256];
int64_t *times = NULL;
int64_t *filepositions = NULL;
- int ret = 0;
+ int ret = AVERROR(ENOSYS);
int64_t initial_pos = avio_tell(ioc);
while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {
@@ -173,6 +173,12 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
num_val = av_int2dbl(avio_rb64(ioc));
current_array[i] = num_val;
}
+ if (times && filepositions) {
+ // All done, exiting at a position allowing amf_parse_object
+ // to finish parsing the object
+ ret = 0;
+ break;
+ }
}
if (timeslen == fileposlen)
@@ -184,7 +190,10 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream
finish:
av_freep(&times);
av_freep(&filepositions);
- avio_seek(ioc, initial_pos, SEEK_SET);
+ // If we got unexpected data, but successfully reset back to
+ // the start pos, the caller can continue parsing
+ if (ret < 0 && avio_seek(ioc, initial_pos, SEEK_SET) > 0)
+ return 0;
return ret;
}