diff options
| author | s-ol <s+removethis@s-ol.nu> | 2025-10-22 16:57:45 +0000 |
|---|---|---|
| committer | s-ol <s+removethis@s-ol.nu> | 2025-10-22 16:57:45 +0000 |
| commit | 90a836553f58375278c82b1369bc5a20c778b078 (patch) | |
| tree | 0e5b8dc945029e681230783362668989dbf8ca2b /src | |
| parent | update for ffmpeg 8 (diff) | |
| download | glsl-view-90a836553f58375278c82b1369bc5a20c778b078.tar.gz glsl-view-90a836553f58375278c82b1369bc5a20c778b078.zip | |
Stream*Source: rewind on EOF
Diffstat (limited to 'src')
| -rw-r--r-- | src/ffmpeg.zig | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/src/ffmpeg.zig b/src/ffmpeg.zig index a856f54..71c214b 100644 --- a/src/ffmpeg.zig +++ b/src/ffmpeg.zig @@ -96,6 +96,11 @@ pub const Decoder = struct { } } + pub fn rewind(self: *Decoder, format: *c.AVFormatContext, stream_index: i32) !void { + try check(c.avformat_seek_file(format, stream_index, 0, 0, 0, 0)); + if (self.reset_fn) |reset_fn| reset_fn(self); + } + pub fn createTexture( self: *Decoder, outer_progress: std.Progress.Node, @@ -371,7 +376,7 @@ pub const StreamSource = struct { .thread = undefined, }; - try self.update(); + _ = try self.update(); self.thread = try gl.Thread.init(allocator, constants, update_loop, .{self}); return &self.source; @@ -388,20 +393,27 @@ pub const StreamSource = struct { fn update_loop(self: *StreamSource) !void { while (!self.thread.quit) { - try self.update(); + const more = try self.update(); + if (!more) { + try self.decoder.rewind(self.format, self.stream); + _ = try self.update(); + } + c.glFlush(); try std.Thread.yield(); } } - fn update(self: *StreamSource) !void { - try check(c.av_read_frame(self.format, self.packet)); + fn update(self: *StreamSource) !bool { + const res = c.av_read_frame(self.format, self.packet); + if (res == c.AVERROR_EOF) return false; + try check(res); defer c.av_packet_unref(self.packet); - if (self.packet.*.stream_index != self.stream) return; + if (self.packet.*.stream_index != self.stream) return true; self.decoder.num_frames = 0; - _ = try self.decoder.process_packet_fn( + return try self.decoder.process_packet_fn( self.decoder, self.packet, if (self.flags.shouldStep()) &self.source.texture else null, @@ -492,7 +504,7 @@ pub const BufferedStreamSource = struct { .thread = undefined, }; - try self.update(); + _ = try self.update(); self.thread = try gl.Thread.init(allocator, constants, update_loop, .{self}); return &self.source; @@ -523,24 +535,32 @@ pub const BufferedStreamSource = struct { fn update_loop(self: *BufferedStreamSource) !void { while (!self.thread.quit) { - try self.update(); + const more = try self.update(); + if (!more) { + try self.decoder.rewind(self.format, self.stream); + _ = try self.update(); + } + c.glFlush(); try std.Thread.yield(); } } - fn update(self: *BufferedStreamSource) !void { - try check(c.av_read_frame(self.format, self.packet)); + fn update(self: *BufferedStreamSource) !bool { + const res = c.av_read_frame(self.format, self.packet); + if (res == c.AVERROR_EOF) return false; + try check(res); defer c.av_packet_unref(self.packet); - if (self.packet.*.stream_index != self.stream) return; + if (self.packet.*.stream_index != self.stream) return true; - _ = try self.decoder.process_packet_fn( + const more = try self.decoder.process_packet_fn( self.decoder, self.packet, if (self.flags.shouldStep()) &self.source.texture else null, ); self.decoder.num_frames = @rem(self.decoder.num_frames, self.depth); + return more; } fn deinit(source: *src.Source, allocator: std.mem.Allocator) void { |
