ffi-ffmpeg 0.5.8135c9c5dc36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.hgignore ADDED
@@ -0,0 +1,10 @@
1
+ syntax: glob
2
+ *.gem
3
+ .bundle
4
+ Gemfire.lock
5
+ pkg/*
6
+
7
+ *.png
8
+ .*.sw[a-z]
9
+ .AppleDouble
10
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in ffi-ffmpeg.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,70 @@
1
+ ffi-ffmpeg
2
+ ==========
3
+ http://github.com/dmlary/ffi-ffmpeg
4
+
5
+ Description
6
+ -----------
7
+ Ruby-FFI bindings and wrappers for FFmpeg libraries.
8
+
9
+ Features
10
+ --------
11
+ Right now this library only supports the reading of video streams.
12
+
13
+ What's missing
14
+ --------------
15
+ * Reading audio streams
16
+ * Execute ffmpeg cleanup when Reader, Stream, Frame instances are gc'ed
17
+ * Encoding
18
+
19
+ Usage
20
+ -----
21
+ ruby
22
+ require 'ffi-ffmpeg'
23
+
24
+ # Allocate a reader for our video file
25
+ reader = FFmpeg::Reader.new(ARGV[0], :pixel_format => :rgb24)
26
+
27
+ # Dump the format information for the file
28
+ reader.dump_format
29
+
30
+ # Grab the first video stream in the file
31
+ stream = reader.streams.select { |s| s.type == :video }.first
32
+
33
+ # Discard non-key frames
34
+ stream.discard = :nonkey
35
+
36
+ # Loop through the key frames for the first video stream
37
+ stream.each_frame do |frame|
38
+ # Do something interesting with the frame...
39
+ # pixel data is in frame.av_frame[:data]
40
+ end
41
+
42
+
43
+ Copyright
44
+ ---------
45
+ Copyright (c) 2011, David M. Lary
46
+ All rights reserved.
47
+
48
+ License
49
+ -------
50
+ Redistribution and use in source and binary forms, with or without
51
+ modification, are permitted provided that the following conditions are met:
52
+
53
+ * Redistributions of source code must retain the above copyright
54
+ notice, this list of conditions and the following disclaimer.
55
+ * Redistributions in binary form must reproduce the above copyright
56
+ notice, this list of conditions and the following disclaimer in the
57
+ documentation and/or other materials provided with the distribution.
58
+ * The name of the author may not be used to endorse or promote products
59
+ derived from this software without specific prior written permission.
60
+
61
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
62
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
63
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
64
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
65
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
66
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
67
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
68
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
69
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
70
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
4
+ require 'ffi-ffmpeg'
5
+
6
+ def write_frame(filename, frame)
7
+ file = File.new(filename, "w")
8
+ file.write "P6\n%d %d\n255\n" % [frame.width, frame.height]
9
+
10
+ data = frame.av_frame[:data][0]
11
+ linesize = frame.av_frame[:linesize][0]
12
+ bytes_per_row = 3 * frame.width
13
+
14
+ frame.height.times do |row|
15
+ file.write data.slice(row * linesize, bytes_per_row)\
16
+ .read_string_length(bytes_per_row)
17
+ end
18
+ file.close
19
+ end
20
+
21
+ # Open our video file
22
+ reader = FFmpeg::Reader.new(ARGV[0], :pixel_format => :rgb24)
23
+
24
+ reader.dump_format
25
+ # Find the first video stream
26
+ stream = reader.streams.select { |s| s.discard = :all; s.type == :video } .first
27
+
28
+ # Tell the library to discard all non-key frames
29
+ stream.discard = :nonkey
30
+
31
+ # Write the first five key frames to disk
32
+ 5.times do |i|
33
+ frame = stream.next_frame
34
+ write_frame("image-%d.ppm" % i, frame)
35
+ puts "wrote frame %d" % frame.number
36
+ end
37
+
38
+ stream.pixel_format = :gray8
39
+
40
+ # Write the first five key frames to disk
41
+ 5.times do |i|
42
+ frame = stream.next_frame
43
+ scaled = frame.scale(:width => 100, :height => 100, :pixel_format => :rgb24)
44
+ write_frame("small-%d.ppm" % i, scaled)
45
+ puts "wrote small frame %d" % scaled.number
46
+ end
47
+
@@ -0,0 +1,46 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
4
+ require 'ffi-ffmpeg'
5
+ require 'pp'
6
+
7
+ def format_seconds(s)
8
+ s = s.to_i
9
+ h = s/3600
10
+ s -= h * 3600
11
+ m = s/60
12
+ s -= m * 60
13
+ "%02d:%02d:%02d" % [ h, m, s ]
14
+ end
15
+
16
+ GLYPHS = %w{ | / - \\ }
17
+ @first = nil
18
+ @last = nil
19
+ @calls = 0
20
+ def spin(frame)
21
+ now = Time.now()
22
+ @first ||= now
23
+ @last ||= now
24
+
25
+ @calls += 1
26
+
27
+ if (@last + 0.25 < now)
28
+ fps = @calls.to_f / (now - @first)
29
+ pos = frame.number / frame.stream.fps.to_f
30
+ printf("\r[%s] %0.03f fps, frame: %d, pos: %s",
31
+ format_seconds(now - @first), fps, frame.number,
32
+ format_seconds(pos))
33
+ @last = now
34
+ end
35
+ end
36
+
37
+ # open our video file
38
+ reader = FFmpeg::Reader.new(ARGV[0])
39
+ reader.dump_format
40
+
41
+ # Find the first video stream
42
+ reader.streams.each { |s| s.discard == :all }
43
+ stream = reader.default_stream
44
+ stream.discard = :default
45
+ # stream.buffer_size = 2
46
+ stream.each_frame { |frame| spin frame}
data/examples/seek.rb ADDED
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pp'
4
+ $: << File.join(File.dirname(__FILE__), "..", "lib")
5
+ require 'ffi-ffmpeg'
6
+
7
+ def write_frame(filename, frame)
8
+ file = File.new(filename, "w")
9
+ file.write "P6\n%d %d\n255\n" % [frame.width, frame.height]
10
+
11
+ data = frame.av_frame[:data][0]
12
+ linesize = frame.av_frame[:linesize][0]
13
+ bytes_per_row = 3 * frame.width
14
+
15
+ frame.height.times do |row|
16
+ file.write data.slice(row * linesize, bytes_per_row)\
17
+ .read_string_length(bytes_per_row)
18
+ end
19
+ file.close
20
+ end
21
+
22
+ # Open our video file
23
+ reader = FFmpeg::Reader.new(ARGV[0], :pixel_format => :rgb24)
24
+ stream = reader.default_stream
25
+
26
+ # Find the first video stream
27
+ reader.streams.each { |s| s.discard = :all unless s == stream }
28
+ stream.discard = :nonkey
29
+
30
+ count = ARGV[1] ? ARGV[1].to_i : 10
31
+ step = File.size(ARGV[0]) / (count + 2)
32
+
33
+ count.times do |i|
34
+ i += 1
35
+ puts "Seeking to %d" % (i * step)
36
+ stream.seek(:pos => i * step)
37
+
38
+ frame = stream.next_frame
39
+
40
+ # For some reason, when working on MPEG-TS files, following the seek,
41
+ # the packet DTS of the next packet read is -1 * AV_NOPTS_VALUE. When
42
+ # we save that frame it looks like a stale buffer. So we want to skip
43
+ # the frame if the pts is this value. Also only accept key frames.
44
+ until frame.key_frame? and frame.pts != -1 * FFI::FFmpeg::AV_NOPTS_VALUE
45
+ frame = stream.next_frame
46
+ end
47
+ puts "Saving frame %d, pts %d" % [ frame.number, frame.pts ]
48
+ write_frame("seek-%02d.ppm" % i, frame)
49
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "ffi-ffmpeg"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "ffi-ffmpeg"
7
+ s.version = "%s.%s" % [ FFmpeg::VERSION,
8
+ `hg id -i`.chomp.sub("+", "m") ]
9
+ s.authors = ["David M. Lary"]
10
+ s.email = ["dmlary@gmail.com"]
11
+ s.homepage = "http://bitbucket.com/dmlary/ffi-ffmpeg"
12
+ s.summary = %q{Ruby FFI bindings for FFmpeg libraries}
13
+ s.description = %q{Ruby FFI bindings for FFmpeg libraries:
14
+ * libavformat
15
+ * libavcodec
16
+ * libavutil
17
+ * libswscale}
18
+
19
+ s.rubyforge_project = "ffi-ffmpeg"
20
+
21
+ s.files = `hg locate`.split("\n")
22
+ s.test_files = `hg locate -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `hg locate -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+ s.add_dependency "ffi"
26
+ end
data/lib/ffi-ffmpeg.rb ADDED
@@ -0,0 +1,30 @@
1
+ require "ffi/ffmpeg"
2
+ require "ffmpeg/version"
3
+ require "ffmpeg/frame"
4
+ require "ffmpeg/stream"
5
+ require "ffmpeg/reader"
6
+
7
+ module FFmpeg
8
+
9
+ # Get the logging level
10
+ def self.log_level
11
+ FFI::FFmpeg.av_log_get_level
12
+ end
13
+
14
+ # Set the logging level
15
+ #
16
+ # [:level] Logging level in FFI::FFMpeg::AVLogLevel
17
+ #
18
+ def self.log_level=(level)
19
+ FFI::FFmpeg.av_log_set_level level
20
+ end
21
+
22
+ private
23
+
24
+ @@registered_all = false
25
+ def self.register_all
26
+ return if @@registered_all
27
+ FFI::FFmpeg.av_register_all
28
+ @@registered_all = true
29
+ end
30
+ end
data/lib/ffi/ffmpeg.rb ADDED
@@ -0,0 +1,629 @@
1
+ require 'ffi'
2
+
3
+ module FFI
4
+ module FFmpeg
5
+ extend FFI::Library
6
+
7
+ AV_NOPTS_VALUE = 0x8000000000000000
8
+
9
+ ffi_lib "libavutil.so.49"
10
+
11
+ AVMediaType = enum :unknown, -1,
12
+ :video,
13
+ :audio,
14
+ :data,
15
+ :subtitle,
16
+ :attachment
17
+
18
+ BIG_ENDIAN = [1].pack("I") == [1].pack("N")
19
+ PixelFormat = enum :none, -1,
20
+ :yuv420p,
21
+ :yuyv422,
22
+ :rgb24,
23
+ :bgr24,
24
+ :yuv422p,
25
+ :yuv444p,
26
+ :yuv410p,
27
+ :yuv411p,
28
+ :gray8,
29
+ :monowhite,
30
+ :monoblack,
31
+ :pal8,
32
+ :yuvj420p,
33
+ :yuvj422p,
34
+ :yuvj444p,
35
+ :xvmc_mpeg2_mc,
36
+ :xvmc_mpeg2_idct,
37
+ :uyvy422,
38
+ :uyyvyy411,
39
+ :bgr8,
40
+ :bgr4,
41
+ :bgr4_byte,
42
+ :rgb8,
43
+ :rgb4,
44
+ :rgb4_byte,
45
+ :nv12,
46
+ :nv21,
47
+ BIG_ENDIAN ? :rgb32 : :bgr32_1, # :argb
48
+ BIG_ENDIAN ? :rgb32_1 : :bgr32, # :rgba
49
+ BIG_ENDIAN ? :bgr32 : :rgb32_1, # :abgr
50
+ BIG_ENDIAN ? :bgr32_1 : :rgb32, # :bgra
51
+ BIG_ENDIAN ? :gray16 : :gray16_1, # :gray16be
52
+ BIG_ENDIAN ? :gray16_1 : :gray16, # :gray16le
53
+ :yuv440p,
54
+ :yuvj440p,
55
+ :yuva420p,
56
+ :vdpau_h264,
57
+ :vdpau_mpeg1,
58
+ :vdpau_mpeg2,
59
+ :vdpau_wmv3,
60
+ :vdpau_vc1,
61
+ BIG_ENDIAN ? :rgb48 : :rgb48_1, # :rgb48be
62
+ BIG_ENDIAN ? :rgb48_1 : :rgb48, # :rgb48le
63
+ BIG_ENDIAN ? :rgb565 : :rgb565_1, # :rgb565be
64
+ BIG_ENDIAN ? :rgb565_1 : :rgb565, # :rgb565le
65
+ BIG_ENDIAN ? :rgb555 : :rgb555_1, # :rgb555be
66
+ BIG_ENDIAN ? :rgb555_1 : :rgb555, # :rgb555le
67
+ BIG_ENDIAN ? :bgr565 : :bgr565_1, # :bgr565be
68
+ BIG_ENDIAN ? :bgr565_1 : :bgr565, # :bgr565le
69
+ BIG_ENDIAN ? :bgr555 : :bgr555_1, # :bgr555be
70
+ BIG_ENDIAN ? :bgr555_1 : :bgr555, # :bgr555le
71
+ :vaapi_moco,
72
+ :vaapi_idct,
73
+ :vaapi_vld,
74
+ BIG_ENDIAN ? :yuv420p16_1 : :yuv420p16, # :yuv420p16le
75
+ BIG_ENDIAN ? :yuv420p16 : :yuv420p16_1, # :yuv420p16be
76
+ BIG_ENDIAN ? :yuv422p16_1 : :yuv422p16, # :yuv422p16le
77
+ BIG_ENDIAN ? :yuv422p16 : :yuv422p16_1, # :yuv422p16be
78
+ BIG_ENDIAN ? :yuv444p16_1 : :yuv444p16, # :yuv444p16le
79
+ BIG_ENDIAN ? :yuv444p16 : :yuv444p16_1, # :yuv444p16be
80
+ :vdpau_mpeg4,
81
+ :dxva2_vld,
82
+ BIG_ENDIAN ? :rgb444 : :rgb444_1, # :rgb444be
83
+ BIG_ENDIAN ? :rgb444_1 : :rgb444, # :rgb444le
84
+ BIG_ENDIAN ? :bgr444 : :bgr444_1, # :bgr444be
85
+ BIG_ENDIAN ? :bgr444_1 : :bgr444, # :bgr444le
86
+ :y400a
87
+
88
+ # Not actually an enum in libavutil.h, but we make it one here to
89
+ # make the api prettier.
90
+ AVLogLevel = enum :quiet, -8,
91
+ :panic, 0,
92
+ :fatal, 8,
93
+ :error, 16,
94
+ :warning, 24,
95
+ :info, 32,
96
+ :verbose, 40,
97
+ :debug, 48
98
+
99
+ attach_function :av_log_get_level, [], AVLogLevel
100
+ attach_function :av_log_set_level, [AVLogLevel], :void
101
+ attach_function :av_free, [:pointer], :void
102
+ attach_function :av_malloc, [:uint], :pointer
103
+
104
+ ffi_lib "libavformat.so.52"
105
+
106
+ MAX_STREAMS = 20
107
+ MAX_REORDER_DELAY = 16
108
+
109
+ AVSEEK_FLAG_BACKWARD = 1
110
+ AVSEEK_FLAG_BYTE = 2
111
+ AVSEEK_FLAG_ANY = 4
112
+
113
+ attach_function :av_register_all, [], :void
114
+ attach_function :av_open_input_file,
115
+ [:pointer, :string, :pointer, :int, :pointer],
116
+ :int
117
+ attach_function :av_find_stream_info, [:pointer], :int
118
+ attach_function :dump_format,
119
+ [:pointer, :int, :string, :int],
120
+ :void
121
+ attach_function :av_read_frame, [:pointer, :pointer], :int
122
+ attach_function :av_seek_frame, [:pointer, :int, :long_long, :int], :int
123
+ attach_function :av_find_default_stream_index, [ :pointer ], :int
124
+
125
+ # Defining this manually since it's a static inline:
126
+ #
127
+ # static inline void av_free_packet(AVPacket *pkt)
128
+ # {
129
+ # if (pkt && pkt->destruct) {
130
+ # pkt->destruct(pkt);
131
+ # }
132
+ # }
133
+ #
134
+ def self.av_free_packet(pkt)
135
+ return unless pkt and pkt[:destruct]
136
+
137
+ FFI::Function.new(:void, [:pointer], pkt[:destruct],
138
+ :blocking => true).call(pkt)
139
+ end
140
+
141
+ def av_free_packet(pkt)
142
+ FFI::FFmpeg.av_free_packet(pkt)
143
+ end
144
+
145
+ ffi_lib "libavcodec.so.52"
146
+ AV_PARSER_PTS_NB = 4
147
+
148
+ AVDiscard = enum :none, -16,
149
+ :default, 0,
150
+ :nonref, 8,
151
+ :bidir, 16,
152
+ :nonkey, 32,
153
+ :all, 48
154
+
155
+ attach_function :avcodec_find_decoder, [:int], :pointer
156
+ attach_function :avcodec_open, [:pointer, :pointer], :int
157
+ attach_function :avcodec_alloc_frame, [], :pointer
158
+ attach_function :avpicture_get_size, [PixelFormat, :int, :int], :int
159
+ attach_function :avpicture_fill,
160
+ [:pointer, :pointer, PixelFormat, :int, :int],
161
+ :int
162
+ attach_function :avcodec_decode_video, [:pointer, :pointer, :pointer,
163
+ :pointer, :int], :int,
164
+ { :blocking => true }
165
+ attach_function :avcodec_default_get_buffer, [:pointer, :pointer], :int
166
+ attach_function :avcodec_default_release_buffer, [:pointer, :pointer], :int
167
+
168
+ ffi_lib "libswscale.so.0"
169
+ SWScaleFlags = enum :fast_bilinear, 0x001,
170
+ :bilinear, 0x002,
171
+ :bicubic, 0x004,
172
+ :x, 0x008,
173
+ :point, 0x010,
174
+ :area, 0x020,
175
+ :bicublin, 0x040,
176
+ :gauss, 0x080,
177
+ :sinc, 0x100,
178
+ :lanczos, 0x200,
179
+ :spline, 0x400
180
+
181
+ attach_function :sws_getContext,
182
+ [:int, :int, PixelFormat, :int, :int, PixelFormat,
183
+ SWScaleFlags, :pointer, :pointer, :pointer],
184
+ :pointer
185
+ attach_function :sws_freeContext,
186
+ [:pointer],
187
+ :void
188
+ attach_function :sws_scale,
189
+ [:pointer, :pointer, :pointer, :int,
190
+ :int, :pointer, :pointer],
191
+ :int,
192
+ { :blocking => true }
193
+
194
+
195
+ class AVRational < FFI::Struct
196
+ layout :num, :int,
197
+ :den, :int
198
+
199
+ def to_f
200
+ self[:num].to_f / self[:den]
201
+ end
202
+
203
+ def to_float
204
+ to_f
205
+ end
206
+
207
+ def to_i
208
+ self[:num] / self[:den]
209
+ end
210
+
211
+ def to_s
212
+ "#<AVRational:0x%016x num=%d, den=%d, %f>" %
213
+ [object_id, self[:num], self[:den], to_f]
214
+ end
215
+ end
216
+
217
+ class AVFrac < FFI::Struct
218
+ layout :val, :long_long,
219
+ :num, :long_long,
220
+ :den, :long_long
221
+
222
+ def to_f
223
+ self[:val] + self[:num].to_f / self[:den]
224
+ end
225
+
226
+ def to_i
227
+ self[:val] + self[:num] / self[:den]
228
+ end
229
+
230
+ def to_s
231
+ "#<AVRational:0x%016x val=%d, num=%d, den=%d, %f>" %
232
+ [object_id, self[:val], self[:num], self[:den], to_f]
233
+ end
234
+ end
235
+
236
+ class AVProbeData < FFI::Struct
237
+ layout :filename, :string,
238
+ :buf, :pointer,
239
+ :buf_size, :int
240
+ end
241
+
242
+ class AVPacket < FFI::Struct
243
+ layout :pts, :long,
244
+ :dts, :long,
245
+ :data, :pointer,
246
+ :size, :int,
247
+ :stream_index, :int,
248
+ :flags, :int,
249
+ :duration, :int,
250
+ :destruct, :pointer,
251
+ :priv, :pointer,
252
+ :pos, :long,
253
+ :convergence_duration, :long
254
+ end
255
+
256
+ class AVPacketList < FFI::Struct
257
+ layout :pkt, AVPacket,
258
+ :next, :pointer
259
+ end
260
+
261
+ class AVStream < FFI::Struct
262
+ layout :index, :int,
263
+ :id, :int,
264
+ :codec, :pointer,
265
+ :r_frame_rate, AVRational,
266
+ :priv_data, :pointer,
267
+ :first_dts, :long_long,
268
+ :pts, AVFrac,
269
+ :time_base, AVRational,
270
+ :pts_wrap_bits, :int,
271
+ :stream_copy, :int,
272
+ :discard, AVDiscard,
273
+ :quality, :float,
274
+ :start_time, :long_long,
275
+ :duration, :long_long,
276
+ :language, [:char, 4],
277
+ :need_parsing, :int, # enum AVStreamParseType,
278
+ :parser, :pointer,
279
+ :cur_dts, :long_long,
280
+ :last_IP_duration, :int,
281
+ :last_IP_pts, :long_long,
282
+ :index_entries, :pointer,
283
+ :nb_index_entries, :int,
284
+ :index_entries_allocated_size, :uint,
285
+ :nb_frames, :long_long,
286
+ :unused, [:long_long, 5],
287
+ :filename, :string,
288
+ :disposition, :int,
289
+ :probe_data, AVProbeData,
290
+ :pts_buffer, [:long_long, MAX_REORDER_DELAY + 1],
291
+ :sample_aspect_ratio, AVRational,
292
+ :metadata, :pointer,
293
+ :cur_ptr, :pointer,
294
+ :cur_len, :int,
295
+ :cur_pkt, AVPacket,
296
+ :reference_dts, :long_long,
297
+ :probe_packets, :int,
298
+ :last_in_packet_butter, AVPacketList,
299
+ :avg_frame_rate, AVRational,
300
+ :codec_info_nb_frames, :int
301
+
302
+ def codec
303
+ AVCodecContext.new send(:[], :codec)
304
+ end
305
+
306
+ def to_s
307
+ '#<AVStream:0x%08x index=%d, id=%d, codec_type=:%s>' %
308
+ [ object_id, self[:index], self[:id], codec[:codec_type] ]
309
+ end
310
+
311
+ def discard=(type)
312
+ send(:[]=, :discard, type)
313
+ end
314
+ end
315
+
316
+ callback :av_codec_context_get_buffer, [:pointer, :pointer], :int
317
+
318
+ class AVCodecContext < FFI::Struct
319
+ layout :av_class, :pointer,
320
+ :bit_rate, :int,
321
+ :bit_rate_rolerance, :int,
322
+ :flags, :int,
323
+ :sub_id, :int,
324
+ :me_method, :int,
325
+ :extradata, :pointer,
326
+ :extradata_size, :int,
327
+ :time_base, AVRational,
328
+ :width, :int,
329
+ :height, :int,
330
+ :gop_size, :int,
331
+ :pix_fmt, PixelFormat,
332
+ :rate_emu, :int,
333
+ :draw_horiz_band, :pointer,
334
+ :sample_rate, :int,
335
+ :channels, :int,
336
+ :sample_fmt, :int, # TODO enum SampleFormat
337
+ :frame_size, :int,
338
+ :frame_number, :int,
339
+ :real_pict_num, :int,
340
+ :delay, :int,
341
+ :qcompress, :float,
342
+ :qblur, :float,
343
+ :qmin, :int,
344
+ :qmax, :int,
345
+ :max_qdiff, :int,
346
+ :max_b_frames, :int,
347
+ :b_quant_factor, :float,
348
+ :rc_strategy, :int,
349
+ :b_frame_strategy, :int,
350
+ :hurry_up, :int,
351
+ :codec, :pointer,
352
+ :priv_data, :pointer,
353
+ :rtp_payload_size, :int,
354
+ :rtp_callback, :pointer,
355
+ :mv_bits, :int,
356
+ :header_bits, :int,
357
+ :i_tex_bits, :int,
358
+ :p_tex_bits, :int,
359
+ :i_count, :int,
360
+ :p_count, :int,
361
+ :skip_count, :int,
362
+ :misc_bits, :int,
363
+ :frame_bits, :int,
364
+ :opaque, :pointer,
365
+ :codec_name, [:char, 32],
366
+ :codec_type, AVMediaType,
367
+ :codec_id, :int, # TODO enum CodecID
368
+ :codec_tag, :uint,
369
+ :workaround_bugs, :int,
370
+ :luma_elim_threshold, :int,
371
+ :chroma_elim_threshold, :int,
372
+ :strict_std_compliance, :int,
373
+ :b_quant_offset, :float,
374
+ :error_recognition, :int,
375
+ :get_buffer, :av_codec_context_get_buffer,
376
+ :release_buffer, :pointer,
377
+ :has_b_frames, :int,
378
+ :block_align, :int,
379
+ :parse_only, :int,
380
+ :mpeg_quant, :int,
381
+ :stats_out, :pointer,
382
+ :stats_in, :pointer,
383
+ :rc_qsquish, :float,
384
+ :rc_qmod_amp, :float,
385
+ :rc_qmod_freq, :int,
386
+ :rc_override, :pointer,
387
+ :rc_override_count, :int,
388
+ :rc_eq, :pointer,
389
+ :rc_max_rate, :int,
390
+ :rc_min_rate, :int,
391
+ :rc_buffer_size, :int,
392
+ :rc_buffer_aggressivity, :float,
393
+ :i_quant_factor, :float,
394
+ :i_quant_offset, :float,
395
+ :rc_initial_cplx, :float,
396
+ :dct_algo, :int,
397
+ :lumi_masking, :float,
398
+ :temporal_cplx_masking, :float,
399
+ :spatial_cplx_masking, :float,
400
+ :p_masking, :float,
401
+ :dark_masking, :float,
402
+ :idct_algo, :int,
403
+ :splice_count, :int,
404
+ :slice_offset, :pointer,
405
+ :error_concealment, :int,
406
+ :dsp_mask, :uint,
407
+ :bits_per_coded_sample, :int,
408
+ :prediction_method, :int,
409
+ :sample_aspect_ratio, AVRational,
410
+ :coded_frame, :pointer,
411
+ :debug, :int,
412
+ :debug_mv, :int,
413
+ :error, [:ulong_long, 4],
414
+ :mb_qmin, :int,
415
+ :mb_qmax, :int,
416
+ :me_cmp, :int,
417
+ :me_sub_cmp, :int,
418
+ :ildct_cmp, :int,
419
+ :dia_size, :int,
420
+ :last_predictor_count, :int,
421
+ :pre_me, :int,
422
+ :me_pre_cmp, :int,
423
+ :pre_dia_size, :int,
424
+ :me_subpel_quality, :int,
425
+ :get_format, :pointer,
426
+ :dtg_active_format, :int,
427
+ :me_range, :int,
428
+ :intra_quant_bias, :int,
429
+ :inter_quant_bias, :int,
430
+ :color_table_id, :int,
431
+ :internal_buffer_count, :int,
432
+ :internal_buffer, :pointer,
433
+ :global_quality, :int,
434
+ :coder_type, :int,
435
+ :context_model, :int,
436
+ :slice_flags, :int,
437
+ :xvmc_acceleration, :int,
438
+ :mb_decision, :int,
439
+ :intra_matrix, :pointer,
440
+ :inter_matrix, :pointer,
441
+ :stream_codec_tag, :int,
442
+ :scenechange_threshold, :int,
443
+ :lmin, :int,
444
+ :lmax, :int,
445
+ :palctrl, :pointer,
446
+ :noise_reduction, :int,
447
+ :reget_buffer, :pointer,
448
+ :rc_initial_buffer_occupancy, :int,
449
+ :inter_threshold, :int,
450
+ :flags2, :int,
451
+ :error_rate, :int,
452
+ :antialias_algo, :int,
453
+ :quantizer_noise_shaping, :int,
454
+ :thread_count, :int,
455
+ :execute, :pointer,
456
+ :thread_opaque, :pointer,
457
+ :me_threshold, :int,
458
+ :mb_threshold, :int,
459
+ :intra_dc_precision, :int,
460
+ :nsse_weight, :int,
461
+ :skip_top, :int,
462
+ :skip_bottom, :int,
463
+ :profile, :int,
464
+ :level, :int,
465
+ :lowres, :int,
466
+ :coded_width, :int,
467
+ :coded_height, :int,
468
+ :frame_skip_threshold, :int,
469
+ :frame_skip_factor, :int,
470
+ :frame_skip_cmp, :int,
471
+ :border_masking, :float,
472
+ :mb_lmin, :int,
473
+ :mb_lmax, :int,
474
+ :me_penalty_compensation, :int,
475
+ :skip_loop_filter, :int, # TODO enum AVDiscard
476
+ :skip_idct, :int, # TODO enum AVDiscard
477
+ :skip_frame, :int, # TODO enum AVDiscard
478
+ :bidir_refine, :int,
479
+ :brd_scale, :int,
480
+ :crf, :float,
481
+ :cqp, :int,
482
+ :keyint_min, :int,
483
+ :refs, :int,
484
+ :chromaoffset, :int,
485
+ :bframebias, :int,
486
+ :trellis, :int,
487
+ :complexityblur, :float,
488
+ :deblockalpha, :int,
489
+ :deblockbeta, :int,
490
+ :partitions, :int,
491
+ :directpred, :int,
492
+ :cutoff, :int,
493
+ :scenechange_factor, :int,
494
+ :mv0_threshold, :int,
495
+ :b_sensitivity, :int,
496
+ :compression_level, :int,
497
+ :use_lpc, :int,
498
+ :lpc_coeff_precision, :int,
499
+ :min_prediction_order, :int,
500
+ :max_prediction_order, :int,
501
+ :prediction_order_method, :int,
502
+ :min_partition_order, :int,
503
+ :max_partition_order, :int,
504
+ :timecode_frame_start, :long_long,
505
+ :request_channel, :int,
506
+ :drc_scale, :float,
507
+ :reordered_opaque, :long_long,
508
+ :bits_per_raw_sample, :int,
509
+ :channel_layout, :long_long,
510
+ :request_channel_layout, :long_long,
511
+ :rc_max_available_vbv_use, :float,
512
+ :rc_min_vbv_overflow_use, :float,
513
+ :hwaccel, :pointer,
514
+ :ticks_per_frame, :int,
515
+ :hwaccel_context, :pointer,
516
+ :color_primaries, :int, # enum AVColorPrimaries
517
+ :color_trc, :int, # enum AVColorTransferCharacteristic
518
+ :colorspace, :int, # enum AVColorSpace
519
+ :color_range, :int, # enum AVColorRange
520
+ :chroma_sample_location, :int,# enum AVChromaLocation
521
+ :execute2, :pointer,
522
+ :weighted_p_pred, :int,
523
+ :aq_mode, :int,
524
+ :aq_strength, :float,
525
+ :psy_rd, :float,
526
+ :psy_trellis, :float,
527
+ :rc_lookahead, :int
528
+ # LONGEST STRUCTURE EVER!!!!
529
+ end
530
+
531
+ class AVFormatContext < FFI::Struct
532
+ layout :av_class, :pointer,
533
+ :iformat, :pointer,
534
+ :oformat, :pointer,
535
+ :priv_data, :pointer,
536
+ :pb, :pointer,
537
+ :nb_streams, :uint,
538
+ :streams, [:pointer, MAX_STREAMS],
539
+ :filename, [:char, 1024],
540
+ :timestamp, :long_long,
541
+ :title, [:char, 512],
542
+ :author, [:char, 512],
543
+ :copyright, [:char, 512],
544
+ :comment, [:char, 512],
545
+ :album, [:char, 512],
546
+ :year, :int,
547
+ :track, :int,
548
+ :genre, [:char, 32],
549
+ :ctx_flags, :int,
550
+ :packet_buffer, :pointer,
551
+ :start_time, :long_long,
552
+ :duration, :long_long,
553
+ :file_size, :long_long,
554
+ :bitrate, :int,
555
+ :cur_st, :pointer,
556
+ :cur_ptr_deprecated, :pointer,
557
+ :cur_len_deprecated, :int,
558
+ :cur_pkt_deprecated, AVPacket,
559
+ :data_offset, :long_long,
560
+ :index_build, :int,
561
+ :mux_rate, :int,
562
+ :packet_size, :uint,
563
+ :max_delay, :int,
564
+ :loop_output, :int,
565
+ :flags, :int,
566
+ :loop_input, :int,
567
+ :probesize, :uint,
568
+ :max_analyze_diration, :int,
569
+ :key, :pointer,
570
+ :keylen, :int,
571
+ :nb_programs, :uint,
572
+ :programs, :pointer,
573
+ :video_codec_id, :uint, # enum CodecID
574
+ :audio_codec_id, :uint, # enum CodecID
575
+ :subtitle_codec_id, :uint, # enum CodecID
576
+ :max_index_size, :uint,
577
+ :max_picture_buffer, :uint,
578
+ :nb_chapters, :uint,
579
+ :chapters, :pointer,
580
+ :debug, :int,
581
+ :raw_packet_buffer, :pointer,
582
+ :raw_packet_buffer_end, :pointer,
583
+ :packet_buffet_end, :pointer,
584
+ :metadata, :pointer,
585
+ :raw_packet_buffer_remaining_size, :int,
586
+ :start_time_realtime, :long_long
587
+ end
588
+
589
+ class AVPicture < FFI::Struct
590
+ layout :data, [:pointer, 4],
591
+ :linesize, [:int, 4]
592
+ end
593
+
594
+ class AVFrame < FFI::Struct
595
+ layout :data, [:pointer, 4],
596
+ :linesize, [:int, 4],
597
+ :base, [:pointer, 4],
598
+ :key_frame, :int,
599
+ :pict_type, :int,
600
+ :pts, :int64,
601
+ :coded_picture_number, :int,
602
+ :dispay_picture_number, :int,
603
+ :quality, :int,
604
+ :age, :int,
605
+ :reference, :int,
606
+ :qscale_table, :pointer,
607
+ :qstride, :int,
608
+ :mbskip_table, :pointer,
609
+ :motion_val, [:pointer, 2],
610
+ :mb_type, :pointer,
611
+ :motion_subsample_log2, :uint8,
612
+ :opaque, :pointer,
613
+ :error, [:uint64, 4],
614
+ :type, :int,
615
+ :repeat_pict, :int,
616
+ :qscale_type, :int,
617
+ :interlaced_frame, :int,
618
+ :top_field_first, :int,
619
+ :pan_scan, :pointer,
620
+ :palette_has_changed, :int,
621
+ :buffer_hints, :int,
622
+ :dct_coeff, :pointer,
623
+ :ref_index, [:pointer, 2],
624
+ :reordered_opaque, :long_long
625
+ end
626
+
627
+
628
+ end # module FFmpeg
629
+ end # module FFI