Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Frame timestamps when transcoding must be set to None #281

Closed
MiguelFRomeroR opened this issue Jan 31, 2018 · 6 comments
Closed

Frame timestamps when transcoding must be set to None #281

MiguelFRomeroR opened this issue Jan 31, 2018 · 6 comments

Comments

@MiguelFRomeroR
Copy link

MiguelFRomeroR commented Jan 31, 2018

I was able to replicate this issue with the following example:

from fractions import Fraction
import av
import logging
logging.basicConfig()

input_container = av.open('input.mp4')
video_stream = input_container.streams.video[0]

output_container = av.open('output.mp4', mode='w')
stream = output_container.add_stream('libx264', rate=Fraction(30000,1001))
stream.width = 512
stream.height = 512
stream.pix_fmt = 'yuv420p'

for frame in input_container.decode(video=0):
	packet = stream.encode(frame)
	output_container.mux(packet)

packet = stream.encode()
output_container.mux(packet)

output_container.close()

The fps of the file 'output.mp4' is 0.06 fps, and therefore the duration of the video is really high. I tried lots of things (changing the rate, time_base, bit_rate, max_bit_rate, ... of the OutputContainer and the CodecContext), until I found out that to solve it, you simply have to set frame.pts and frame.time_base to None, to allow the encoder to generate it's own timestamps.

from fractions import Fraction
import av
import logging
logging.basicConfig()

input_container = av.open('input.mp4')
video_stream = input_container.streams.video[0]

output_container = av.open('output.mp4', mode='w')
stream = output_container.add_stream('libx264', rate=Fraction(30000,1001))
stream.width = 512
stream.height = 512
stream.pix_fmt = 'yuv420p'

for frame in input_container.decode(video=0):
	frame.pts = None
	frame.time_base = None
	packet = stream.encode(frame)
	output_container.mux(packet)

packet = stream.encode()
output_container.mux(packet)

output_container.close()

This error is very subtle but I wanted to remark it, because someone else may have a related issue.

I'm using the latest (31-01-2018) ffmpeg version N-89907-g293f24b, the PyAV version built from source under Ubuntu 16.04.

@mikeboers
Copy link
Member

This should land in the documentation, as PyAV/FFmpeg are working as they need to.

@jlaine
Copy link
Member

jlaine commented Sep 20, 2018

Could this be due to the fact the frames had a bogus timebase until recently?

@jlaine
Copy link
Member

jlaine commented Sep 20, 2018

I ran the following, which worked fine using PyAV 0.5.1:

import av
import logging
logging.basicConfig()

input_container = av.open('input.mp4')
video_stream = input_container.streams.video[0]

output_container = av.open('output.mp4', mode='w')
stream = output_container.add_stream('libx264')
stream.width = 512
stream.height = 512
stream.pix_fmt = 'yuv420p'
stream.time_base = video_stream.time_base

for frame in input_container.decode(video=0):
    packet = stream.encode(frame)
    output_container.mux(packet)

output_container.close()

As you can see:

  • I didn't pass the rate parameter when opening the container, but copied time_base from the input to the output stream
  • I didn't touch the frames' pts or time_base
  • I didn't use the final stream.encode(), as this results in a packet with no PTS causing ffmpeg to bomb

The output file has the exact same framerate as my input.

@mikeboers
Copy link
Member

@jlaine It might have been the wrong timebase on the frames.

My comment from Mar. 21 was because I thought the timebase didn't match on the two streams (which it wouldn't), and so if you don't remap the pts from one to the other it will be wonky. But that is what the great time overhaul of v0.4.0 was supposed to do at all.

This could very likely be fixed, but I'm leaving the issue here as a signal to document that time needs your attention all the time.

@zhiweny1122

This comment was marked as off-topic.

@jlaine
Copy link
Member

jlaine commented Mar 25, 2022

To the best of my knowledge this is fixed

@jlaine jlaine closed this as completed Mar 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants