Generate thumbnails on CPU and with high niceness
This commit is contained in:
parent
fd4e46791c
commit
6016db128c
1 changed files with 27 additions and 20 deletions
|
@ -1,9 +1,11 @@
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
from concurrent.futures import ThreadPoolExecutor
|
from concurrent.futures import ThreadPoolExecutor
|
||||||
from typing import TYPE_CHECKING
|
from queue import LifoQueue
|
||||||
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
from gi.repository import GLib, Gst
|
from gi.repository import GLib, Gst
|
||||||
|
|
||||||
|
@ -32,8 +34,10 @@ class Thumbnailer(ThreadPoolExecutor):
|
||||||
max_workers=MAX_WORKERS,
|
max_workers=MAX_WORKERS,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._work_queue = cast(Any, LifoQueue())
|
||||||
|
|
||||||
def generate_thumbnail(self, file_item: FileItem):
|
def generate_thumbnail(self, file_item: FileItem):
|
||||||
"""Schedule thumbnail generation"""
|
"""Schedule thumbnail generation."""
|
||||||
|
|
||||||
if not file_item.full_path.is_file():
|
if not file_item.full_path.is_file():
|
||||||
return
|
return
|
||||||
|
@ -41,39 +45,41 @@ class Thumbnailer(ThreadPoolExecutor):
|
||||||
if file_item.attempted_thumbnail:
|
if file_item.attempted_thumbnail:
|
||||||
return
|
return
|
||||||
|
|
||||||
if self._work_queue.qsize() >= MAX_WORKERS:
|
self.submit(generate_thumbnail_sync_nicely, file_item)
|
||||||
# print("[thumbnail] Ignoring:", file_item.full_path.name)
|
|
||||||
return
|
|
||||||
|
|
||||||
self.submit(generate_thumbnail_sync, file_item)
|
|
||||||
file_item.attempted_thumbnail = True
|
file_item.attempted_thumbnail = True
|
||||||
|
|
||||||
|
|
||||||
|
def generate_thumbnail_sync_nicely(file_item: FileItem):
|
||||||
|
os.nice(19)
|
||||||
|
return generate_thumbnail_sync(file_item)
|
||||||
|
|
||||||
|
|
||||||
def generate_thumbnail_sync(file_item: FileItem):
|
def generate_thumbnail_sync(file_item: FileItem):
|
||||||
"""Generate thumbnail for a single file"""
|
"""Generate thumbnail for a single file"""
|
||||||
|
|
||||||
# print("[thumbnailer] Generate:", file_item.full_path.name)
|
# print("[thumbnailer] Generate:", file_item.full_path.name)
|
||||||
|
|
||||||
pipeline_str = (
|
pipeline_str = (
|
||||||
"uridecodebin name=uridecodebin ! "
|
"uridecodebin name=uridecodebin force-sw-decoders=true ! "
|
||||||
"videoconvert ! "
|
"videoconvert ! "
|
||||||
"jpegenc quality=85 ! "
|
"jpegenc quality=85 ! "
|
||||||
"appsink sync=false name=sink"
|
"appsink sync=false name=sink"
|
||||||
)
|
)
|
||||||
|
|
||||||
pipeline = Gst.parse_launch(pipeline_str)
|
pipeline: Gst.Pipeline | None = None
|
||||||
assert isinstance(pipeline, Gst.Pipeline)
|
|
||||||
|
|
||||||
sink = pipeline.get_by_name("sink")
|
|
||||||
assert isinstance(sink, Gst.Element)
|
|
||||||
|
|
||||||
uridecodebin = pipeline.get_by_name("uridecodebin")
|
|
||||||
assert isinstance(uridecodebin, Gst.Element)
|
|
||||||
|
|
||||||
# Set file URI
|
|
||||||
uridecodebin.set_property("uri", Gst.filename_to_uri(str(file_item.full_path)))
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
pipeline = cast(Gst.Pipeline, Gst.parse_launch(pipeline_str))
|
||||||
|
|
||||||
|
sink = pipeline.get_by_name("sink")
|
||||||
|
assert isinstance(sink, Gst.Element)
|
||||||
|
|
||||||
|
uridecodebin = pipeline.get_by_name("uridecodebin")
|
||||||
|
assert isinstance(uridecodebin, Gst.Element)
|
||||||
|
|
||||||
|
# Set file URI
|
||||||
|
uridecodebin.set_property("uri", Gst.filename_to_uri(str(file_item.full_path)))
|
||||||
|
|
||||||
# Set pipeline to PAUSED to get duration
|
# Set pipeline to PAUSED to get duration
|
||||||
pipeline.set_state(Gst.State.PAUSED)
|
pipeline.set_state(Gst.State.PAUSED)
|
||||||
pipeline.get_state(Gst.CLOCK_TIME_NONE)
|
pipeline.get_state(Gst.CLOCK_TIME_NONE)
|
||||||
|
@ -119,4 +125,5 @@ def generate_thumbnail_sync(file_item: FileItem):
|
||||||
print("[thumbnailer]", err, file=sys.stderr)
|
print("[thumbnailer]", err, file=sys.stderr)
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
pipeline.set_state(Gst.State.NULL)
|
if pipeline:
|
||||||
|
pipeline.set_state(Gst.State.NULL)
|
||||||
|
|
Loading…
Reference in a new issue