lavf/oggparsevorbis: rework timestamp offset and end trimming

Replace the first-page packet scan with a direct use of the first
packet's duration as the timestamp offset (the Vorbis I spec
guarantees it produces no PCM output).

Track last_page_granule to correctly anchor EOS trimming regardless
of any initial granule offset. Track bos_pos to reinitialize parser
state at stream boundaries without resetting at page boundaries.

Restore the granule=0 workaround from ticket #3710 and handle
chained streams by clearing bos_pos when new headers are collected.

Vorbis I spec: https://xiph.org/vorbis/doc/Vorbis_I_spec.html
This commit is contained in:
Romain Beauxis
2026-05-07 19:13:45 -05:00
committed by Romain Beauxis
parent de038122a3
commit 63b7e4cefa
15 changed files with 263 additions and 263 deletions

View File

@@ -572,6 +572,9 @@ static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize,
ogg->curidx = idx;
os->incomplete = 0;
// the packet started at the first segment of the page it completes on
os->page_start = segp == 0;
if (os->header) {
if ((ret = os->codec->header(s, idx)) < 0) {
av_log(s, AV_LOG_ERROR, "Header processing failed: %s\n", av_err2str(ret));

View File

@@ -85,6 +85,7 @@ struct ogg_stream {
int nsegs, segp;
uint8_t segments[255];
int incomplete; ///< whether we're expecting a continuation in the next page
int page_start; ///< current packet is the first one starting in the page
int page_end; ///< current packet is the last one completed in the page
int keyframe_seek;
int got_start;

View File

@@ -213,14 +213,16 @@ struct oggvorbis_private {
unsigned int len[3];
unsigned char *packet[3];
AVVorbisParseContext *vp;
int64_t final_pts;
int final_duration;
uint8_t *header;
int header_size;
uint8_t *comment;
int comment_size;
uint8_t *setup;
int setup_size;
int64_t bos_page_pos;
int ts_offset;
int64_t last_page_granule;
int eos_page_duration;
};
static int fixup_vorbis_headers(AVFormatContext *as,
@@ -230,7 +232,9 @@ static int fixup_vorbis_headers(AVFormatContext *as,
int i, offset, len, err;
int buf_len;
unsigned char *ptr;
uint64_t total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
uint64_t total_len;
total_len = (uint64_t)priv->len[0] + priv->len[1] + priv->len[2];
if (total_len + total_len / 255 + 64 > INT_MAX)
return AVERROR_INVALIDDATA;
@@ -379,13 +383,14 @@ static int vorbis_header(AVFormatContext *s, int idx)
struct oggvorbis_private *priv;
int pkt_type = os->buf[os->pstart];
if (!os->private) {
if (!os->private)
os->private = av_mallocz(sizeof(struct oggvorbis_private));
if (!os->private)
return AVERROR(ENOMEM);
}
if (!os->private)
return AVERROR(ENOMEM);
priv = os->private;
priv->bos_page_pos = -1;
if (!(pkt_type & 1))
return priv->vp ? 0 : AVERROR_INVALIDDATA;
@@ -456,136 +461,124 @@ static int vorbis_packet(AVFormatContext *s, int idx)
struct ogg_stream *os = ogg->streams + idx;
struct oggvorbis_private *priv = os->private;
int duration, flags = 0;
int skip_packet = 0;
int bos, skip_packet = 0;
int ret, new_extradata_size;
PutByteContext pb;
if (os->psize == 0)
return AVERROR_INVALIDDATA;
if (!priv->vp)
return AVERROR_INVALIDDATA;
/* first packet handling
* here we parse the duration of each packet in the first page and compare
* the total duration to the page granule to find the encoder delay and
* set the first timestamp */
if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS) && (int64_t)os->granule>=0) {
int seg, d;
uint8_t *last_pkt = os->buf + os->pstart;
uint8_t *next_pkt = last_pkt;
/* Track the page holding the first data packet by its file position,
* which stays stable when probing rescans the start of the stream. */
if (priv->bos_page_pos < 0)
priv->bos_page_pos = os->page_pos;
bos = os->page_start && os->page_pos == priv->bos_page_pos;
if (bos) {
av_vorbis_parse_reset(priv->vp);
duration = 0;
seg = os->segp;
d = av_vorbis_parse_frame_flags(priv->vp, last_pkt, 1, &flags);
if (d < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
} else if (flags & VORBIS_FLAG_COMMENT) {
vorbis_update_metadata(s, idx);
flags = 0;
}
duration += d;
last_pkt = next_pkt = next_pkt + os->psize;
for (; seg < os->nsegs; seg++) {
if (os->segments[seg] < 255) {
int d = av_vorbis_parse_frame_flags(priv->vp, last_pkt, 1, &flags);
if (d < 0) {
duration = os->granule;
break;
} else if (flags & VORBIS_FLAG_COMMENT) {
vorbis_update_metadata(s, idx);
flags = 0;
}
duration += d;
last_pkt = next_pkt + os->segments[seg];
}
next_pkt += os->segments[seg];
}
os->lastpts =
os->lastdts = os->granule - duration;
if (!os->granule && duration) //hack to deal with broken files (Ticket3710)
os->lastpts = os->lastdts = AV_NOPTS_VALUE;
if (s->streams[idx]->start_time == AV_NOPTS_VALUE) {
s->streams[idx]->start_time = FFMAX(os->lastpts, 0);
if (s->streams[idx]->duration != AV_NOPTS_VALUE)
s->streams[idx]->duration -= s->streams[idx]->start_time;
}
priv->final_pts = AV_NOPTS_VALUE;
av_vorbis_parse_reset(priv->vp);
priv->last_page_granule = 0;
}
/* parse packet duration */
if (os->psize > 0) {
duration = av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
if (duration < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
}
duration = av_vorbis_parse_frame_flags(priv->vp, os->buf + os->pstart, 1, &flags);
if (duration < 0) {
os->pflags |= AV_PKT_FLAG_CORRUPT;
return 0;
}
os->pduration = duration;
if (flags & VORBIS_FLAG_HEADER) {
ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
if (ret < 0)
return ret;
/* Save ts_offset from the very first chained stream to account for the
* first priming packet. This only shifts timestamps; the Vorbis decoder
* discards the leading priming samples itself, so we do not set
* codecpar->initial_padding. */
if (!priv->ts_offset)
priv->ts_offset = os->pduration;
ret = av_reallocp(&priv->header, os->psize);
if (ret < 0)
return ret;
memcpy(priv->header, os->buf + os->pstart, os->psize);
priv->header_size = os->psize;
skip_packet = 1;
}
if (flags & VORBIS_FLAG_COMMENT) {
ret = vorbis_update_metadata(s, idx);
if (ret < 0)
return ret;
ret = av_reallocp(&priv->comment, os->psize);
if (ret < 0)
return ret;
memcpy(priv->comment, os->buf + os->pstart, os->psize);
priv->comment_size = os->psize;
flags = 0;
skip_packet = 1;
}
if (flags & VORBIS_FLAG_SETUP) {
ret = av_reallocp(&priv->setup, os->psize);
if (ret < 0)
return ret;
memcpy(priv->setup, os->buf + os->pstart, os->psize);
priv->setup_size = os->psize;
skip_packet = 1;
}
os->pduration = duration;
/* Initial position shift to account for encoder delay. */
if (bos) {
if (os->lastpts != AV_NOPTS_VALUE)
os->lastpts -= priv->ts_offset;
if (os->lastdts != AV_NOPTS_VALUE)
os->lastdts -= priv->ts_offset;
}
/* final packet handling
* here we save the pts of the first packet in the final page, sum up all
* packet durations in the final page except for the last one, and compare
* to the page granule to find the duration of the final packet */
/* Broken files may have granule=0 on pages that contain audio data.
* In that case timestamps are unreliable, so discard them.
* See https://trac.ffmpeg.org/ticket/3710 */
if (!os->granule && os->pduration)
os->lastpts = os->lastdts = AV_NOPTS_VALUE;
if (os->flags & OGG_FLAG_EOS) {
if (os->lastpts != AV_NOPTS_VALUE) {
priv->final_pts = os->lastpts;
priv->final_duration = 0;
}
if (os->segp == os->nsegs) {
int64_t skip = priv->final_pts + priv->final_duration + os->pduration - os->granule;
/* Reset at the start of the EOS page to avoid carrying over stale
* duration from a previously processed EOS page, as can happen on
* short or chained ogg streams and when probing rescans the page.
* os->segp has already been advanced past the current packet by
* ogg_packet(), so rely on os->page_start to detect the page start. */
if (os->page_start)
priv->eos_page_duration = 0;
if (os->segp != os->nsegs) {
priv->eos_page_duration += os->pduration;
} else {
int64_t skip = priv->eos_page_duration + os->pduration -
(os->granule - priv->last_page_granule);
if (skip > 0)
os->end_trimming = skip;
os->pduration = os->granule - priv->final_pts - priv->final_duration;
}
priv->final_duration += os->pduration;
} else
priv->last_page_granule = os->granule;
/* Handle in-stream header packets from chained streams. The packet is
* skipped; the headers are buffered and attached as extradata to the
* first data packet that follows. */
if (flags & VORBIS_FLAG_HEADER) {
ret = vorbis_parse_header(s, s->streams[idx], os->buf + os->pstart, os->psize);
if (ret < 0)
return ret;
ret = av_reallocp(&priv->header, os->psize);
if (ret < 0)
return ret;
memcpy(priv->header, os->buf + os->pstart, os->psize);
priv->header_size = os->psize;
skip_packet = 1;
}
if (flags & VORBIS_FLAG_COMMENT) {
ret = vorbis_update_metadata(s, idx);
if (ret < 0)
return ret;
ret = av_reallocp(&priv->comment, os->psize);
if (ret < 0)
return ret;
memcpy(priv->comment, os->buf + os->pstart, os->psize);
priv->comment_size = os->psize;
flags = 0;
skip_packet = 1;
}
if (flags & VORBIS_FLAG_SETUP) {
ret = av_reallocp(&priv->setup, os->psize);
if (ret < 0)
return ret;
memcpy(priv->setup, os->buf + os->pstart, os->psize);
priv->setup_size = os->psize;
skip_packet = 1;
}
/* All three headers for the new chained stream have been collected;
* pack them into new extradata to be attached to the next data packet. */
if (priv->header && priv->comment && priv->setup) {
new_extradata_size = priv->header_size + priv->comment_size + priv->setup_size + 6;
@@ -615,6 +608,10 @@ static int vorbis_packet(AVFormatContext *s, int idx)
av_log(s, AV_LOG_ERROR, "Failed to re-initialize Vorbis parser\n");
return AVERROR_INVALIDDATA;
}
/* Reset bos_page_pos so the next packet will initialize it for the
* new chained stream. */
priv->bos_page_pos = -1;
}
return skip_packet;

View File

@@ -1 +1 @@
ae878bdaec23f36a63d142165fe57f49
4498ed5370e5a15904bad5d5a716d0b9

View File

@@ -1 +1 @@
ffe8a674bdf38e4f650f91963debc654
7a0febe8623a2838ac5878f58159c74f

View File

@@ -1,49 +1,48 @@
a1d752fbef195f967e80f86f31877929 *tests/data/fate/mov-mp4-chapters.mp4
111248 tests/data/fate/mov-mp4-chapters.mp4
d3560e9ac82b30c4f59f357b94124a71 *tests/data/fate/mov-mp4-chapters.mp4
111288 tests/data/fate/mov-mp4-chapters.mp4
#extradata 0: 3469, 0xc6769ddc
#tb 0: 1/44100
#media_type 0: audio
#codec_id 0: vorbis
#sample_rate 0: 44100
#channel_layout_name 0: mono
0, -256, -256, 256, 28, 0xefcf103e, F=0x5
0, 0, 0, 1152, 198, 0xfbbe5eb5
0, 1152, 1152, 2944, 198, 0xabd95c6c
0, 4096, 4096, 256, 41, 0x954b12a5
0, 4352, 4352, 256, 41, 0xbccd1463
0, 0, 0, 256, 28, 0xefcf103e
0, 256, 256, 1152, 198, 0xfbbe5eb5
0, 1408, 1408, 2048, 198, 0xabd95c6c
0, 3456, 3456, 1152, 41, 0x954b12a5
[CHAPTER]
id=0
time_base=1/44100
start=0
start_time=0.000000
end=220500
end_time=5.000000
end=220765
end_time=5.006009
TAG:title=start
[/CHAPTER]
[CHAPTER]
id=1
time_base=1/44100
start=220500
start_time=5.000000
end=463050
end_time=10.500000
start=220765
start_time=5.006009
end=463315
end_time=10.506009
TAG:title=Five Seconds
[/CHAPTER]
[CHAPTER]
id=2
time_base=1/44100
start=463050
start_time=10.500000
end=661500
end_time=15.000000
start=463315
start_time=10.506009
end=661765
end_time=15.006009
TAG:title=Ten point 5 seconds
[/CHAPTER]
[CHAPTER]
id=3
time_base=1/44100
start=661500
start_time=15.000000
end=875341
end_time=19.849002
start=661765
start_time=15.006009
end=875606
end_time=19.855011
TAG:title=15 sec - over soon
[/CHAPTER]

View File

@@ -1,6 +1,6 @@
[PACKET]
pts=-704
dts=-704
pts=-256
dts=-256
duration=128
flags=K__
TAG:encoder=Lavc52.32.0
@@ -9,14 +9,14 @@ side_data_type=Strings Metadata
[/SIDE_DATA]
[/PACKET]
[PACKET]
pts=-576
dts=-576
pts=-128
dts=-128
duration=128
flags=K__
[/PACKET]
[PACKET]
pts=-448
dts=-448
pts=0
dts=0
duration=576
flags=K__
[/PACKET]
@@ -92,7 +92,7 @@ nb_streams=2
nb_programs=0
nb_stream_groups=0
format_name=ogg
start_time=0.000000
start_time=-0.005805
duration=1.011519
size=59943
bit_rate=474083

View File

@@ -1,14 +1,14 @@
Stream ID: 0, codec name: vorbis, metadata: encoder=Lavc61.19.100 libvorbis:title=First Stream
Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, packet PTS: -128, packet DTS: -128
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libvorbis:title=First Stream
Stream ID: 0, packet PTS: 128, packet DTS: 128
Stream ID: 0, frame PTS: 128, metadata: N/A
Stream ID: 0, packet PTS: 704, packet DTS: 704
Stream ID: 0, frame PTS: 704, metadata: N/A
Stream ID: 0, packet PTS: 1323, packet DTS: 1323
Stream ID: 0, packet PTS: 0, packet DTS: 0
Stream ID: 0, frame PTS: 0, metadata: N/A
Stream ID: 0, packet PTS: 576, packet DTS: 576
Stream ID: 0, frame PTS: 576, metadata: N/A
Stream ID: 0, packet PTS: 1600, packet DTS: 1600
Stream ID: 0, new metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
Stream ID: 0, frame PTS: 1323, metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
Stream ID: 0, packet PTS: 1451, packet DTS: 1451
Stream ID: 0, frame PTS: 1451, metadata: N/A
Stream ID: 0, packet PTS: 2027, packet DTS: 2027
Stream ID: 0, frame PTS: 2027, metadata: N/A
Stream ID: 0, frame PTS: 1600, metadata: encoder=Lavc61.19.100 libvorbis:title=Second Stream
Stream ID: 0, packet PTS: 1728, packet DTS: 1728
Stream ID: 0, frame PTS: 1728, metadata: N/A
Stream ID: 0, packet PTS: 2304, packet DTS: 2304
Stream ID: 0, frame PTS: 2304, metadata: N/A

View File

@@ -1,10 +1,10 @@
[PACKET]
codec_type=audio
stream_index=0
pts=0
pts_time=0.000000
dts=0
dts_time=0.000000
pts=-128
pts_time=-0.002902
dts=-128
dts_time=-0.002902
duration=128
duration_time=0.002902
size=28
@@ -20,10 +20,10 @@ side_data_type=Strings Metadata
[PACKET]
codec_type=audio
stream_index=0
pts=128
pts_time=0.002902
dts=128
dts_time=0.002902
pts=0
pts_time=0.000000
dts=0
dts_time=0.000000
duration=576
duration_time=0.013061
size=59
@@ -34,12 +34,12 @@ data_hash=CRC32:3a566e87
[PACKET]
codec_type=audio
stream_index=0
pts=704
pts_time=0.015964
dts=704
dts_time=0.015964
duration=619
duration_time=0.014036
pts=576
pts_time=0.013061
dts=576
dts_time=0.013061
duration=1024
duration_time=0.023220
size=85
pos=3373
flags=K__
@@ -55,10 +55,10 @@ discard_reason=0
[PACKET]
codec_type=audio
stream_index=0
pts=1323
pts_time=0.030000
dts=1323
dts_time=0.030000
pts=1600
pts_time=0.036281
dts=1600
dts_time=0.036281
duration=128
duration_time=0.002902
size=28
@@ -77,10 +77,10 @@ side_data_type=New Extradata
[PACKET]
codec_type=audio
stream_index=0
pts=1451
pts_time=0.032902
dts=1451
dts_time=0.032902
pts=1728
pts_time=0.039184
dts=1728
dts_time=0.039184
duration=576
duration_time=0.013061
size=59
@@ -91,12 +91,12 @@ data_hash=CRC32:3a566e87
[PACKET]
codec_type=audio
stream_index=0
pts=2027
pts_time=0.045964
dts=2027
dts_time=0.045964
duration=619
duration_time=0.014036
pts=2304
pts_time=0.052245
dts=2304
dts_time=0.052245
duration=1024
duration_time=0.023220
size=85
pos=6949
flags=K__
@@ -140,9 +140,9 @@ nb_streams=1
nb_programs=0
nb_stream_groups=0
format_name=ogg
start_time=0.000000
duration=0.030000
start_time=-0.002902
duration=0.032902
size=7151
bit_rate=1906933
bit_rate=1738739
probe_score=100
[/FORMAT]

View File

@@ -1,8 +1,8 @@
[PACKET]
pts=0
pts_time=0.000000
dts=0
dts_time=0.000000
pts=-128
pts_time=-0.002902
dts=-128
dts_time=-0.002902
duration=128
duration_time=0.002902
flags=K__
@@ -11,37 +11,37 @@ side_data_type=Strings Metadata
[/SIDE_DATA]
[/PACKET]
[PACKET]
pts=128
pts_time=0.002902
dts=128
dts_time=0.002902
pts=0
pts_time=0.000000
dts=0
dts_time=0.000000
duration=576
duration_time=0.013061
flags=K__
[/PACKET]
[PACKET]
pts=704
pts_time=0.015964
dts=704
dts_time=0.015964
pts=576
pts_time=0.013061
dts=576
dts_time=0.013061
duration=1024
duration_time=0.023220
flags=K__
[/PACKET]
[PACKET]
pts=1728
pts_time=0.039184
dts=1728
dts_time=0.039184
pts=1600
pts_time=0.036281
dts=1600
dts_time=0.036281
duration=1024
duration_time=0.023220
flags=K__
[/PACKET]
[PACKET]
pts=2752
pts_time=0.062404
dts=2752
dts_time=0.062404
pts=2624
pts_time=0.059501
dts=2624
dts_time=0.059501
duration=1024
duration_time=0.023220
flags=K__
@@ -56,7 +56,7 @@ nb_streams=1
nb_programs=0
nb_stream_groups=0
format_name=ogg
start_time=0.000000
duration=1.000000
start_time=-0.002902
duration=1.002902
probe_score=100
[/FORMAT]

View File

@@ -56,7 +56,7 @@ nb_streams=1
nb_programs=0
nb_stream_groups=0
format_name=ogg
start_time=0.000000
duration=30.000000
start_time=-0.002902
duration=30.002902
probe_score=100
[/FORMAT]

View File

@@ -72,7 +72,7 @@
72256-72256=0
73280-73280=0
74304-74304=0
75328-75776=-448
75328-75328=0
75904-75904=0
76032-76032=0
76160-76160=0
@@ -106,21 +106,21 @@
79744-79744=0
79872-79872=0
80000-80000=0
80576-81024=-448
80576-80576=0
81152-81152=0
81280-81280=0
81408-81408=0
81984-81984=0
83008-83008=0
84032-84032=0
85056-85504=-448
85056-85056=0
85632-85632=0
85760-85760=0
85888-85888=0
86016-86016=0
86144-86144=0
86272-86272=0
86848-87296=-448
86848-86848=0
87424-87424=0
87552-87552=0
87680-87680=0

View File

@@ -1,31 +1,31 @@
[PACKET]
pts=44608
dts=44608
duration=1024
pts=89536
dts=89536
duration=128
flags=K__
[/PACKET]
[PACKET]
pts=45632
dts=45632
duration=1024
pts=89664
dts=89664
duration=128
flags=K__
[/PACKET]
[PACKET]
pts=46656
dts=46656
duration=1024
pts=89792
dts=89792
duration=128
flags=K__
[/PACKET]
[PACKET]
pts=47680
dts=47680
duration=1024
pts=89920
dts=89920
duration=128
flags=K__
[/PACKET]
[PACKET]
pts=48704
dts=48704
duration=1024
pts=90048
dts=90048
duration=128
flags=K__
[/PACKET]
[STREAM]
@@ -64,9 +64,9 @@ nb_streams=1
nb_programs=0
nb_stream_groups=0
format_name=ogg
start_time=0.000000
duration=3.033107
start_time=-0.002902
duration=3.036009
size=40295
bit_rate=106280
bit_rate=106178
probe_score=100
[/FORMAT]

View File

@@ -1,5 +1,5 @@
d3146d0817d9f3471b4bda4fa61cc090 *tests/data/fate/webm-dash-chapters.webm
111153 tests/data/fate/webm-dash-chapters.webm
b72cac0fe6048d70685a43965c2c87c6 *tests/data/fate/webm-dash-chapters.webm
111155 tests/data/fate/webm-dash-chapters.webm
#extradata 0: 3469, 0xc6769ddc
#tb 0: 1/1000
#media_type 0: audio
@@ -9,65 +9,65 @@ d3146d0817d9f3471b4bda4fa61cc090 *tests/data/fate/webm-dash-chapters.webm
0, 0, 0, 5, 28, 0xefcf103e
0, 6, 6, 26, 198, 0xfbbe5eb5
0, 32, 32, 46, 198, 0xabd95c6c
0, 99, 99, 26, 41, 0x954b12a5
0, 105, 105, 5, 41, 0xbccd1463
0, 78, 78, 26, 41, 0x954b12a5
0, 104, 104, 5, 41, 0xbccd1463
0, 110, 110, 5, 44, 0x4fa218a1
0, 116, 116, 5, 43, 0xf87716d4
0, 122, 122, 5, 32, 0x0fdc1057
0, 128, 128, 5, 67, 0xd5352244
0, 134, 134, 5, 68, 0x36e91faf
0, 140, 140, 5, 57, 0xe6f51928
0, 139, 139, 5, 57, 0xe6f51928
0, 145, 145, 5, 49, 0x3bb416e1
0, 151, 151, 5, 54, 0x678f1777
0, 157, 157, 5, 57, 0x56601ef3
0, 163, 163, 5, 52, 0xc0fe1a12
0, 169, 169, 26, 236, 0xfe396f02
0, 195, 195, 46, 208, 0x018e62d3
0, 168, 168, 26, 236, 0xfe396f02
0, 194, 194, 46, 208, 0x018e62d3
0, 241, 241, 46, 223, 0x9fa76917
0, 308, 308, 26, 46, 0xd8c314f9
0, 314, 314, 5, 46, 0x199018bc
0, 287, 287, 26, 46, 0xd8c314f9
0, 313, 313, 5, 46, 0x199018bc
0, 319, 319, 5, 46, 0xbe8314cd
0, 325, 325, 5, 45, 0xe0ad1622
0, 331, 331, 5, 43, 0xe52a1659
0, 337, 337, 5, 58, 0xd5e01f9c
0, 343, 343, 5, 67, 0x5bbc2201
0, 342, 342, 5, 67, 0x5bbc2201
0, 348, 348, 26, 226, 0x04887569
0, 375, 375, 46, 217, 0x4b6564ab
0, 374, 374, 46, 217, 0x4b6564ab
0, 421, 421, 46, 211, 0xb7e868da
0, 467, 467, 46, 198, 0x7bf65d8a
[CHAPTER]
id=1
time_base=1/1000000000
start=0
start_time=0.000000
end=5000000000
end_time=5.000000
start=6000000
start_time=0.006000
end=5006000000
end_time=5.006000
TAG:title=start
[/CHAPTER]
[CHAPTER]
id=2
time_base=1/1000000000
start=5000000000
start_time=5.000000
end=10500000000
end_time=10.500000
start=5006000000
start_time=5.006000
end=10506000000
end_time=10.506000
TAG:title=Five Seconds
[/CHAPTER]
[CHAPTER]
id=3
time_base=1/1000000000
start=10500000000
start_time=10.500000
end=15000000000
end_time=15.000000
start=10506000000
start_time=10.506000
end=15006000000
end_time=15.006000
TAG:title=Ten point 5 seconds
[/CHAPTER]
[CHAPTER]
id=4
time_base=1/1000000000
start=15000000000
start_time=15.000000
end=19849000000
end_time=19.849000
start=15006000000
start_time=15.006000
end=19855000000
end_time=19.855000
TAG:title=15 sec - over soon
[/CHAPTER]

View File

@@ -1,3 +1,3 @@
20f1e9b1714513a0ba85ca636e818784 *tests/data/lavf-fate/lavf.vp8.ogg
95009 tests/data/lavf-fate/lavf.vp8.ogg
tests/data/lavf-fate/lavf.vp8.ogg CRC=0xa5857a66
tests/data/lavf-fate/lavf.vp8.ogg CRC=0xfb8d7a66