Skip to content
GitLab
Projects Groups Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
  • P PyAV
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 37
    • Issues 37
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 26
    • Merge requests 26
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Schedules
  • Deployments
    • Deployments
    • Environments
    • Releases
  • Packages and registries
    • Packages and registries
    • Package Registry
    • Infrastructure Registry
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • CI/CD
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • PyAV
  • PyAV
  • Merge requests
  • !765

Better time_base support with filters

  • Review changes

  • Download
  • Email patches
  • Plain diff
Merged Administrator requested to merge github/fork/fvollmer/time_base_filtered into main Mar 27, 2021
  • Overview 2
  • Commits 1
  • Pipelines 0
  • Changes 3

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
Assignee
Assign to
Reviewers
Request review from
Time tracking
Source branch: github/fork/fvollmer/time_base_filtered