Hacker News new | ask | show | jobs
by j1elo 1734 days ago
My all time question about FFmpeg is what are all those timestamp correction flags and synchronization options for:

* -fflags +genpts, +igndts, +ignidx

* -vsync

* -copyts

* -use_wallclock_as_timestamps 1

* And more that you find even when you thought you had seen all flags that might be related.

FFmpeg docs are a strange beast, they cover a lot of topics, but are extremely shallow in most of them, so the overall quality ends up being pretty poor. I mean it's like the kind of frowned upon code comments such as "ignidx ignores the index; genpts generates PTS". No surprises there... but no real explanation, either.

What I'd love is for a real, technical explanation of what are the consequences of each flag, and more importantly, the kind of scenarios where they would make a desirable difference.

Especially for the case of recording live video that comes from an unreliable connection (RTP through UDP) and storing it as-is (no transcoding whatsoever): what is the best, or recommended set of flags that FFmpeg authors would recommend? Given that packets can get lost, or timestamps can get garbled, UDP packets reordered in the network, or any combination of funny stuff.

For now I've sort of decided on using genpts+igndts and use_wallclock_as_timestamps, but all comes from intuition and simple tests, and not from actual evidence and guided by technical documentation of each flag.

1 comments

Think of ffmpeg as a universal translator. There are 100s of languages in use around the world, with their own syntax, vocabulary, writing system, formal and informal conventions ..etc.

A universal translator framework cannot provide a bespoke translation engine for all possible permutations of source and target language. Instead it provides a common engine which is meant to be suitable enough for the most common traits shared across languages.

When converting any two languages at random, there will be quirks of the language or errors/ambiguity in the source prose which the engine cannot hope to all automatically recognize and accommodate, so there are all these options that do one specific thing and allow users to modify a step of the translation process. The docs cannot go in detail because the downstream ramifications of the option can vary based on the exact properties of the source-target pair and the transformations requested of ffmpeg. Instead the docs will describe the exact change directly triggered by the option.

----

As for the specific options,

* -fflags +genpts, +igndts, +ignidx

All of these apply to inputs only.

genpts: if input packets have missing presentation timestamps, this option will assign the decoding timestamp as PTS, if present.

igndts will unset dts if packet's pts is set.

ignidx is only applied to a few formats. These provide a keyframe index, which ffmpeg uses to populate its internal KF index for the stream. This option makes ffmpeg ignore the supplied index.

* -vsync

The option is misnamed. It's better called fpsmode. Most commonly used to drop or duplicate frames to achieve a constant framerate stream.

* -copyts

FFmpeg will, by default, remove any starting offset to input timestamps or adjust timestamps if they overflow (roll over) or have a large gap. copyts stops all that and relays input timestamps. Basically used if one wishes to manually examine and adjust timestamps using setpts filter or setts bitstream filter.

* -use_wallclock_as_timestamps 1

Discards input timestamps and assign system clock time at time of handling packet as its pts.

Thank you; I understand what you mean with the translator metaphor. The project still needs to pick some very common usage scenarios and discuss them in depth (kind of "let's pick English and Spanish, two very commonly used languages, and talk about all quirks and translation techniques", in your own example).

You already provided better lines for some of the options than what their docs state, although I'd still miss a small commentary about some example instances where some of them would be useful.

For example: "igndts will unset dts if packet's pts is set"... OK but why would anyone want to do that? DTS is for Decoding, PTS is for Presentation, so wouldn't mixing them cause presentation issues?

As mentioned I'm interested in storing UDP RTP as-is, and for that I'm using "-fflags +genpts+igndts -use_wallclock_as_timestamps 1" because intuitively it makes sense to me that potentially broken incoming timestamps should be ignored and new ones written from scratch, but now that you mention it, maybe "+genpts" is doing nothing in this scenario?

> You already provided better lines for some of the options than what their docs state

I wrote the docs section you refer to :)

They are meant to be narrow and to the point, not didactic, not least because the codepath leading up to an option and following that option depend on internal evaluations and other options.

> why would anyone want to do that?

Because the input has weird or unreliable DTS. One would have to check code history to see why an option was initially added. Many of ffmpeg options are there to deal with edge cases or weird inputs.

> -fflags +genpts+igndts -use_wallclock_as_timestamps 1

In theory, igndts is unsetting wallclock dts set by the last option. genpts should have no effect, again due to the third option.

> They are meant to be narrow and to the point, not didactic

And that's understandable, but I believe some are crossing a thin line between "this is not the place where you should be learning about the technicalities of this option" and "this was added for some obscure and undocumented reason and nobody will really know for sure why it's useful".

> [why would anyone want to do use +igndts?] Because the input has weird or unreliable DTS.

> In theory, igndts is unsetting wallclock dts set by the last option. genpts should have no effect, again due to the third option.

These 2 are perfect examples of concise clarifications that would help users a lot

> I wrote the docs section you refer to :)

And I personally thank you for it; it's much better some documentation, even if IMHO a bit too short on details, than no docs at all... and writing proper docs is hard, I know it very well from the project I'm maintainer of! :)