summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-02-06 22:03:25 +0100
committerReimar Döffinger <Reimar.Doeffinger@gmx.de>2012-02-06 22:08:45 +0100
commit787528b4a614898c52551dbedcb1f7ea1e5fe5ad (patch)
treeba3b95d9c7c7072b1c426c9944d3ad394f5dbf0d /libavformat
parent6833fe4342e82fad258376797f8333f96dd13d2d (diff)
Detect theora keyframes by content in Ogg demuxer.
A lot of files do not mark keyframes correctly via granule, so detect keyframe or not based on data and complain if it mismatches. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/oggdec.c17
1 files changed, 16 insertions, 1 deletions
diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c
index ab71b39556..e32ab69cf1 100644
--- a/libavformat/oggdec.c
+++ b/libavformat/oggdec.c
@@ -576,6 +576,18 @@ static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts)
return pts;
}
+static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize)
+{
+ struct ogg *ogg = s->priv_data;
+ struct ogg_stream *os = ogg->streams + idx;
+ if (psize && s->streams[idx]->codec->codec_id == CODEC_ID_THEORA) {
+ if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) {
+ av_log(s, AV_LOG_WARNING, "Broken file, keyframes not correctly marked.\n");
+ os->pflags ^= AV_PKT_FLAG_KEY;
+ }
+ }
+}
+
static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt)
{
struct ogg *ogg;
@@ -597,6 +609,7 @@ retry:
// pflags might not be set until after this
pts = ogg_calc_pts(s, idx, &dts);
+ ogg_validate_keyframe(s, idx, pstart, psize);
if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY))
goto retry;
@@ -639,13 +652,15 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index,
int64_t pts = AV_NOPTS_VALUE;
int64_t keypos = -1;
int i = -1;
+ int pstart, psize;
avio_seek(bc, *pos_arg, SEEK_SET);
ogg_reset(ogg);
- while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, NULL, NULL, pos_arg)) {
+ while (avio_tell(bc) < pos_limit && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) {
if (i == stream_index) {
struct ogg_stream *os = ogg->streams + stream_index;
pts = ogg_calc_pts(s, i, NULL);
+ ogg_validate_keyframe(s, i, pstart, psize);
if (os->pflags & AV_PKT_FLAG_KEY) {
keypos = *pos_arg;
} else if (os->keyframe_seek) {