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 CHANGED
@@ -6,7 +6,7 @@ require 'rake/packagetask'
6
6
  require 'rbconfig'
7
7
 
8
8
  PKG_NAME = 'hornetseye-ffmpeg'
9
- PKG_VERSION = '0.1.0'
9
+ PKG_VERSION = '0.2.0'
10
10
  CXX = ENV[ 'CXX' ] || 'g++'
11
11
  STRIP = ENV[ 'STRIP' ] || 'strip'
12
12
  RB_FILES = FileList[ 'lib/**/*.rb' ]
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
- SWS_BILINEAR, 0, 0, 0 );
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 memory = Data_Wrap_Struct( cMalloc, 0, 0, (void *)data );
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
- memory );
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
+
@@ -15,4 +15,5 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  require 'hornetseye_frame'
18
+ require 'hornetseye-ffmpeg/avinput'
18
19
 
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.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-26 00:00:00 +01:00
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