PyAV v17.0.1
Code to reproduce:
from fractions import Fraction
import av
path = "/tmp/pyav_nonzero_video_pts_repro.mp4"
fps = Fraction(30, 1)
out = av.open(path, "w")
stream = out.add_stream("mpeg4", rate=fps)
stream.width = 64
stream.height = 64
stream.pix_fmt = "yuv420p"
stream.codec_context.time_base = Fraction(1, fps)
print("encode input:")
for i in range(4):
frame = av.VideoFrame(64, 64, "yuv420p")
frame.pts = i + 1
frame.time_base = source_tb
print(
i,
"frame_time * fps =", Fraction(frame.pts) * frame.time_base * fps,
)
for packet in stream.encode(frame):
out.mux(packet)
for packet in stream.encode():
print(
" packet before mux:",
"packet.pts =", packet.pts,
"packet.time_base =", packet.time_base,
)
out.mux(packet)
out.close()
print("\ndecode output:")
inp = av.open(path)
video = inp.streams.video[0]
print(
"decoded stream:",
"time_base =", video.time_base,
"start_time =", video.start_time,
"average_rate =", video.average_rate,
)
for i, frame in enumerate(inp.decode(video)):
t_x_fps = Fraction(frame.pts) * frame.time_base * fps
print(
i,
"frame_time * fps =", t_x_fps,
)
Output:
encode input:
0 frame_time * fps = 1
1 frame_time * fps = 2
2 frame_time * fps = 3
3 frame_time * fps = 4
decode output:
decoded stream: time_base = 1/15360 start_time = 507 average_rate = 30
0 frame_time * fps = 507/512
1 frame_time * fps = 1019/512
2 frame_time * fps = 1531/512
3 frame_time * fps = 2043/512
Expected output:
encode input:
0 frame_time * fps = 1
1 frame_time * fps = 2
2 frame_time * fps = 3
3 frame_time * fps = 4
decode output:
...
0 frame_time * fps = 1
1 frame_time * fps = 2
2 frame_time * fps = 3
3 frame_time * fps = 4
Weirdly enough if the pts starts from values like 0, 3, 6, 12, the problem does not occur at all.
PyAV v17.0.1
Code to reproduce:
Output:
Expected output:
Weirdly enough if the pts starts from values like 0, 3, 6, 12, the problem does not occur at all.