diff --git a/av/filter/context.pyi b/av/filter/context.pyi index 13ee480c2..d37febdb9 100644 --- a/av/filter/context.pyi +++ b/av/filter/context.pyi @@ -12,3 +12,6 @@ class FilterContext: def graph(self) -> Graph: ... def push(self, frame: Frame) -> None: ... def pull(self) -> Frame: ... + def process_command( + self, cmd: str, arg: str | None = None, res_len: int = 1024, flags: int = 0 + ) -> str | None: ... diff --git a/av/filter/context.pyx b/av/filter/context.pyx index ba5981ff1..85c23863b 100644 --- a/av/filter/context.pyx +++ b/av/filter/context.pyx @@ -1,3 +1,5 @@ +cimport libav as lib + import weakref from av.audio.frame cimport alloc_audio_frame @@ -132,3 +134,41 @@ cdef class FilterContext: frame._init_user_attributes() frame.time_base = avrational_to_fraction(&self.ptr.inputs[0].time_base) return frame + + def process_command(self, cmd, arg=None, int res_len=1024, int flags=0): + if not cmd: + raise ValueError("Invalid cmd") + + cdef char *c_cmd = NULL + cdef char *c_arg = NULL + + c_cmd = cmd + if arg is not None: + c_arg = arg + + cdef char *c_res = NULL + cdef int ret + cdef bytearray res_buf = None + cdef unsigned char[:] view + cdef bytes b + cdef int nul + + if res_len > 0: + res_buf = bytearray(res_len) + view = res_buf + c_res = &view[0] + else: + c_res = NULL + + with nogil: + ret = lib.avfilter_process_command(self.ptr, c_cmd, c_arg, c_res, res_len, flags) + err_check(ret) + + if res_buf is not None: + b = bytes(res_buf) + nul = b.find(b'\x00') + if nul >= 0: + b = b[:nul] + if b: + return b.decode("utf-8", "strict") + return None diff --git a/include/libavfilter/avfilter.pxd b/include/libavfilter/avfilter.pxd index b1ced248b..8d4c05f6f 100644 --- a/include/libavfilter/avfilter.pxd +++ b/include/libavfilter/avfilter.pxd @@ -62,6 +62,15 @@ cdef extern from "libavfilter/avfilter.h" nogil: # custom cdef set pyav_get_available_filters() + int avfilter_process_command(AVFilterContext *filter, + const char *cmd, + const char *arg, + char *res, + int res_len, + int flags) + + cdef int AVFILTER_CMD_FLAG_FAST + cdef extern from "libavfilter/buffersink.h" nogil: cdef void av_buffersink_set_frame_size(AVFilterContext *ctx, unsigned frame_size)