Files
rk_pve/mp4/libav.py
2025-10-03 13:25:14 +02:00

113 lines
3.2 KiB
Python

# RozK
# https://www.ffmpeg.org/doxygen/trunk/group__libavf.html
import ctypes
_avformat = ctypes.cdll.LoadLibrary('libavformat.so')
_avcodec = ctypes.cdll.LoadLibrary('libavcodec.so')
class AVFormatContext(ctypes.Structure):
pass
AVFormatContext_p = ctypes.POINTER(AVFormatContext)
AVFormatContext_pp = ctypes.POINTER(AVFormatContext_p)
_avformat.avformat_alloc_context.restype = AVFormatContext_p
_avformat.avformat_alloc_context.argtypes = None
def alloc_context():
return _avformat.avformat_alloc_context()
_avformat.avformat_free_context.restype = None
_avformat.avformat_free_context.argtypes = [AVFormatContext_p] # context
def free_context(context):
_avformat.avformat_free_context(context)
_avformat.avformat_open_input.restype = ctypes.c_int
_avformat.avformat_open_input.argtypes = [
AVFormatContext_pp, # context
ctypes.c_char_p, # url
ctypes.c_void_p, # format
ctypes.POINTER(ctypes.c_void_p)] # options
def open_input(context, url):
return _avformat.avformat_open_input(ctypes.byref(context), url.encode('ascii', 'ignore'), None, None)
_avformat.avformat_close_input.restype = None
_avformat.avformat_close_input.argtypes = [AVFormatContext_pp] # context
def close_input(context):
_avformat.avformat_close_input(ctypes.byref(context))
_avformat.avformat_find_stream_info.restype = ctypes.c_int
_avformat.avformat_find_stream_info.argtypes = [
AVFormatContext_p, # context
ctypes.POINTER(ctypes.c_void_p)] # options
def find_stream_info(context):
return _avformat.avformat_find_stream_info(context, None)
AVMEDIA_TYPE_UNKNOWN = -1
AVMEDIA_TYPE_VIDEO = 0
AVMEDIA_TYPE_AUDIO = 1
AVMEDIA_TYPE_DATA = 2
AVMEDIA_TYPE_SUBTITLE = 3
AVMEDIA_TYPE_ATTACHMENT = 4
class AVCodec(ctypes.Structure):
_fields_ = [
("name", ctypes.c_char_p),
("long_name", ctypes.c_char_p)]
# ...
AVCodec_p = ctypes.POINTER(AVCodec)
AVCodec_pp = ctypes.POINTER(AVCodec_p)
_avformat.av_find_best_stream.restype = ctypes.c_int
_avformat.av_find_best_stream.argtypes = [
AVFormatContext_p, # context
ctypes.c_int, # type
ctypes.c_int, # wanted stream
ctypes.c_int, # related stream
AVCodec_pp, # decoder
ctypes.c_int] # flags
def find_best_stream(context, type):
codec = AVCodec_p()
index = _avformat.av_find_best_stream(context, type, -1, -1, ctypes.byref(codec), 0)
return index, codec
class AVPacket(ctypes.Structure):
_fields_ = [
("buf", ctypes.c_void_p),
("pts", ctypes.c_int64),
("dts", ctypes.c_int64),
("data", ctypes.c_void_p),
("size", ctypes.c_int),
("stream_index", ctypes.c_int)]
# ...
AVPacket_p = ctypes.POINTER(AVPacket)
AVPacket_pp = ctypes.POINTER(AVPacket_p)
_avformat.av_packet_alloc.restype = AVPacket_p
_avformat.av_packet_alloc.argtypes = None
def packet_alloc():
return _avformat.av_packet_alloc()
_avformat.av_packet_free.restype = None
_avformat.av_packet_free.argtypes = [AVPacket_pp] # packet
def packet_free(packet):
_avformat.av_packet_free(ctypes.byref(packet))
_avformat.av_read_frame.restype = ctypes.c_int
_avformat.av_read_frame.argtypes = [
AVFormatContext_p, # context
AVPacket_p] # packet
def read_frame(context, packet):
return _avformat.av_read_frame(context, packet)