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 +1 -0
- data/README.md +44 -2
- data/lib/ffi/ffmpeg.rb +173 -122
- data/lib/ffmpeg/reader.rb +1 -1
- data/lib/ffmpeg/version.rb +1 -1
- metadata +5 -5
data/.hgignore
CHANGED
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
|
-
|
63
|
+
|
22
64
|
require 'ffi-ffmpeg'
|
23
65
|
|
24
66
|
# Allocate a reader for our video file
|
data/lib/ffi/ffmpeg.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
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
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
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
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
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
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
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
|
-
|
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
|
data/lib/ffmpeg/reader.rb
CHANGED
data/lib/ffmpeg/version.rb
CHANGED
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.
|
5
|
-
prerelease:
|
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-
|
12
|
+
date: 2011-11-26 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: ffi
|
16
|
-
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: *
|
24
|
+
version_requirements: *17824180
|
25
25
|
description: Ruby FFI bindings for libavformat, libavcodec, libavutil, and libswscale
|
26
26
|
email:
|
27
27
|
- dmlary@gmail.com
|