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
							 |