47 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			47 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# 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
 |