Uoti Urpala wrote:
Attached patch fixes an assertion failure that's fairly easy to trigger
with corrupt files.
The asf seek regression triggered by the preroll changes (caused by
binary seek fallback) is still there, anyone going to fix that?
yes, the preroll changes now expose that asf bug.
Disabling the utils.c fallback for asf should be enough. I'm not posting
a patch for that one as the method of disabling it is a matter of
opinion/style; I neither care what method libavformat uses for that nor
want to discuss it.
attached are 2 patches that both solve the issue, one makes ASF cleanup
after util.c falls back to binary search, the other one introduces a new
flag that prevents util.c from doing so.
comment welcome
>From 51e6aea5998f1babf86a1bd68c200da85addd88f Mon Sep 17 00:00:00 2001
From: Vladimir Pantelic <[email protected]>
Date: Tue, 10 May 2011 14:23:16 +0200
Subject: [PATCH] reset asf decoder after lavf generic binary search
binary search uses asf_read_pts() which changes the internal
asf stream state, so remember that we need to reset the
asf state when asf_read_packet is called the next time
---
libavformat/asfdec.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 77c8449..3a1fbda 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -67,6 +67,7 @@ typedef struct {
int64_t packet_pos;
int stream_index;
+ int needs_reset;
ASFStream* asf_st; ///< currently decoded stream
} ASFContext;
@@ -1085,10 +1086,17 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk
return 0;
}
+static void asf_reset_header(AVFormatContext *s);
+
static int asf_read_packet(AVFormatContext *s, AVPacket *pkt)
{
ASFContext *asf = s->priv_data;
+ if(asf->needs_reset) {
+ asf->needs_reset = 0;
+ asf_reset_header(s);
+ }
+
for (;;) {
int ret;
@@ -1149,6 +1157,7 @@ static int asf_read_close(AVFormatContext *s)
static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos, int64_t pos_limit)
{
+ ASFContext *asf = s->priv_data;
AVPacket pkt1, *pkt = &pkt1;
ASFStream *asf_st;
int64_t pts;
@@ -1192,6 +1201,7 @@ static int64_t asf_read_pts(AVFormatContext *s, int stream_index, int64_t *ppos,
}
}
+ asf->needs_reset = 1;
*ppos= pos;
//printf("found keyframe at %"PRId64" stream %d stamp:%"PRId64"\n", *ppos, stream_index, pts);
--
1.6.0.2
>From 4e2c40ecd0821b0dd3247ea8bb6eeb1af0204f80 Mon Sep 17 00:00:00 2001
From: Vladimir Pantelic <[email protected]>
Date: Tue, 10 May 2011 14:54:21 +0200
Subject: [PATCH] fix asf demuxer to not fall back to binary search
asf_read_seek() inside the asf demuxer already does the
right thing, it tries the index and if that fails it uses
binary search. If binary search is called from outside of asfdec.c
it will fail because the asf code cannot clean up after itself.
Therefore introduce AVFMT_NOBINSEARCH that prevents the seek
code to fallback to binary search.
---
libavformat/asfdec.c | 1 +
libavformat/avformat.h | 1 +
libavformat/utils.c | 2 +-
3 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c
index 77c8449..6feeed9 100644
--- a/libavformat/asfdec.c
+++ b/libavformat/asfdec.c
@@ -1298,4 +1298,5 @@ AVInputFormat ff_asf_demuxer = {
asf_read_close,
asf_read_seek,
asf_read_pts,
+ .flags = AVFMT_NOBINSEARCH,
};
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 7327562..e84a87b 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -258,6 +258,7 @@ typedef struct AVFormatParameters {
#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */
#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */
#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */
+#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
typedef struct AVOutputFormat {
const char *name;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 7959102..c018fff 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1713,7 +1713,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f
return 0;
}
- if(s->iformat->read_timestamp)
+ if(s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH))
return av_seek_frame_binary(s, stream_index, timestamp, flags);
else
return av_seek_frame_generic(s, stream_index, timestamp, flags);
--
1.6.0.2
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel