hornetseye-ffmpeg 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/ext/avinput.cc +76 -2
- data/ext/avinput.hh +7 -0
- data/ext/frame.cc +6 -2
- data/lib/hornetseye-ffmpeg/avinput.rb +57 -0
- data/lib/hornetseye_ffmpeg_ext.rb +1 -0
- metadata +4 -3
data/Rakefile
CHANGED
data/ext/avinput.cc
CHANGED
@@ -15,13 +15,19 @@
|
|
15
15
|
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
16
16
|
#include "avinput.hh"
|
17
17
|
|
18
|
+
#if !defined(INT64_C)
|
19
|
+
#define INT64_C(c) c ## LL
|
20
|
+
#endif
|
21
|
+
|
22
|
+
// Also see FFMPEG tutorial at http://dranger.com/ffmpeg/
|
23
|
+
|
18
24
|
using namespace std;
|
19
25
|
|
20
26
|
VALUE AVInput::cRubyClass = Qnil;
|
21
27
|
|
22
28
|
AVInput::AVInput( const string &mrl ) throw (Error):
|
23
29
|
m_mrl( mrl ), m_ic( NULL ), m_enc( NULL ), m_codec( NULL ), m_idx( -1 ),
|
24
|
-
m_frame( NULL )
|
30
|
+
m_pts( 0 ), m_frame( NULL )
|
25
31
|
{
|
26
32
|
try {
|
27
33
|
int err = av_open_input_file( &m_ic, mrl.c_str(), NULL, 0, NULL );
|
@@ -86,7 +92,9 @@ FramePtr AVInput::read(void) throw (Error)
|
|
86
92
|
packet.data, packet.size );
|
87
93
|
ERRORMACRO( err >= 0, Error, ,
|
88
94
|
"Error decoding frame of video \"" << m_mrl << "\"" );
|
95
|
+
|
89
96
|
if ( frameFinished ) {
|
97
|
+
if ( packet.dts != AV_NOPTS_VALUE ) m_pts = packet.dts;
|
90
98
|
av_free_packet( &packet );
|
91
99
|
AVFrame frame;
|
92
100
|
m_data = boost::shared_array< char >( new char[ m_enc->width *
|
@@ -102,7 +110,7 @@ FramePtr AVInput::read(void) throw (Error)
|
|
102
110
|
struct SwsContext *swsContext =
|
103
111
|
sws_getContext( m_enc->width, m_enc->height, m_enc->pix_fmt,
|
104
112
|
m_enc->width, m_enc->height, PIX_FMT_YUV420P,
|
105
|
-
|
113
|
+
SWS_FAST_BILINEAR, 0, 0, 0 );
|
106
114
|
sws_scale( swsContext, m_frame->data, m_frame->linesize, 0,
|
107
115
|
m_enc->height, frame.data, frame.linesize );
|
108
116
|
sws_freeContext( swsContext );
|
@@ -117,13 +125,40 @@ FramePtr AVInput::read(void) throw (Error)
|
|
117
125
|
return retVal;
|
118
126
|
}
|
119
127
|
|
128
|
+
AVRational AVInput::timeBase(void) throw (Error)
|
129
|
+
{
|
130
|
+
ERRORMACRO( m_ic != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
|
131
|
+
"Did you call \"close\" before?" );
|
132
|
+
return m_ic->streams[ m_idx ]->time_base;
|
133
|
+
}
|
134
|
+
|
135
|
+
void AVInput::seek( long timestamp ) throw (Error)
|
136
|
+
{
|
137
|
+
ERRORMACRO( m_ic != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
|
138
|
+
"Did you call \"close\" before?" );
|
139
|
+
ERRORMACRO( av_seek_frame( m_ic, -1, timestamp, 0 ) >= 0,
|
140
|
+
Error, , "Error seeking in video \"" << m_mrl << "\"" );
|
141
|
+
avcodec_flush_buffers( m_enc );
|
142
|
+
}
|
143
|
+
|
144
|
+
long long AVInput::pts(void) throw (Error)
|
145
|
+
{
|
146
|
+
ERRORMACRO( m_ic != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
|
147
|
+
"Did you call \"close\" before?" );
|
148
|
+
return m_pts;
|
149
|
+
}
|
150
|
+
|
120
151
|
VALUE AVInput::registerRubyClass( VALUE rbModule )
|
121
152
|
{
|
122
153
|
av_register_all();
|
123
154
|
cRubyClass = rb_define_class_under( rbModule, "AVInput", rb_cObject );
|
124
155
|
rb_define_singleton_method( cRubyClass, "new",
|
125
156
|
RUBY_METHOD_FUNC( wrapNew ), 1 );
|
157
|
+
rb_define_const( cRubyClass, "AV_TIME_BASE", INT2NUM( AV_TIME_BASE ) );
|
126
158
|
rb_define_method( cRubyClass, "read", RUBY_METHOD_FUNC( wrapRead ), 0 );
|
159
|
+
rb_define_method( cRubyClass, "time_base", RUBY_METHOD_FUNC( wrapTimeBase ), 0 );
|
160
|
+
rb_define_method( cRubyClass, "seek", RUBY_METHOD_FUNC( wrapSeek ), 1 );
|
161
|
+
rb_define_method( cRubyClass, "pts", RUBY_METHOD_FUNC( wrapPTS ), 0 );
|
127
162
|
}
|
128
163
|
|
129
164
|
void AVInput::deleteRubyObject( void *ptr )
|
@@ -157,3 +192,42 @@ VALUE AVInput::wrapRead( VALUE rbSelf )
|
|
157
192
|
};
|
158
193
|
return retVal;
|
159
194
|
}
|
195
|
+
|
196
|
+
VALUE AVInput::wrapTimeBase( VALUE rbSelf )
|
197
|
+
{
|
198
|
+
VALUE retVal = Qnil;
|
199
|
+
try {
|
200
|
+
AVInputPtr *self; Data_Get_Struct( rbSelf, AVInputPtr, self );
|
201
|
+
AVRational time_base = (*self)->timeBase();
|
202
|
+
retVal = rb_funcall( rb_cObject, rb_intern( "Rational" ), 2,
|
203
|
+
INT2NUM( time_base.num ), INT2NUM( time_base.den ) );
|
204
|
+
} catch( exception &e ) {
|
205
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
206
|
+
};
|
207
|
+
return retVal;
|
208
|
+
}
|
209
|
+
|
210
|
+
VALUE AVInput::wrapSeek( VALUE rbSelf, VALUE rbPos )
|
211
|
+
{
|
212
|
+
VALUE retVal = Qnil;
|
213
|
+
try {
|
214
|
+
AVInputPtr *self; Data_Get_Struct( rbSelf, AVInputPtr, self );
|
215
|
+
(*self)->seek( NUM2LL( rbPos ) );
|
216
|
+
} catch( exception &e ) {
|
217
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
218
|
+
};
|
219
|
+
return retVal;
|
220
|
+
}
|
221
|
+
|
222
|
+
VALUE AVInput::wrapPTS( VALUE rbSelf )
|
223
|
+
{
|
224
|
+
VALUE retVal = Qnil;
|
225
|
+
try {
|
226
|
+
AVInputPtr *self; Data_Get_Struct( rbSelf, AVInputPtr, self );
|
227
|
+
retVal = LL2NUM( (*self)->pts() );
|
228
|
+
} catch( exception &e ) {
|
229
|
+
rb_raise( rb_eRuntimeError, "%s", e.what() );
|
230
|
+
};
|
231
|
+
return retVal;
|
232
|
+
}
|
233
|
+
|
data/ext/avinput.hh
CHANGED
@@ -32,17 +32,24 @@ public:
|
|
32
32
|
virtual ~AVInput(void);
|
33
33
|
void close(void);
|
34
34
|
FramePtr read(void) throw (Error);
|
35
|
+
AVRational timeBase(void) throw (Error);
|
36
|
+
void seek( long timestamp ) throw (Error);
|
37
|
+
long long pts(void) throw (Error);
|
35
38
|
static VALUE cRubyClass;
|
36
39
|
static VALUE registerRubyClass( VALUE rbModule );
|
37
40
|
static void deleteRubyObject( void *ptr );
|
38
41
|
static VALUE wrapNew( VALUE rbClass, VALUE rbMRL );
|
39
42
|
static VALUE wrapRead( VALUE rbSelf );
|
43
|
+
static VALUE wrapTimeBase( VALUE rbSelf );
|
44
|
+
static VALUE wrapSeek( VALUE rbSelf, VALUE rbPos );
|
45
|
+
static VALUE wrapPTS( VALUE rbSelf );
|
40
46
|
protected:
|
41
47
|
std::string m_mrl;
|
42
48
|
AVFormatContext *m_ic;
|
43
49
|
AVCodecContext *m_enc;
|
44
50
|
AVCodec *m_codec;
|
45
51
|
int m_idx;
|
52
|
+
long long m_pts;
|
46
53
|
AVFrame *m_frame;
|
47
54
|
boost::shared_array< char > m_data;
|
48
55
|
};
|
data/ext/frame.cc
CHANGED
@@ -24,9 +24,13 @@ Frame::Frame( const char *typecode, int width, int height, char *data ):
|
|
24
24
|
VALUE mModule = rb_define_module( "Hornetseye" );
|
25
25
|
VALUE cMalloc = rb_define_class_under( mModule, "Malloc", rb_cObject );
|
26
26
|
VALUE cFrame = rb_define_class_under( mModule, "Frame", rb_cObject );
|
27
|
-
VALUE
|
27
|
+
VALUE rbSize = rb_funcall( cFrame, rb_intern( "typesize" ), 3,
|
28
|
+
rb_const_get( mModule, rb_intern( typecode ) ),
|
29
|
+
INT2NUM( width ), INT2NUM( height ) );
|
30
|
+
VALUE rbMemory = Data_Wrap_Struct( cMalloc, 0, 0, (void *)data );
|
31
|
+
rb_ivar_set( rbMemory, rb_intern( "@size" ), rbSize );
|
28
32
|
m_frame = rb_funcall( cFrame, rb_intern( "import" ), 4,
|
29
33
|
rb_const_get( mModule, rb_intern( typecode ) ),
|
30
34
|
INT2NUM( width ), INT2NUM( height ),
|
31
|
-
|
35
|
+
rbMemory );
|
32
36
|
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# hornetseye-frame - Colourspace conversions and compression
|
2
|
+
# Copyright (C) 2010 Jan Wedekind
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
7
|
+
# (at your option) any later version.
|
8
|
+
#
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
12
|
+
# GNU General Public License for more details.
|
13
|
+
#
|
14
|
+
# You should have received a copy of the GNU General Public License
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
16
|
+
|
17
|
+
# Namespace of Hornetseye computer vision library
|
18
|
+
module Hornetseye
|
19
|
+
|
20
|
+
class AVInput
|
21
|
+
|
22
|
+
class << self
|
23
|
+
|
24
|
+
alias_method :orig_new, :new
|
25
|
+
|
26
|
+
def new( mrl )
|
27
|
+
retval = orig_new mrl
|
28
|
+
retval.instance_eval { @frame = nil }
|
29
|
+
retval
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
alias_method :orig_read, :read
|
35
|
+
|
36
|
+
def read
|
37
|
+
@frame = orig_read
|
38
|
+
end
|
39
|
+
|
40
|
+
def pos=( timestamp )
|
41
|
+
unless @frame
|
42
|
+
begin
|
43
|
+
read
|
44
|
+
rescue Exception
|
45
|
+
end
|
46
|
+
end
|
47
|
+
seek timestamp * AV_TIME_BASE
|
48
|
+
end
|
49
|
+
|
50
|
+
def pos
|
51
|
+
pts * time_base
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 0.
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jan Wedekind
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-09-
|
17
|
+
date: 2010-09-28 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -85,6 +85,7 @@ files:
|
|
85
85
|
- README.md
|
86
86
|
- COPYING
|
87
87
|
- .document
|
88
|
+
- lib/hornetseye-ffmpeg/avinput.rb
|
88
89
|
- lib/hornetseye_ffmpeg_ext.rb
|
89
90
|
- ext/avinput.cc
|
90
91
|
- ext/init.cc
|