hornetseye-ffmpeg 0.1.0 → 0.2.0
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/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
|