Message ID | 1302616041-4750-1-git-send-email-martin@martin.st |
---|---|
State | Committed |
Commit | 578d6861a753eb0b9d277f7ec17d1502eb2bb35a |
Headers | show |
On 4/12/11 3:47 PM, Martin Storsjö wrote: > 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. Looks nicely, how to test it? lu
On Tue, 12 Apr 2011, Luca Barbato wrote: > On 4/12/11 3:47 PM, Martin Storsjö wrote: > > 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. > > Looks nicely, how to test it? Mostly by hacking it in different ways to test how it behaves. You can test these different scenarios: - Run normally with a file with an index, notice that the index is present and works (seek in the file with ffplay) - Make parse_keyframes_index return -1, notice that ffplay shows much less metadata than normally - Make it forcibly do the seek at the end of the function (even if aborting the parsing at an inconvenient place), notice that it still shows as much metadata as it did initially, since it succeeded to seek back - If seeking back to the start of the block did fail, the function will return < 0 and the rest of the packet won't be parsed => acceptable fallback for those corner cases IMO. // Martin
On 4/12/11 4:06 PM, Martin Storsjö wrote: > On Tue, 12 Apr 2011, Luca Barbato wrote: > >> On 4/12/11 3:47 PM, Martin Storsjö wrote: >>> 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. >> >> Looks nicely, how to test it? > > Mostly by hacking it in different ways to test how it behaves. > Thank you =) Seems good.
On Tue, 12 Apr 2011, Luca Barbato wrote: > On 4/12/11 4:06 PM, Martin Storsjö wrote: > > On Tue, 12 Apr 2011, Luca Barbato wrote: > > > > > On 4/12/11 3:47 PM, Martin Storsjö wrote: > > > > 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. > > > > > > Looks nicely, how to test it? > > > > Mostly by hacking it in different ways to test how it behaves. > > > > Thank you =) Seems good. Ok, queued then. // Martin
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 62d25c8..52ba14f 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(×); 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; }