ffi-ffmpeg 0.7.0beae74ee3d7 → 0.8.525a2f4a3ce0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|