Skip to content

Commit e0103cf

Browse files
authored
Reduce Python overhead in reformat
1 parent 4baa626 commit e0103cf

1 file changed

Lines changed: 29 additions & 30 deletions

File tree

av/video/reformatter.py

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import cython
44
import cython.cimports.libav as lib
55
from cython.cimports.av.error import err_check
6-
from cython.cimports.av.video.format import VideoFormat
6+
from cython.cimports.av.video.format import VideoFormat, get_pix_fmt
77
from cython.cimports.av.video.frame import alloc_video_frame
88

99

@@ -91,6 +91,7 @@ class ColorPrimaries(IntEnum):
9191

9292

9393
@cython.cfunc
94+
@cython.inline
9495
def _resolve_enum_value(
9596
value: object, enum_class: object, default: cython.int
9697
) -> cython.int:
@@ -106,6 +107,16 @@ def _resolve_enum_value(
106107
raise ValueError(f"Cannot convert {value} to {enum_class.__name__}")
107108

108109

110+
@cython.cfunc
111+
@cython.inline
112+
def _resolve_format(format: object, default: lib.AVPixelFormat) -> lib.AVPixelFormat:
113+
if format is None:
114+
return default
115+
if isinstance(format, VideoFormat):
116+
return cython.cast(VideoFormat, format).pix_fmt
117+
return get_pix_fmt(format)
118+
119+
109120
@cython.cfunc
110121
def _set_frame_colorspace(
111122
frame: cython.pointer(lib.AVFrame),
@@ -186,18 +197,15 @@ def reformat(
186197
selection based on the number of available CPUs. Defaults to ``0`` (auto).
187198
188199
"""
189-
190-
video_format: VideoFormat = VideoFormat(
191-
format if format is not None else frame.format
192-
)
200+
c_dst_format = _resolve_format(format, frame.format.pix_fmt)
193201
c_src_colorspace = _resolve_enum_value(
194-
src_colorspace, Colorspace, frame.colorspace
202+
src_colorspace, Colorspace, frame.ptr.colorspace
195203
)
196204
c_dst_colorspace = _resolve_enum_value(
197-
dst_colorspace, Colorspace, frame.colorspace
205+
dst_colorspace, Colorspace, frame.ptr.colorspace
198206
)
199207
c_interpolation = _resolve_enum_value(
200-
interpolation, Interpolation, int(Interpolation.BILINEAR)
208+
interpolation, Interpolation, SWS_BILINEAR
201209
)
202210
c_src_color_range = _resolve_enum_value(src_color_range, ColorRange, 0)
203211
c_dst_color_range = _resolve_enum_value(dst_color_range, ColorRange, 0)
@@ -206,16 +214,18 @@ def reformat(
206214
dst_color_primaries, ColorPrimaries, 0
207215
)
208216
c_threads: cython.int = threads if threads is not None else 0
217+
c_width: cython.int = width if width is not None else frame.ptr.width
218+
c_height: cython.int = height if height is not None else frame.ptr.height
209219

210220
# Track whether user explicitly specified destination metadata
211221
set_dst_color_trc: cython.bint = dst_color_trc is not None
212222
set_dst_color_primaries: cython.bint = dst_color_primaries is not None
213223

214224
return self._reformat(
215225
frame,
216-
width or frame.ptr.width,
217-
height or frame.ptr.height,
218-
video_format.pix_fmt,
226+
c_width,
227+
c_height,
228+
c_dst_format,
219229
c_src_colorspace,
220230
c_dst_colorspace,
221231
c_interpolation,
@@ -252,25 +262,6 @@ def _reformat(
252262
src_format = cython.cast(lib.AVPixelFormat, frame.ptr.format)
253263

254264
# Shortcut!
255-
if frame.ptr.hw_frames_ctx:
256-
if (
257-
dst_format == src_format
258-
and width == frame.ptr.width
259-
and height == frame.ptr.height
260-
and dst_colorspace == src_colorspace
261-
and src_color_range == dst_color_range
262-
and not set_dst_color_trc
263-
and not set_dst_color_primaries
264-
):
265-
return frame
266-
267-
frame_sw = alloc_video_frame()
268-
err_check(lib.av_hwframe_transfer_data(frame_sw.ptr, frame.ptr, 0))
269-
frame_sw.pts = frame.pts
270-
frame_sw._init_user_attributes()
271-
frame = frame_sw
272-
src_format = cython.cast(lib.AVPixelFormat, frame.ptr.format)
273-
274265
if (
275266
dst_format == src_format
276267
and width == frame.ptr.width
@@ -282,6 +273,14 @@ def _reformat(
282273
):
283274
return frame
284275

276+
if frame.ptr.hw_frames_ctx:
277+
frame_sw = alloc_video_frame()
278+
err_check(lib.av_hwframe_transfer_data(frame_sw.ptr, frame.ptr, 0))
279+
frame_sw.pts = frame.pts
280+
frame_sw._init_user_attributes()
281+
frame = frame_sw
282+
src_format = cython.cast(lib.AVPixelFormat, frame.ptr.format)
283+
285284
if self.ptr == cython.NULL:
286285
self.ptr = sws_alloc_context()
287286
if self.ptr == cython.NULL:

0 commit comments

Comments
 (0)