Tiny refactor of codecs (#1121)

* improve performance using pointers

* simplify decoder's collect

* simplify decoder's collect

* add threading to decoders

* fix test

* switch back to return bytes

* fix macos
This commit is contained in:
Henry Ruhs
2026-05-19 10:31:53 +02:00
committed by GitHub
parent c00ea92f35
commit fbacb24fcc
7 changed files with 128 additions and 169 deletions
+23 -38
View File
@@ -1,52 +1,56 @@
import ctypes
import struct
from typing import Optional
from facefusion.libraries import aom as aom_module
from facefusion.types import AomDecoder, Resolution
from facefusion.types import AomDecoder, AomPointer
def create() -> Optional[AomDecoder]:
def create(thread_count : int) -> Optional[AomDecoder]:
aom_library = aom_module.create_static_library()
if aom_library:
aom_decoder = ctypes.create_string_buffer(128)
aom_codec = ctypes.c_void_p.in_dll(aom_library, 'aom_codec_av1_dx_algo')
config_buffer = ctypes.create_string_buffer(128)
if aom_library.aom_codec_dec_init_ver(aom_decoder, ctypes.byref(aom_codec), None, 0, 22) == 0:
struct.pack_into('I', config_buffer, 0, thread_count)
struct.pack_into('I', config_buffer, 12, 1)
if aom_library.aom_codec_dec_init_ver(aom_decoder, ctypes.byref(aom_codec), config_buffer, 0, 22) == 0:
return aom_decoder
return None
#TODO: needs review
def decode(aom_decoder : AomDecoder, input_buffer : bytes) -> bytes:
def decode(aom_decoder : AomDecoder, input_buffer : bytes) -> Optional[AomPointer]:
aom_library = aom_module.create_static_library()
output_buffer = bytes()
if aom_library and input_buffer:
input_total = len(input_buffer)
temp_buffer = (ctypes.c_uint8 * input_total).from_buffer_copy(input_buffer)
temp_buffer = ctypes.create_string_buffer(input_buffer)
if aom_library.aom_codec_decode(aom_decoder, temp_buffer, input_total, None) == 0:
frame_pointer = aom_library.aom_codec_get_frame(aom_decoder, ctypes.byref(ctypes.c_void_p(0)))
address = aom_library.aom_codec_get_frame(aom_decoder, ctypes.byref(ctypes.c_void_p(0)))
if frame_pointer:
output_buffer = collect(frame_pointer)
if address:
frame_width = ctypes.c_uint.from_address(address + 28).value & ~1
frame_height = ctypes.c_uint.from_address(address + 32).value & ~1
return output_buffer
return AomPointer(
buffer = collect(address, frame_width, frame_height),
resolution = (frame_width, frame_height)
)
return None
#TODO: needs review
def collect(frame_pointer : int) -> bytes:
frame_width = ctypes.c_uint.from_address(frame_pointer + 28).value & ~1
frame_height = ctypes.c_uint.from_address(frame_pointer + 32).value & ~1
planes_offset = frame_pointer + 64
strides_offset = frame_pointer + 88
def collect(address : int, frame_width : int, frame_height : int) -> bytes:
output_buffer = bytes()
for index in range(3):
plane_pointer = ctypes.c_void_p.from_address(planes_offset + index * 8).value
stride = ctypes.c_int.from_address(strides_offset + index * 4).value
plane_pointer = ctypes.c_void_p.from_address(address + 64 + index * 8).value
stride = ctypes.c_int.from_address(address + 88 + index * 4).value
plane_width = frame_width >> (index > 0)
plane_height = frame_height >> (index > 0)
@@ -56,25 +60,6 @@ def collect(frame_pointer : int) -> bytes:
return output_buffer
#TODO: needs review
def read_resolution(aom_decoder : AomDecoder, input_buffer : bytes) -> Optional[Resolution]:
aom_library = aom_module.create_static_library()
if aom_library and input_buffer:
input_total = len(input_buffer)
temp_buffer = (ctypes.c_uint8 * input_total).from_buffer_copy(input_buffer)
if aom_library.aom_codec_decode(aom_decoder, temp_buffer, input_total, None) == 0:
frame_pointer = aom_library.aom_codec_get_frame(aom_decoder, ctypes.byref(ctypes.c_void_p(0)))
if frame_pointer:
frame_width = ctypes.c_uint.from_address(frame_pointer + 28).value & ~1
frame_height = ctypes.c_uint.from_address(frame_pointer + 32).value & ~1
return frame_width, frame_height
return None
def destroy(aom_decoder : AomDecoder) -> None:
aom_library = aom_module.create_static_library()