mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-11 17:55:21 +00:00
Fix Theora-in-ogg keyframe handling.
To make seeking work correctly, we must write a new granule for each keyframe. Unfortunately we currently have no regression tests due to no included Theora encoder. A test based on -vcodec copy from a Theora FATE sample should probably be added. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
This commit is contained in:
parent
b223035511
commit
ff92549195
@ -131,6 +131,11 @@ static int ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule)
|
||||||
|
{
|
||||||
|
return oggstream->kfgshift && !(granule & ((1<<oggstream->kfgshift)-1));
|
||||||
|
}
|
||||||
|
|
||||||
static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule)
|
static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule)
|
||||||
{
|
{
|
||||||
if (oggstream->kfgshift)
|
if (oggstream->kfgshift)
|
||||||
@ -199,9 +204,15 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st,
|
|||||||
int i, segments, len, flush = 0;
|
int i, segments, len, flush = 0;
|
||||||
|
|
||||||
// Handles VFR by flushing page because this frame needs to have a timestamp
|
// Handles VFR by flushing page because this frame needs to have a timestamp
|
||||||
|
// For theora, keyframes also need to have a timestamp to correctly mark
|
||||||
|
// them as such, otherwise seeking will not work correctly at the very
|
||||||
|
// least with old libogg versions.
|
||||||
|
// Do not try to flush empty packets though, that will create broken files.
|
||||||
if (st->codec->codec_id == CODEC_ID_THEORA &&
|
if (st->codec->codec_id == CODEC_ID_THEORA &&
|
||||||
ogg_granule_to_timestamp(oggstream, granule) >
|
oggstream->page.size &&
|
||||||
ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1) {
|
(ogg_granule_to_timestamp(oggstream, granule) >
|
||||||
|
ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 ||
|
||||||
|
ogg_key_granule(oggstream, granule))) {
|
||||||
if (oggstream->page.granule != -1)
|
if (oggstream->page.granule != -1)
|
||||||
ogg_buffer_page(s, oggstream);
|
ogg_buffer_page(s, oggstream);
|
||||||
flush = 1;
|
flush = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user