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
  • Issues
  • #886
Closed
Open
Issue created Feb 14, 2022 by Sebastian Wallkötter@FirefoxMetzgerContributor

How do I send EOF to a av.filter.Graph?

Overview

I'm trying to use the FFMPEG filter palettegen to compute a color pallette for a video (and then turn it into a GIF later on). However, the filter expects to read a full video and wishes to receive an EOF error (relevant line inside FFmpeg source) before it outputs a single 256 color pallette.

When using the binary, this can be achieved as: ffmpeg -i testsrc.mp4 -vf palettegen pallette.png (To generate a test video: ffmpeg -f lavfi -i testsrc -t 10 -pix_fmt yuv444p testsrc.mp4)

However, writing the same in pyAV the filter never produces an output, because it waits for the EOF signal. I don't know how to send it, nor have I been able to work it out from the source code. A pointer would be highly appreciated :)

Here is the code as far as I got:

import av
import av.filter

graph = av.filter.Graph()

with av.open("testsrc.mp4", "r") as container:
    video_stream = container.streams.video[0]
    
    # setup filter graph
    video_in = graph.add_buffer(template=video_stream)
    palette_gen_filter = graph.add("palettegen")
    video_out = graph.add("buffersink")
    video_in.link_to(palette_gen_filter)
    palette_gen_filter.link_to(video_out)
    graph.configure()

    for frame in container.decode(video=0):
        graph.push(frame)

    # TODO: Send EOF ... but how?

    palette_frame = graph.pull()  # this currently fails   

The above currently fails with the following exception:

Traceback (most recent call last):
  File "delete_me.py", line 22, in <module>
    palette_frame = graph.pull()  # this currently fails
  File "av/filter/graph.pyx", line 212, in av.filter.graph.Graph.pull
  File "av/filter/context.pyx", line 107, in av.filter.context.FilterContext.pull
  File "av/error.pyx", line 336, in av.error.err_check
av.error.BlockingIOError: [Errno 11] Resource temporarily unavailable
Assignee
Assign to
Time tracking