diff --git a/mp4/decoder.py b/mp4/decoder.py index 248ef70..db41e17 100644 --- a/mp4/decoder.py +++ b/mp4/decoder.py @@ -58,6 +58,3 @@ class Decoder: errstring = libav.strerror(errcode) raise Exception(f"Failed to send packet: {errstring}") return self._receive() - - def flush(self): - return self.decode(None) diff --git a/mp4/demuxer.py b/mp4/demuxer.py index f8ae8a6..327b723 100644 --- a/mp4/demuxer.py +++ b/mp4/demuxer.py @@ -34,16 +34,16 @@ class Demuxer: raise Exception("Failed to find stream info") self.video_stream = self._find_stream(libav.AVMEDIA_TYPE_VIDEO) if self.video_stream is None: + libav.format_close_input(self._context) raise Exception("Failed to find a video stream") self.audio_stream = self._find_stream(libav.AVMEDIA_TYPE_AUDIO) if self.audio_stream is None: + libav.format_close_input(self._context) raise Exception("Failed to find an audio stream") - @property - def nb_streams(self): - if not self._context: - return 0 - return self._context.contents.nb_streams + def __del__(self): + if self._context: + libav.format_close_input(self._context) def _find_stream(self, 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 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): if not self._context: return None @@ -60,7 +66,3 @@ class Demuxer: if errcode < 0: return None return packet - - def close(self): - if self._context: - libav.format_close_input(self._context) diff --git a/mp4/libav.py b/mp4/libav.py index 3895d72..419f019 100644 --- a/mp4/libav.py +++ b/mp4/libav.py @@ -50,12 +50,19 @@ class AVCodecParameters(ctypes.Structure): AVCodecParameters_p = ctypes.POINTER(AVCodecParameters) +class AVRational(ctypes.Structure): + _fields_ = [ + ("num", ctypes.c_int), + ("den", ctypes.c_int)] + class AVStream(ctypes.Structure): _fields_ = [ ("av_class", ctypes.c_void_p), ("index", 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) diff --git a/mp4/packet.py b/mp4/packet.py index c077247..bc92f17 100644 --- a/mp4/packet.py +++ b/mp4/packet.py @@ -36,9 +36,3 @@ class Packet: if self._ref: return self._ref.contents.stream_index return -1 - - @property - def pts(self): - if self._ref: - return self._ref.contents.pts - return 0 diff --git a/pve.py b/pve.py index 765917f..fd66ccb 100644 --- a/pve.py +++ b/pve.py @@ -27,23 +27,12 @@ audio_decoder = Decoder(demuxer.audio_stream) while True: packet = demuxer.read_packet() - if packet is None: - break - if demuxer.video_stream.contains(packet): + eof = (packet is None) + if eof or demuxer.video_stream.contains(packet): video_frames = video_decoder.decode(packet) print(f"decoded {len(video_frames)} video frames") - continue - elif demuxer.audio_stream.contains(packet): + if eof or demuxer.audio_stream.contains(packet): audio_frames = audio_decoder.decode(packet) print(f"decoded {len(audio_frames)} audio frames") - continue - else: - 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() + if eof: + break