# RozK import errno from . import libav from .frame import Frame class Decoder: __slots__ = '_ref' def __init__(self, codec): self._ref = libav.codec_alloc_context(codec) if not self._ref: raise MemoryError errcode = libav.codec_open(self._ref, codec) if errcode < 0: libav.codec_free_context(self._ref) raise Exception("Failed to open codec context") def __del__(self): if self._ref: libav.codec_free_context(self._ref) def _recieve(self, frames): while True: frame = Frame() errcode = libav.codec_receive_frame(self._ref, frame) if errcode == 0: frames.append(frame) elif errcode == errno.EAGAIN: break else: raise Exception(f"Failed to receive frame: {errcode}") def decode(self, packet): if not self._ref: return None frames = [] while True: errcode = libav.codec_send_packet(self._ref, packet) if errcode != 0 and errcode != errno.EAGAIN: raise Exception(f"Failed to send packet: {errcode}") self._recieve(frames) if errcode == 0: break return frames