This commit is contained in:
2025-10-03 18:08:09 +02:00
parent 7cf7a8cb9a
commit b0c3fbc1b1
5 changed files with 24 additions and 35 deletions

View File

@ -58,6 +58,3 @@ class Decoder:
errstring = libav.strerror(errcode) errstring = libav.strerror(errcode)
raise Exception(f"Failed to send packet: {errstring}") raise Exception(f"Failed to send packet: {errstring}")
return self._receive() return self._receive()
def flush(self):
return self.decode(None)

View File

@ -34,16 +34,16 @@ class Demuxer:
raise Exception("Failed to find stream info") raise Exception("Failed to find stream info")
self.video_stream = self._find_stream(libav.AVMEDIA_TYPE_VIDEO) self.video_stream = self._find_stream(libav.AVMEDIA_TYPE_VIDEO)
if self.video_stream is None: if self.video_stream is None:
libav.format_close_input(self._context)
raise Exception("Failed to find a video stream") raise Exception("Failed to find a video stream")
self.audio_stream = self._find_stream(libav.AVMEDIA_TYPE_AUDIO) self.audio_stream = self._find_stream(libav.AVMEDIA_TYPE_AUDIO)
if self.audio_stream is None: if self.audio_stream is None:
libav.format_close_input(self._context)
raise Exception("Failed to find an audio stream") raise Exception("Failed to find an audio stream")
@property def __del__(self):
def nb_streams(self): if self._context:
if not self._context: libav.format_close_input(self._context)
return 0
return self._context.contents.nb_streams
def _find_stream(self, type): def _find_stream(self, type):
index, codec_ref = libav.format_find_best_stream(self._context, type) index, codec_ref = libav.format_find_best_stream(self._context, type)
@ -52,6 +52,12 @@ class Demuxer:
parameters = self._context.contents.streams[index].contents.codecpar parameters = self._context.contents.streams[index].contents.codecpar
return Stream(index, Codec(codec_ref), parameters) return Stream(index, Codec(codec_ref), parameters)
@property
def nb_streams(self):
if not self._context:
return 0
return self._context.contents.nb_streams
def read_packet(self): def read_packet(self):
if not self._context: if not self._context:
return None return None
@ -60,7 +66,3 @@ class Demuxer:
if errcode < 0: if errcode < 0:
return None return None
return packet return packet
def close(self):
if self._context:
libav.format_close_input(self._context)

View File

@ -50,12 +50,19 @@ class AVCodecParameters(ctypes.Structure):
AVCodecParameters_p = ctypes.POINTER(AVCodecParameters) AVCodecParameters_p = ctypes.POINTER(AVCodecParameters)
class AVRational(ctypes.Structure):
_fields_ = [
("num", ctypes.c_int),
("den", ctypes.c_int)]
class AVStream(ctypes.Structure): class AVStream(ctypes.Structure):
_fields_ = [ _fields_ = [
("av_class", ctypes.c_void_p), ("av_class", ctypes.c_void_p),
("index", ctypes.c_int), ("index", ctypes.c_int),
("id", ctypes.c_int), ("id", ctypes.c_int),
("codecpar", AVCodecParameters_p)] ("codecpar", AVCodecParameters_p),
("priv_data", ctypes.c_void_p),
("time_base", AVRational)]
# ... # ...
AVStream_p = ctypes.POINTER(AVStream) AVStream_p = ctypes.POINTER(AVStream)

View File

@ -36,9 +36,3 @@ class Packet:
if self._ref: if self._ref:
return self._ref.contents.stream_index return self._ref.contents.stream_index
return -1 return -1
@property
def pts(self):
if self._ref:
return self._ref.contents.pts
return 0

21
pve.py
View File

@ -27,23 +27,12 @@ audio_decoder = Decoder(demuxer.audio_stream)
while True: while True:
packet = demuxer.read_packet() packet = demuxer.read_packet()
if packet is None: eof = (packet is None)
break if eof or demuxer.video_stream.contains(packet):
if demuxer.video_stream.contains(packet):
video_frames = video_decoder.decode(packet) video_frames = video_decoder.decode(packet)
print(f"decoded {len(video_frames)} video frames") print(f"decoded {len(video_frames)} video frames")
continue if eof or demuxer.audio_stream.contains(packet):
elif demuxer.audio_stream.contains(packet):
audio_frames = audio_decoder.decode(packet) audio_frames = audio_decoder.decode(packet)
print(f"decoded {len(audio_frames)} audio frames") print(f"decoded {len(audio_frames)} audio frames")
continue if eof:
else: break
print("unkown packet")
video_frames = video_decoder.flush()
print(f"flushed {len(video_frames)} video frames")
audio_frames = audio_decoder.flush()
print(f"flushed {len(audio_frames)} audio frames")
demuxer.close()