diff options
Diffstat (limited to 'src/video/ffmpeg.zig')
| -rw-r--r-- | src/video/ffmpeg.zig | 126 |
1 files changed, 0 insertions, 126 deletions
diff --git a/src/video/ffmpeg.zig b/src/video/ffmpeg.zig deleted file mode 100644 index 03456d5..0000000 --- a/src/video/ffmpeg.zig +++ /dev/null @@ -1,126 +0,0 @@ -const std = @import("std"); -const c = @import("../c.zig"); -const gl = @import("../gl.zig"); -const build_config = @import("build_config"); -const dec = @import("decoder.zig"); - -const check = dec.check; - -pub const AVDecoder = struct { - decoder: dec.Decoder, - - sws_ctx: *c.SwsContext, - codec_par: c.AVCodecParameters, - codec_ctx: [*c]c.AVCodecContext, - - raw_frame: [*c]c.AVFrame, - rgba_frame: [*c]c.AVFrame, - - pub fn init(allocator: std.mem.Allocator, codec_par: c.AVCodecParameters) dec.Errors!*dec.Decoder { - const self = try allocator.create(AVDecoder); - errdefer allocator.destroy(self); - - const codec = c.avcodec_find_decoder(codec_par.codec_id) orelse return error.UnsupportedCodec; - - var codec_ctx = c.avcodec_alloc_context3(codec) orelse return error.AVAllocationError; - errdefer c.avcodec_free_context(&codec_ctx); - var raw_frame = c.av_frame_alloc() orelse return error.AVAllocationError; - errdefer c.av_frame_free(&raw_frame); - var rgba_frame = c.av_frame_alloc() orelse return error.AVAllocationError; - errdefer c.av_frame_free(&rgba_frame); - - try check(c.avcodec_parameters_to_context(codec_ctx, &codec_par)); - try check(c.avcodec_open2(codec_ctx, codec, null)); - errdefer check(c.avcodec_close(codec_ctx)) catch unreachable; - - const sws_ctx = c.sws_getContext( - codec_par.width, - codec_par.height, - codec_par.format, - codec_par.width, - codec_par.height, - c.AV_PIX_FMT_RGBA, - c.SWS_POINT, - null, - null, - 0, - ) orelse return error.AVGenericError; - errdefer c.sws_freeContext(sws_ctx); - - self.* = .{ - .decoder = .{ - .process_packet_fn = processPacket, - .init_texture_fn = initTexture, - .reset_fn = reset, - .deinit_fn = deinit, - .num_frames = 0, - }, - .sws_ctx = sws_ctx, - .codec_par = codec_par, - .codec_ctx = codec_ctx, - .raw_frame = raw_frame, - .rgba_frame = rgba_frame, - }; - return &self.decoder; - } - - pub fn deinit(decoder: *dec.Decoder, allocator: std.mem.Allocator) void { - const self: *AVDecoder = @fieldParentPtr("decoder", decoder); - - const raw_ptr: [*c][*c]c.AVFrame = &self.raw_frame; - const rgba_ptr: [*c][*c]c.AVFrame = &self.rgba_frame; - c.av_frame_free(raw_ptr); - c.av_frame_free(rgba_ptr); - - c.sws_freeContext(self.sws_ctx); - check(c.avcodec_close(self.codec_ctx)) catch unreachable; - c.avcodec_free_context(&self.codec_ctx); - - allocator.destroy(self); - } - - pub fn reset(decoder: *dec.Decoder) void { - const self: *AVDecoder = @fieldParentPtr("decoder", decoder); - c.avcodec_flush_buffers(self.codec_ctx); - } - - pub fn initTexture(decoder: *dec.Decoder, texture: *const gl.Texture) void { - const self: *AVDecoder = @fieldParentPtr("decoder", decoder); - - texture.allocate( - self.codec_par.width, - self.codec_par.height, - self.decoder.num_frames, - c.GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, - ); - } - - pub fn processPacket(decoder: *dec.Decoder, packet: *c.AVPacket, texture: ?*const gl.Texture) dec.Errors!bool { - const self: *AVDecoder = @fieldParentPtr("decoder", decoder); - - try check(c.avcodec_send_packet(self.codec_ctx, packet)); - while (true) { - const ires = c.avcodec_receive_frame(self.codec_ctx, self.raw_frame); - if (ires == c.AVERROR_EOF) return false; - if (ires == c.AVERROR(c.EAGAIN)) return true; - try check(ires); - try check(c.sws_scale_frame(self.sws_ctx, self.rgba_frame, self.raw_frame)); - - c.glPixelStorei(c.GL_UNPACK_ROW_LENGTH, @divFloor(self.rgba_frame.*.linesize[0], @sizeOf(u8) * 4)); - - if (texture) |tex| { - tex.setLayer( - self.rgba_frame.*.width, - self.rgba_frame.*.height, - self.decoder.num_frames, - c.GL_RGBA, - self.rgba_frame.*.data[0], - ); - - if (tex.type == .TEXTURE_2D) return false; - } - - self.decoder.num_frames += 1; - } - } -}; |
