Created by: fvollmer
PyAV frames didn't have a time_base
after they were passed through a filter and add_buffer
also ignored the time_base
.
The following example deinterlaces a 30fps video.
import av.filter
import errno
input_container = av.open(format='lavfi', file='color=c=pink:duration=5:r=30')
input_video_stream = input_container.streams.video[0]
graph = av.filter.Graph()
buffer = graph.add_buffer(template=input_video_stream)
bwdif = graph.add("bwdif", "send_field:tff:all")
buffersink = graph.add("buffersink")
buffer.link_to(bwdif)
bwdif.link_to(buffersink)
graph.configure()
for frame in input_container.decode():
print(f"old time_base: {frame.time_base}, old pts: {frame.pts}")
graph.push(frame)
while True:
try:
filtered_frame = graph.pull()
except av.utils.AVError as e:
if e.errno != errno.EAGAIN:
raise
break
print(f"filtered time_base: {filtered_frame.time_base}, filtered pts: {filtered_frame.pts}")
With these patches the time_base is handled correctly
old time_base: 1/30, old pts: 0
old time_base: 1/30, old pts: 1
filtered time_base: 1/60, filtered pts: 0
filtered time_base: 1/60, filtered pts: 1
old time_base: 1/30, old pts: 2
filtered time_base: 1/60, filtered pts: 2
filtered time_base: 1/60, filtered pts: 3
old time_base: 1/30, old pts: 3
filtered time_base: 1/60, filtered pts: 4
filtered time_base: 1/60, filtered pts: 5
...
instead of
old time_base: 1/30, old pts: 0
old time_base: 1/30, old pts: 1
filtered time_base: None, filtered pts: 0
filtered time_base: None, filtered pts: 1
old time_base: 1/30, old pts: 2
filtered time_base: None, filtered pts: 2
filtered time_base: None, filtered pts: 3
old time_base: 1/30, old pts: 3
filtered time_base: None, filtered pts: 4
filtered time_base: None, filtered pts: 5