mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-02-06 14:40:51 +03:00
Set default max threads in Python (#4)
* Removed unused C values * Set default max threads in Python --------- Co-authored-by: Andrew Murray <radarhere@users.noreply.github.com>
This commit is contained in:
parent
d6a0a15f53
commit
50b993a0cb
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
from io import BytesIO
|
||||
from typing import IO
|
||||
|
||||
|
@ -46,6 +47,15 @@ def _accept(prefix: bytes) -> bool | str:
|
|||
return False
|
||||
|
||||
|
||||
def _get_default_max_threads():
|
||||
if DEFAULT_MAX_THREADS:
|
||||
return DEFAULT_MAX_THREADS
|
||||
if hasattr(os, "sched_getaffinity"):
|
||||
return len(os.sched_getaffinity(0))
|
||||
else:
|
||||
return os.cpu_count() or 1
|
||||
|
||||
|
||||
class AvifImageFile(ImageFile.ImageFile):
|
||||
format = "AVIF"
|
||||
format_description = "AVIF image"
|
||||
|
@ -64,7 +74,10 @@ class AvifImageFile(ImageFile.ImageFile):
|
|||
raise SyntaxError(msg)
|
||||
|
||||
self._decoder = _avif.AvifDecoder(
|
||||
self.fp.read(), DECODE_CODEC_CHOICE, CHROMA_UPSAMPLING, DEFAULT_MAX_THREADS
|
||||
self.fp.read(),
|
||||
DECODE_CODEC_CHOICE,
|
||||
CHROMA_UPSAMPLING,
|
||||
_get_default_max_threads(),
|
||||
)
|
||||
|
||||
# Get info from decoder
|
||||
|
@ -140,7 +153,7 @@ def _save(
|
|||
duration = info.get("duration", 0)
|
||||
subsampling = info.get("subsampling", "4:2:0")
|
||||
speed = info.get("speed", 6)
|
||||
max_threads = info.get("max_threads", DEFAULT_MAX_THREADS)
|
||||
max_threads = info.get("max_threads", _get_default_max_threads())
|
||||
codec = info.get("codec", "auto")
|
||||
range_ = info.get("range", "full")
|
||||
tile_rows_log2 = info.get("tile_rows", 0)
|
||||
|
|
89
src/_avif.c
89
src/_avif.c
|
@ -44,54 +44,6 @@ typedef struct {
|
|||
|
||||
static PyTypeObject AvifDecoder_Type;
|
||||
|
||||
static int default_max_threads = 0;
|
||||
|
||||
static void
|
||||
init_max_threads(void) {
|
||||
PyObject *os = NULL;
|
||||
PyObject *n = NULL;
|
||||
long num_cpus;
|
||||
|
||||
os = PyImport_ImportModule("os");
|
||||
if (os == NULL) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (PyObject_HasAttrString(os, "sched_getaffinity")) {
|
||||
n = PyObject_CallMethod(os, "sched_getaffinity", "i", 0);
|
||||
if (n == NULL) {
|
||||
goto error;
|
||||
}
|
||||
num_cpus = PySet_Size(n);
|
||||
} else {
|
||||
n = PyObject_CallMethod(os, "cpu_count", NULL);
|
||||
if (n == NULL) {
|
||||
goto error;
|
||||
}
|
||||
num_cpus = PyLong_AsLong(n);
|
||||
}
|
||||
|
||||
if (num_cpus < 1) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
default_max_threads = (int)num_cpus;
|
||||
|
||||
done:
|
||||
Py_XDECREF(os);
|
||||
Py_XDECREF(n);
|
||||
return;
|
||||
|
||||
error:
|
||||
if (PyErr_Occurred()) {
|
||||
PyErr_Clear();
|
||||
}
|
||||
PyErr_WarnEx(
|
||||
PyExc_RuntimeWarning, "could not get cpu count: using max_threads=1", 1
|
||||
);
|
||||
goto done;
|
||||
}
|
||||
|
||||
static int
|
||||
normalize_quantize_value(int qvalue) {
|
||||
if (qvalue < AVIF_QUANTIZER_BEST_QUALITY) {
|
||||
|
@ -306,23 +258,23 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
|
|||
AvifEncoderObject *self = NULL;
|
||||
avifEncoder *encoder = NULL;
|
||||
|
||||
char *subsampling = "4:2:0";
|
||||
int qmin = AVIF_QUANTIZER_BEST_QUALITY; // =0
|
||||
int qmax = 10; // "High Quality", but not lossless
|
||||
int quality = 75;
|
||||
int speed = 8;
|
||||
int exif_orientation = 0;
|
||||
int max_threads = default_max_threads;
|
||||
char *subsampling;
|
||||
int qmin;
|
||||
int qmax;
|
||||
int quality;
|
||||
int speed;
|
||||
int exif_orientation;
|
||||
int max_threads;
|
||||
PyObject *icc_bytes;
|
||||
PyObject *exif_bytes;
|
||||
PyObject *xmp_bytes;
|
||||
PyObject *alpha_premultiplied = NULL;
|
||||
PyObject *autotiling = NULL;
|
||||
int tile_rows_log2 = 0;
|
||||
int tile_cols_log2 = 0;
|
||||
PyObject *alpha_premultiplied;
|
||||
PyObject *autotiling;
|
||||
int tile_rows_log2;
|
||||
int tile_cols_log2;
|
||||
|
||||
char *codec = "auto";
|
||||
char *range = "full";
|
||||
char *codec;
|
||||
char *range;
|
||||
|
||||
PyObject *advanced;
|
||||
|
||||
|
@ -438,13 +390,6 @@ AvifEncoderNew(PyObject *self_, PyObject *args) {
|
|||
|
||||
encoder = avifEncoderCreate();
|
||||
|
||||
if (max_threads == 0) {
|
||||
if (default_max_threads == 0) {
|
||||
init_max_threads();
|
||||
}
|
||||
max_threads = default_max_threads;
|
||||
}
|
||||
|
||||
int is_aom_encode = strcmp(codec, "aom") == 0 ||
|
||||
(strcmp(codec, "auto") == 0 &&
|
||||
_codec_available("aom", AVIF_CODEC_FLAG_CAN_ENCODE));
|
||||
|
@ -730,7 +675,7 @@ AvifDecoderNew(PyObject *self_, PyObject *args) {
|
|||
char *codec_str;
|
||||
avifCodecChoice codec;
|
||||
avifChromaUpsampling upsampling;
|
||||
int max_threads = 0;
|
||||
int max_threads;
|
||||
|
||||
avifResult result;
|
||||
|
||||
|
@ -785,12 +730,6 @@ AvifDecoderNew(PyObject *self_, PyObject *args) {
|
|||
|
||||
self->decoder = avifDecoderCreate();
|
||||
#if AVIF_VERSION >= 80400
|
||||
if (max_threads == 0) {
|
||||
if (default_max_threads == 0) {
|
||||
init_max_threads();
|
||||
}
|
||||
max_threads = default_max_threads;
|
||||
}
|
||||
self->decoder->maxThreads = max_threads;
|
||||
#endif
|
||||
#if AVIF_VERSION >= 90200
|
||||
|
|
Loading…
Reference in New Issue
Block a user