Skip to content

Commit

Permalink
feat: flush frames when EOF encountered
Browse files Browse the repository at this point in the history
  • Loading branch information
stakach committed Sep 29, 2023
1 parent 05ab7cf commit c43617a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
10 changes: 10 additions & 0 deletions src/ffmpeg.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,14 @@ module FFmpeg
return "unknown" if success < 0
String.new(buffer.to_unsafe) # unsafe as it's \0 terminated
end

def self.mktag(a : Char, b : Char, c : Char, d : Char)
(a.ord) | (b.ord << 8) | (c.ord << 16) | (d.ord.to_u << 24)
end

def self.fferrtag(a : Char, b : Char, c : Char, d : Char)
-(mktag(a, b, c, d))
end

AVERROR_EOF = fferrtag('E', 'O', 'F', ' ')
end
9 changes: 7 additions & 2 deletions src/ffmpeg/codec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,13 @@ class FFmpeg::Codec

getter frame : Frame { Frame.new }

def decode(packet : Packet, &)
success = LibAV::Codec.send_packet(@context, packet)
def decode(packet : Packet?, &)
success = if packet
LibAV::Codec.send_packet(@context, packet)
else
# flush the codec for any final frames
LibAV::Codec.send_packet(@context, Pointer(FFmpeg::LibAV::Codec::Packet).null)
end
raise "failed to read packet with #{success}: #{FFmpeg.get_error_message(success)}" if success < 0

loop do
Expand Down
10 changes: 9 additions & 1 deletion src/ffmpeg/format.cr
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,15 @@ class FFmpeg::Format

def read(&)
status = LibAV::Format.read_frame(@context, packet)
raise "failed to read a frame with #{status}: #{FFmpeg.get_error_message(status)}" if status < 0

if status < 0
case status
when AVERROR_EOF
raise IO::EOFError.new(FFmpeg.get_error_message(status))
else
raise "failed to read a frame with #{status}: #{FFmpeg.get_error_message(status)}"
end
end

begin
yield packet
Expand Down
18 changes: 12 additions & 6 deletions src/ffmpeg/video.cr
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,21 @@ abstract class FFmpeg::Video

seek(0, SeekStyle::Frame)

Log.trace { "extracting frames" }
while !closed?
format.read do |packet|
if packet.stream_index == stream_index
codec.decode(packet) do |frame|
yield frame
begin
Log.trace { "extracting frames" }
while !closed?
format.read do |packet|
if packet.stream_index == stream_index
codec.decode(packet) do |frame|
yield frame
end
end
end
end
rescue error : IO::EOFError
codec.decode(nil) do |frame|
yield frame
end
end
ensure
close
Expand Down

0 comments on commit c43617a

Please sign in to comment.