ffi-ffmpeg 0.7.0beae74ee3d7 → 0.8.525a2f4a3ce0

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 CHANGED
@@ -5,6 +5,7 @@ Gemfire.lock
5
5
  pkg/*
6
6
 
7
7
  *.png
8
+ *.ppm
8
9
  .*.sw[a-z]
9
10
  .AppleDouble
10
11
  .DS_Store
data/README.md CHANGED
@@ -4,7 +4,7 @@ http://github.com/dmlary/ffi-ffmpeg
4
4
 
5
5
  Description
6
6
  -----------
7
- Ruby-FFI bindings and wrappers for FFmpeg libraries.
7
+ Ruby-FFI bindings and wrappers for FFmpeg libraries, version 0.5.1.
8
8
 
9
9
  Features
10
10
  --------
@@ -16,9 +16,51 @@ What's missing
16
16
  * Execute ffmpeg cleanup when Reader, Stream, Frame instances are gc'ed
17
17
  * Encoding
18
18
 
19
+ OMG, FFmpeg 0.5.1 is so old
20
+ ---------------------------
21
+ While working with ffmpeg in python, I got sick of constantly having to
22
+ build and install a new version ffmpeg from source every time I upgraded
23
+ the ffmpeg wraper. When I decided to write this ruby gem I selected the
24
+ version that was available as a pre-built package for my servers which
25
+ happen to run Ubuntu 10.04 LTS (lucid). This version will not change
26
+ until sometime after the next LTS release (mid-2012 ... that's a lot sooner
27
+ that I expected).
28
+
29
+ Getting 0.5.1 on OS X 10.6
30
+ --------------------------
31
+ You can either download, build and install ffmpeg from source, but it's
32
+ much easier to use macports. To get FFmpeg 0.5.1 via macports, you'll need
33
+ to use an older revision of the port:
34
+
35
+ cd /tmp
36
+ svn co -r 66961 http://svn.macports.org/repository/macports/trunk/dports/multimedia/ffmpeg
37
+ cd ffmpeg
38
+ sudo port install
39
+
40
+ This may fail while building some of the documentation for ffmpeg. If it
41
+ does fail, you can edit the top-level Makefile in the work directory and
42
+ remove the html document targets:
43
+
44
+ --- Makefile 2011-11-20 21:42:28.000000000 -0600
45
+ +++ Makefile 2011-11-20 21:42:34.000000000 -0600
46
+ @@ -113,9 +113,7 @@
47
+ VHOOK_DEPS = $(HOOKS:$(SLIBSUF)=.d)
48
+ depend dep: $(VHOOK_DEPS)
49
+
50
+ -documentation: $(addprefix doc/, ffmpeg-doc.html faq.html ffserver-doc.html \
51
+ - ffplay-doc.html general.html hooks.html \
52
+ - $(ALLMANPAGES))
53
+ +documentation: $(addprefix doc/, $(ALLMANPAGES))
54
+
55
+ doc/%.html: doc/%.texi
56
+ texi2html -monolithic -number $<
57
+
58
+ You may also need to set your DYLD_LIBRARY_PATH to point at /opt/local/lib
59
+ for dlopen() to be able to find the macports compiled libraries.
60
+
19
61
  Usage
20
62
  -----
21
- ruby
63
+
22
64
  require 'ffi-ffmpeg'
23
65
 
24
66
  # Allocate a reader for our video file
@@ -1,12 +1,58 @@
1
1
  require 'ffi'
2
+ require 'rbconfig'
3
+ require 'dl'
2
4
 
3
5
  module FFI
4
6
  module FFmpeg
5
7
  extend FFI::Library
6
8
 
7
- AV_NOPTS_VALUE = 0x8000000000000000
9
+ LIBRARY_FILENAME = {
10
+ :avutil => ENV['FFI_FFMPEG_LIBAVUTIL'],
11
+ :avformat => ENV['FFI_FFMPEG_LIBAVFORMAT'],
12
+ :avcodec => ENV['FFI_FFMPEG_LIBAVCODEC'],
13
+ :swscale => ENV['FFI_FFMPEG_LIBSWSCALE']
14
+ }
15
+
16
+ case Config::CONFIG['target_os']
17
+ when /linux/
18
+ LIBRARY_FILENAME[:avutil] ||= "libavutil.so.49"
19
+ LIBRARY_FILENAME[:avformat] ||= "libavformat.so.52"
20
+ LIBRARY_FILENAME[:avcodec] ||= "libavcodec.so.52"
21
+ LIBRARY_FILENAME[:swscale] ||= "libswscale.so.0"
22
+ when /darwin/
23
+ LIBRARY_FILENAME[:avutil] ||= "libavutil.49"
24
+ LIBRARY_FILENAME[:avformat] ||= "libavformat.52"
25
+ LIBRARY_FILENAME[:avcodec] ||= "libavcodec.52"
26
+
27
+ # Ok, this is stupid, but macports increments the major revision
28
+ # number from 0 to 1 to make some of their code work. We check
29
+ # for this case here and try libswscale.0 failing back to
30
+ # libswscale.1.
31
+ #
32
+ # See this commit for details:
33
+ # https://svn.macports.org/changeset/43550
34
+ LIBRARY_FILENAME[:swscale] ||= begin
35
+ DL.dlopen("libswscale.0.dylib").close
36
+ "libswscale.0"
37
+ rescue DL::DLError
38
+ "libswscale.1"
39
+ end
40
+ end
8
41
 
9
- ffi_lib "libavutil.so.49"
42
+ ###################################################
43
+ # #
44
+ # Definitions #
45
+ # #
46
+ ###################################################
47
+
48
+ AV_NOPTS_VALUE = 0x8000000000000000
49
+ MAX_STREAMS = 20
50
+ MAX_REORDER_DELAY = 16
51
+ AVSEEK_FLAG_BACKWARD = 1
52
+ AVSEEK_FLAG_BYTE = 2
53
+ AVSEEK_FLAG_ANY = 4
54
+ AV_TIME_BASE = 1000000
55
+ AV_PARSER_PTS_NB = 4
10
56
 
11
57
  AVMediaType = enum :unknown, -1,
12
58
  :video,
@@ -15,7 +61,7 @@ module FFI
15
61
  :subtitle,
16
62
  :attachment
17
63
 
18
- BIG_ENDIAN = [1].pack("I") == [1].pack("N")
64
+ big_endian = [1].pack("I") == [1].pack("N")
19
65
  PixelFormat = enum :none, -1,
20
66
  :yuv420p,
21
67
  :yuyv422,
@@ -44,12 +90,12 @@ module FFI
44
90
  :rgb4_byte,
45
91
  :nv12,
46
92
  :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
93
+ big_endian ? :rgb32 : :bgr32_1, # :argb
94
+ big_endian ? :rgb32_1 : :bgr32, # :rgba
95
+ big_endian ? :bgr32 : :rgb32_1, # :abgr
96
+ big_endian ? :bgr32_1 : :rgb32, # :bgra
97
+ big_endian ? :gray16 : :gray16_1, # :gray16be
98
+ big_endian ? :gray16_1 : :gray16, # :gray16le
53
99
  :yuv440p,
54
100
  :yuvj440p,
55
101
  :yuva420p,
@@ -58,115 +104,51 @@ module FFI
58
104
  :vdpau_mpeg2,
59
105
  :vdpau_wmv3,
60
106
  :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
107
+ big_endian ? :rgb48 : :rgb48_1, # :rgb48be
108
+ big_endian ? :rgb48_1 : :rgb48, # :rgb48le
109
+ big_endian ? :rgb565 : :rgb565_1, # :rgb565be
110
+ big_endian ? :rgb565_1 : :rgb565, # :rgb565le
111
+ big_endian ? :rgb555 : :rgb555_1, # :rgb555be
112
+ big_endian ? :rgb555_1 : :rgb555, # :rgb555le
113
+ big_endian ? :bgr565 : :bgr565_1, # :bgr565be
114
+ big_endian ? :bgr565_1 : :bgr565, # :bgr565le
115
+ big_endian ? :bgr555 : :bgr555_1, # :bgr555be
116
+ big_endian ? :bgr555_1 : :bgr555, # :bgr555le
71
117
  :vaapi_moco,
72
118
  :vaapi_idct,
73
119
  :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
120
+ big_endian ? :yuv420p16_1 : :yuv420p16, # :yuv420p16le
121
+ big_endian ? :yuv420p16 : :yuv420p16_1, # :yuv420p16be
122
+ big_endian ? :yuv422p16_1 : :yuv422p16, # :yuv422p16le
123
+ big_endian ? :yuv422p16 : :yuv422p16_1, # :yuv422p16be
124
+ big_endian ? :yuv444p16_1 : :yuv444p16, # :yuv444p16le
125
+ big_endian ? :yuv444p16 : :yuv444p16_1, # :yuv444p16be
80
126
  :vdpau_mpeg4,
81
127
  :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
128
+ big_endian ? :rgb444 : :rgb444_1, # :rgb444be
129
+ big_endian ? :rgb444_1 : :rgb444, # :rgb444le
130
+ big_endian ? :bgr444 : :bgr444_1, # :bgr444be
131
+ big_endian ? :bgr444_1 : :bgr444, # :bgr444le
86
132
  :y400a
87
133
 
88
134
  # Not actually an enum in libavutil.h, but we make it one here to
89
135
  # 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
136
+ AVLogLevel = enum :quiet, -8,
137
+ :panic, 0,
138
+ :fatal, 8,
139
+ :error, 16,
140
+ :warning, 24,
141
+ :info, 32,
142
+ :verbose, 40,
143
+ :debug, 48
144
+
145
+ AVDiscard = enum :none, -16,
146
+ :default, 0,
147
+ :nonref, 8,
148
+ :bidir, 16,
149
+ :nonkey, 32,
150
+ :all, 48
124
151
 
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_TIME_BASE = 1000000
147
- AV_PARSER_PTS_NB = 4
148
-
149
- AVDiscard = enum :none, -16,
150
- :default, 0,
151
- :nonref, 8,
152
- :bidir, 16,
153
- :nonkey, 32,
154
- :all, 48
155
-
156
- attach_function :avcodec_find_decoder, [:int], :pointer
157
- attach_function :avcodec_open, [:pointer, :pointer], :int
158
- attach_function :avcodec_alloc_frame, [], :pointer
159
- attach_function :avpicture_get_size, [PixelFormat, :int, :int], :int
160
- attach_function :avpicture_fill,
161
- [:pointer, :pointer, PixelFormat, :int, :int],
162
- :int
163
- attach_function :avcodec_decode_video, [:pointer, :pointer, :pointer,
164
- :pointer, :int], :int,
165
- { :blocking => true }
166
- attach_function :avcodec_default_get_buffer, [:pointer, :pointer], :int
167
- attach_function :avcodec_default_release_buffer, [:pointer, :pointer], :int
168
-
169
- ffi_lib "libswscale.so.0"
170
152
  SWScaleFlags = enum :fast_bilinear, 0x001,
171
153
  :bilinear, 0x002,
172
154
  :bicubic, 0x004,
@@ -179,19 +161,13 @@ module FFI
179
161
  :lanczos, 0x200,
180
162
  :spline, 0x400
181
163
 
182
- attach_function :sws_getContext,
183
- [:int, :int, PixelFormat, :int, :int, PixelFormat,
184
- SWScaleFlags, :pointer, :pointer, :pointer],
185
- :pointer
186
- attach_function :sws_freeContext,
187
- [:pointer],
188
- :void
189
- attach_function :sws_scale,
190
- [:pointer, :pointer, :pointer, :int,
191
- :int, :pointer, :pointer],
192
- :int,
193
- { :blocking => true }
164
+ callback :av_codec_context_get_buffer, [:pointer, :pointer], :int
194
165
 
166
+ ###################################################
167
+ # #
168
+ # Data Structures #
169
+ # #
170
+ ###################################################
195
171
 
196
172
  class AVRational < FFI::Struct
197
173
  layout :num, :int,
@@ -314,8 +290,6 @@ module FFI
314
290
  end
315
291
  end
316
292
 
317
- callback :av_codec_context_get_buffer, [:pointer, :pointer], :int
318
-
319
293
  class AVCodecContext < FFI::Struct
320
294
  layout :av_class, :pointer,
321
295
  :bit_rate, :int,
@@ -625,6 +599,83 @@ module FFI
625
599
  :reordered_opaque, :long_long
626
600
  end
627
601
 
602
+ ###################################################
603
+ # #
604
+ # Functions #
605
+ # #
606
+ ###################################################
607
+
608
+ ffi_lib LIBRARY_FILENAME[:avutil]
609
+
610
+ attach_function :av_log_get_level, [], AVLogLevel
611
+ attach_function :av_log_set_level, [AVLogLevel], :void
612
+ attach_function :av_free, [:pointer], :void
613
+ attach_function :av_malloc, [:uint], :pointer
614
+
615
+ ffi_lib LIBRARY_FILENAME[:avformat]
616
+ attach_function :av_register_all, [], :void
617
+ attach_function :av_open_input_file,
618
+ [:pointer, :string, :pointer, :int, :pointer],
619
+ :int
620
+ attach_function :av_find_stream_info, [:pointer], :int
621
+ attach_function :dump_format,
622
+ [:pointer, :int, :string, :int],
623
+ :void
624
+ attach_function :av_read_frame, [:pointer, :pointer], :int
625
+ attach_function :av_seek_frame, [:pointer, :int, :long_long, :int], :int
626
+ attach_function :av_find_default_stream_index, [ :pointer ], :int
627
+
628
+ # This function is inlined in avformat, defining it here
629
+ # for convenience.
630
+ #
631
+ # Original definition:
632
+ # static inline void av_free_packet(AVPacket *pkt)
633
+ # {
634
+ # if (pkt && pkt->destruct) {
635
+ # pkt->destruct(pkt);
636
+ # }
637
+ # }
638
+ #
639
+ def self.av_free_packet(pkt)
640
+ return unless pkt and pkt[:destruct]
641
+
642
+ FFI::Function.new(:void, [:pointer], pkt[:destruct],
643
+ :blocking => true).call(pkt)
644
+ end
645
+
646
+ def av_free_packet(pkt)
647
+ FFI::FFmpeg.av_free_packet(pkt)
648
+ end
649
+
650
+ ffi_lib LIBRARY_FILENAME[:avcodec]
651
+ attach_function :avcodec_find_decoder, [:int], :pointer
652
+ attach_function :avcodec_open, [:pointer, :pointer], :int
653
+ attach_function :avcodec_alloc_frame, [], :pointer
654
+ attach_function :avpicture_get_size, [PixelFormat, :int, :int], :int
655
+ attach_function :avpicture_fill,
656
+ [:pointer, :pointer, PixelFormat, :int, :int],
657
+ :int
658
+ attach_function :avcodec_decode_video, [:pointer, :pointer, :pointer,
659
+ :pointer, :int], :int,
660
+ { :blocking => true }
661
+ attach_function :avcodec_default_get_buffer, [:pointer, :pointer], :int
662
+ attach_function :avcodec_default_release_buffer, [:pointer, :pointer], :int
663
+
664
+ ffi_lib LIBRARY_FILENAME[:swscale]
665
+ attach_function :sws_getContext,
666
+ [:int, :int, PixelFormat, :int, :int, PixelFormat,
667
+ SWScaleFlags, :pointer, :pointer, :pointer],
668
+ :pointer
669
+ attach_function :sws_freeContext,
670
+ [:pointer],
671
+ :void
672
+ attach_function :sws_scale,
673
+ [:pointer, :pointer, :pointer, :int,
674
+ :int, :pointer, :pointer],
675
+ :int,
676
+ { :blocking => true }
677
+
678
+ callback :av_codec_context_get_buffer, [:pointer, :pointer], :int
628
679
 
629
680
  end # module FFmpeg
630
681
  end # module FFI
@@ -27,7 +27,7 @@ class FFmpeg::Reader
27
27
 
28
28
  # Video duration in (fractional) seconds
29
29
  def duration
30
- @av_format_ctx[:duration].to_f / AV_TIME_BASE
30
+ @duration ||= @av_format_ctx[:duration].to_f / AV_TIME_BASE
31
31
  end
32
32
 
33
33
  def each_frame(&block)
@@ -1,3 +1,3 @@
1
1
  module FFmpeg
2
- VERSION = "0.7"
2
+ VERSION = "0.8"
3
3
  end
metadata CHANGED
@@ -1,19 +1,19 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ffi-ffmpeg
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0beae74ee3d7
5
- prerelease: 5
4
+ version: 0.8.525a2f4a3ce0
5
+ prerelease: 7
6
6
  platform: ruby
7
7
  authors:
8
8
  - David M. Lary
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-06 00:00:00.000000000Z
12
+ date: 2011-11-26 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
- requirement: &14840620 !ruby/object:Gem::Requirement
16
+ requirement: &17824180 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *14840620
24
+ version_requirements: *17824180
25
25
  description: Ruby FFI bindings for libavformat, libavcodec, libavutil, and libswscale
26
26
  email:
27
27
  - dmlary@gmail.com