hornetseye-ffmpeg 0.8.0 → 0.8.1

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
@@ -7,7 +7,7 @@ require 'rake/loaders/makefile'
7
7
  require 'rbconfig'
8
8
 
9
9
  PKG_NAME = 'hornetseye-ffmpeg'
10
- PKG_VERSION = '0.8.0'
10
+ PKG_VERSION = '0.8.1'
11
11
  CFG = RbConfig::CONFIG
12
12
  CXX = ENV[ 'CXX' ] || 'g++'
13
13
  RB_FILES = FileList[ 'lib/**/*.rb' ]
data/ext/avinput.cc CHANGED
@@ -282,13 +282,20 @@ long long AVInput::duration(void) throw (Error)
282
282
  return m_ic->streams[ m_videoStream ]->duration;
283
283
  }
284
284
 
285
- long long AVInput::startTime(void) throw (Error)
285
+ long long AVInput::videoStartTime(void) throw (Error)
286
286
  {
287
- ERRORMACRO( m_ic != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
287
+ ERRORMACRO( m_videoStream != -1, Error, , "Video \"" << m_mrl << "\" is not open. "
288
288
  "Did you call \"close\" before?" );
289
289
  return m_ic->streams[ m_videoStream ]->start_time;
290
290
  }
291
291
 
292
+ long long AVInput::audioStartTime(void) throw (Error)
293
+ {
294
+ ERRORMACRO( m_audioStream != -1, Error, , "Audio \"" << m_mrl << "\" is not open. "
295
+ "Did you call \"close\" before?" );
296
+ return m_ic->streams[ m_audioStream ]->start_time;
297
+ }
298
+
292
299
  void AVInput::seek( long long timestamp ) throw (Error)
293
300
  {
294
301
  ERRORMACRO( m_ic != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
@@ -332,7 +339,10 @@ VALUE AVInput::registerRubyClass( VALUE rbModule )
332
339
  rb_define_method( cRubyClass, "sample_rate", RUBY_METHOD_FUNC( wrapSampleRate ), 0 );
333
340
  rb_define_method( cRubyClass, "channels", RUBY_METHOD_FUNC( wrapChannels ), 0 );
334
341
  rb_define_method( cRubyClass, "duration", RUBY_METHOD_FUNC( wrapDuration ), 0 );
335
- rb_define_method( cRubyClass, "start_time", RUBY_METHOD_FUNC( wrapStartTime ), 0 );
342
+ rb_define_method( cRubyClass, "video_start_time",
343
+ RUBY_METHOD_FUNC( wrapVideoStartTime ), 0 );
344
+ rb_define_method( cRubyClass, "audio_start_time",
345
+ RUBY_METHOD_FUNC( wrapAudioStartTime ), 0 );
336
346
  rb_define_method( cRubyClass, "width", RUBY_METHOD_FUNC( wrapWidth ), 0 );
337
347
  rb_define_method( cRubyClass, "height", RUBY_METHOD_FUNC( wrapHeight ), 0 );
338
348
  rb_define_method( cRubyClass, "has_audio?", RUBY_METHOD_FUNC( wrapHasAudio ), 0 );
@@ -488,12 +498,24 @@ VALUE AVInput::wrapDuration( VALUE rbSelf )
488
498
  return retVal;
489
499
  }
490
500
 
491
- VALUE AVInput::wrapStartTime( VALUE rbSelf )
501
+ VALUE AVInput::wrapVideoStartTime( VALUE rbSelf )
502
+ {
503
+ VALUE retVal = Qnil;
504
+ try {
505
+ AVInputPtr *self; Data_Get_Struct( rbSelf, AVInputPtr, self );
506
+ retVal = LL2NUM( (*self)->videoStartTime() );
507
+ } catch ( exception &e ) {
508
+ rb_raise( rb_eRuntimeError, "%s", e.what() );
509
+ };
510
+ return retVal;
511
+ }
512
+
513
+ VALUE AVInput::wrapAudioStartTime( VALUE rbSelf )
492
514
  {
493
515
  VALUE retVal = Qnil;
494
516
  try {
495
517
  AVInputPtr *self; Data_Get_Struct( rbSelf, AVInputPtr, self );
496
- retVal = LL2NUM( (*self)->startTime() );
518
+ retVal = LL2NUM( (*self)->audioStartTime() );
497
519
  } catch ( exception &e ) {
498
520
  rb_raise( rb_eRuntimeError, "%s", e.what() );
499
521
  };
data/ext/avinput.hh CHANGED
@@ -56,7 +56,8 @@ public:
56
56
  int sampleRate(void) throw (Error);
57
57
  int channels(void) throw (Error);
58
58
  long long duration(void) throw (Error);
59
- long long startTime(void) throw (Error);
59
+ long long videoStartTime(void) throw (Error);
60
+ long long audioStartTime(void) throw (Error);
60
61
  void seek( long long timestamp ) throw (Error);
61
62
  long long videoPts(void) throw (Error);
62
63
  long long audioPts(void) throw (Error);
@@ -75,7 +76,8 @@ public:
75
76
  static VALUE wrapSampleRate( VALUE rbSelf );
76
77
  static VALUE wrapChannels( VALUE rbSelf );
77
78
  static VALUE wrapDuration( VALUE rbSelf );
78
- static VALUE wrapStartTime( VALUE rbSelf );
79
+ static VALUE wrapVideoStartTime( VALUE rbSelf );
80
+ static VALUE wrapAudioStartTime( VALUE rbSelf );
79
81
  static VALUE wrapWidth( VALUE rbSelf );
80
82
  static VALUE wrapHeight( VALUE rbSelf );
81
83
  static VALUE wrapHasAudio( VALUE rbSelf );
data/ext/avoutput.cc CHANGED
@@ -35,9 +35,9 @@ AVOutput::AVOutput( const string &mrl, int videoBitRate, int width, int height,
35
35
  int aspectRatioDen, enum CodecID videoCodec,
36
36
  int audioBitRate, int sampleRate, int channels,
37
37
  enum CodecID audioCodec ) throw (Error):
38
- m_mrl( mrl ), m_oc( NULL ), m_video_st( NULL ), m_audio_st( NULL),
39
- m_video_codec_open( false ), m_audio_codec_open( false ), m_video_buf( NULL ),
40
- m_audio_buf( NULL ), m_file_open( false ), m_header_written( false ),
38
+ m_mrl( mrl ), m_oc( NULL ), m_videoStream( NULL ), m_audioStream( NULL),
39
+ m_videoCodecOpen( false ), m_audioCodecOpen( false ), m_videoBuf( NULL ),
40
+ m_audioBuf( NULL ), m_fileOpen( false ), m_headerWritten( false ),
41
41
  m_swsContext( NULL ), m_frame( NULL )
42
42
  {
43
43
  try {
@@ -56,11 +56,11 @@ AVOutput::AVOutput( const string &mrl, int videoBitRate, int width, int height,
56
56
  snprintf( m_oc->filename, sizeof( m_oc->filename ), "%s", mrl.c_str() );
57
57
  ERRORMACRO( format->video_codec != CODEC_ID_NONE, Error, ,
58
58
  "Output format does not support video" );
59
- m_video_st = av_new_stream( m_oc, 0 );
60
- ERRORMACRO( m_video_st != NULL, Error, , "Could not allocate video stream" );
61
- m_video_st->sample_aspect_ratio.num = aspectRatioNum;
62
- m_video_st->sample_aspect_ratio.den = aspectRatioDen;
63
- AVCodecContext *c = m_video_st->codec;
59
+ m_videoStream = av_new_stream( m_oc, 0 );
60
+ ERRORMACRO( m_videoStream != NULL, Error, , "Could not allocate video stream" );
61
+ m_videoStream->sample_aspect_ratio.num = aspectRatioNum;
62
+ m_videoStream->sample_aspect_ratio.den = aspectRatioDen;
63
+ AVCodecContext *c = m_videoStream->codec;
64
64
  c->codec_id = videoCodec != CODEC_ID_NONE ? videoCodec : format->video_codec;
65
65
  c->codec_type = CODEC_TYPE_VIDEO;
66
66
  c->bit_rate = videoBitRate;
@@ -75,9 +75,9 @@ AVOutput::AVOutput( const string &mrl, int videoBitRate, int width, int height,
75
75
  if ( m_oc->oformat->flags & AVFMT_GLOBALHEADER )
76
76
  c->flags |= CODEC_FLAG_GLOBAL_HEADER;
77
77
  if ( channels > 0 ) {
78
- m_audio_st = av_new_stream( m_oc, 0 );
79
- ERRORMACRO( m_audio_st != NULL, Error, , "Could not allocate audio stream" );
80
- AVCodecContext *c = m_audio_st->codec;
78
+ m_audioStream = av_new_stream( m_oc, 0 );
79
+ ERRORMACRO( m_audioStream != NULL, Error, , "Could not allocate audio stream" );
80
+ AVCodecContext *c = m_audioStream->codec;
81
81
  c->codec_id = audioCodec != CODEC_ID_NONE ? audioCodec : format->audio_codec;
82
82
  c->codec_type = CODEC_TYPE_AUDIO;
83
83
  c->bit_rate = audioBitRate;
@@ -94,23 +94,23 @@ AVOutput::AVOutput( const string &mrl, int videoBitRate, int width, int height,
94
94
  ERRORMACRO( avcodec_open( c, codec ) >= 0, Error, ,
95
95
  "Error opening video codec \"" << codec->name << "\": "
96
96
  << strerror( errno ) );
97
- m_video_codec_open = true;
97
+ m_videoCodecOpen = true;
98
98
  if ( !( m_oc->oformat->flags & AVFMT_RAWPICTURE ) ) {
99
- m_video_buf = (char *)av_malloc( VIDEO_BUF_SIZE );
100
- ERRORMACRO( m_video_buf != NULL, Error, ,
99
+ m_videoBuf = (char *)av_malloc( VIDEO_BUF_SIZE );
100
+ ERRORMACRO( m_videoBuf != NULL, Error, ,
101
101
  "Error allocating video output buffer" );
102
102
  };
103
103
  if ( channels > 0 ) {
104
- AVCodecContext *c = m_audio_st->codec;
104
+ AVCodecContext *c = m_audioStream->codec;
105
105
  AVCodec *codec = avcodec_find_encoder( c->codec_id );
106
106
  ERRORMACRO( codec != NULL, Error, , "Could not find audio codec "
107
107
  << c->codec_id );
108
108
  ERRORMACRO( avcodec_open( c, codec ) >= 0, Error, ,
109
109
  "Error opening audio codec \"" << codec->name << "\": "
110
110
  << strerror( errno ) );
111
- m_audio_codec_open = true;
112
- m_audio_buf = (char *)av_malloc( AUDIO_BUF_SIZE );
113
- ERRORMACRO( m_audio_buf != NULL, Error, ,
111
+ m_audioCodecOpen = true;
112
+ m_audioBuf = (char *)av_malloc( AUDIO_BUF_SIZE );
113
+ ERRORMACRO( m_audioBuf != NULL, Error, ,
114
114
  "Error allocating audio output buffer" );
115
115
  #ifndef NDEBUG
116
116
  cerr << "audio frame size = " << c->frame_size << " samples" << endl;
@@ -119,12 +119,12 @@ AVOutput::AVOutput( const string &mrl, int videoBitRate, int width, int height,
119
119
  if ( !( format->flags & AVFMT_NOFILE ) ) {
120
120
  ERRORMACRO( url_fopen( &m_oc->pb, mrl.c_str(), URL_WRONLY ) >= 0, Error, ,
121
121
  "Could not open \"" << mrl << "\"" );
122
- m_file_open = true;
122
+ m_fileOpen = true;
123
123
  };
124
124
  ERRORMACRO( av_write_header( m_oc ) >= 0, Error, ,
125
125
  "Error writing header of video \"" << mrl << "\": "
126
126
  << strerror( errno ) );
127
- m_header_written = true;
127
+ m_headerWritten = true;
128
128
  m_swsContext = sws_getContext( width, height, PIX_FMT_YUV420P,
129
129
  width, height, PIX_FMT_YUV420P,
130
130
  SWS_FAST_BILINEAR, 0, 0, 0 );
@@ -158,63 +158,95 @@ void AVOutput::close(void)
158
158
  sws_freeContext( m_swsContext );
159
159
  m_swsContext = NULL;
160
160
  };
161
- if ( m_header_written ) {
161
+ if ( m_headerWritten ) {
162
162
  av_write_trailer( m_oc );
163
- m_header_written = false;
163
+ m_headerWritten = false;
164
164
  };
165
- if ( m_audio_st ) {
166
- if ( m_audio_codec_open ) {
167
- avcodec_close( m_audio_st->codec );
168
- m_audio_codec_open = false;
165
+ if ( m_audioStream ) {
166
+ if ( m_audioCodecOpen ) {
167
+ avcodec_close( m_audioStream->codec );
168
+ m_audioCodecOpen = false;
169
169
  };
170
170
  };
171
- if ( m_video_st ) {
172
- if ( m_video_codec_open ) {
173
- avcodec_close( m_video_st->codec );
174
- m_video_codec_open = false;
171
+ if ( m_videoStream ) {
172
+ if ( m_videoCodecOpen ) {
173
+ avcodec_close( m_videoStream->codec );
174
+ m_videoCodecOpen = false;
175
175
  };
176
176
  };
177
- if ( m_audio_buf ) {
178
- av_free( m_audio_buf );
179
- m_audio_buf = NULL;
177
+ if ( m_audioBuf ) {
178
+ av_free( m_audioBuf );
179
+ m_audioBuf = NULL;
180
180
  };
181
- if ( m_video_buf ) {
182
- av_free( m_video_buf );
183
- m_video_buf = NULL;
181
+ if ( m_videoBuf ) {
182
+ av_free( m_videoBuf );
183
+ m_videoBuf = NULL;
184
184
  };
185
185
  if ( m_oc ) {
186
186
  for ( unsigned int i = 0; i < m_oc->nb_streams; i++ ) {
187
187
  av_freep( &m_oc->streams[i]->codec );
188
188
  av_freep( &m_oc->streams[i] );
189
189
  };
190
- m_audio_st = NULL;
191
- m_video_st = NULL;
192
- if ( m_file_open ) {
190
+ m_audioStream = NULL;
191
+ m_videoStream = NULL;
192
+ if ( m_fileOpen ) {
193
193
  #ifdef HAVE_BYTEIO_PTR
194
194
  url_fclose( m_oc->pb );
195
195
  #else
196
196
  url_fclose( &m_oc->pb );
197
197
  #endif
198
- m_file_open = false;
198
+ m_fileOpen = false;
199
199
  };
200
200
  av_free( m_oc );
201
201
  m_oc = NULL;
202
202
  };
203
203
  }
204
204
 
205
+ AVRational AVOutput::videoTimeBase(void) throw (Error)
206
+ {
207
+ ERRORMACRO( m_videoStream != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
208
+ "Did you call \"close\" before?" );
209
+ return m_videoStream->time_base;
210
+ }
211
+
212
+ AVRational AVOutput::audioTimeBase(void) throw (Error)
213
+ {
214
+ ERRORMACRO( m_audioStream != NULL, Error, , "Audio \"" << m_mrl << "\" is not open. "
215
+ "Did you call \"close\" before?" );
216
+ return m_audioStream->time_base;
217
+ }
218
+
219
+ int AVOutput::frameSize(void) throw (Error)
220
+ {
221
+ ERRORMACRO( m_oc != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
222
+ "Did you call \"close\" before?" );
223
+ ERRORMACRO( m_audioStream != NULL, Error, , "Video \"" << m_mrl << "\" does not have "
224
+ "an audio stream" );
225
+ return m_audioStream->codec->frame_size;
226
+ }
227
+
228
+ int AVOutput::channels(void) throw (Error)
229
+ {
230
+ ERRORMACRO( m_oc != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
231
+ "Did you call \"close\" before?" );
232
+ ERRORMACRO( m_audioStream != NULL, Error, , "Video \"" << m_mrl << "\" does not have "
233
+ "an audio stream" );
234
+ return m_audioStream->codec->channels;
235
+ }
236
+
205
237
  void AVOutput::writeVideo( FramePtr frame ) throw (Error)
206
238
  {
207
239
  ERRORMACRO( m_oc != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
208
240
  "Did you call \"close\" before?" );
209
- ERRORMACRO( m_video_st->codec->width == frame->width() &&
210
- m_video_st->codec->height == frame->height(), Error, ,
241
+ ERRORMACRO( m_videoStream->codec->width == frame->width() &&
242
+ m_videoStream->codec->height == frame->height(), Error, ,
211
243
  "Resolution of frame is " << frame->width() << 'x'
212
244
  << frame->height() << " but video resolution is "
213
- << m_video_st->codec->width << 'x' << m_video_st->codec->height );
245
+ << m_videoStream->codec->width << 'x' << m_videoStream->codec->height );
214
246
  if ( m_oc->oformat->flags & AVFMT_RAWPICTURE ) {
215
247
  ERRORMACRO( false, Error, , "Raw picture encoding not implemented yet" );
216
248
  } else {
217
- AVCodecContext *c = m_video_st->codec;
249
+ AVCodecContext *c = m_videoStream->codec;
218
250
  AVFrame picture;
219
251
  int
220
252
  width = c->width,
@@ -231,7 +263,7 @@ void AVOutput::writeVideo( FramePtr frame ) throw (Error)
231
263
  picture.linesize[2] = width2a;
232
264
  sws_scale( m_swsContext, picture.data, picture.linesize, 0,
233
265
  c->height, m_frame->data, m_frame->linesize );
234
- int packetSize = avcodec_encode_video( c, (uint8_t *)m_video_buf,
266
+ int packetSize = avcodec_encode_video( c, (uint8_t *)m_videoBuf,
235
267
  VIDEO_BUF_SIZE, m_frame );
236
268
  ERRORMACRO( packetSize >= 0, Error, , "Error encoding video frame" );
237
269
  if ( packetSize > 0 ) {
@@ -239,11 +271,11 @@ void AVOutput::writeVideo( FramePtr frame ) throw (Error)
239
271
  av_init_packet( &packet );
240
272
  if ( c->coded_frame->pts != AV_NOPTS_VALUE )
241
273
  packet.pts = av_rescale_q( c->coded_frame->pts, c->time_base,
242
- m_video_st->time_base );
274
+ m_videoStream->time_base );
243
275
  if ( c->coded_frame->key_frame )
244
276
  packet.flags |= PKT_FLAG_KEY;
245
- packet.stream_index = m_video_st->index;
246
- packet.data = (uint8_t *)m_video_buf;
277
+ packet.stream_index = m_videoStream->index;
278
+ packet.data = (uint8_t *)m_videoBuf;
247
279
  packet.size = packetSize;
248
280
  ERRORMACRO( av_interleaved_write_frame( m_oc, &packet ) >= 0, Error, ,
249
281
  "Error writing video frame of video \"" << m_mrl << "\": "
@@ -252,35 +284,17 @@ void AVOutput::writeVideo( FramePtr frame ) throw (Error)
252
284
  };
253
285
  }
254
286
 
255
- int AVOutput::frameSize(void) throw (Error)
256
- {
257
- ERRORMACRO( m_oc != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
258
- "Did you call \"close\" before?" );
259
- ERRORMACRO( m_audio_st != NULL, Error, , "Video \"" << m_mrl << "\" does not have "
260
- "an audio stream" );
261
- return m_audio_st->codec->frame_size;
262
- }
263
-
264
- int AVOutput::channels(void) throw (Error)
265
- {
266
- ERRORMACRO( m_oc != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
267
- "Did you call \"close\" before?" );
268
- ERRORMACRO( m_audio_st != NULL, Error, , "Video \"" << m_mrl << "\" does not have "
269
- "an audio stream" );
270
- return m_audio_st->codec->channels;
271
- }
272
-
273
287
  void AVOutput::writeAudio( SequencePtr frame ) throw (Error)
274
288
  {
275
289
  ERRORMACRO( m_oc != NULL, Error, , "Video \"" << m_mrl << "\" is not open. "
276
290
  "Did you call \"close\" before?" );
277
- ERRORMACRO( m_audio_st != NULL, Error, , "Video \"" << m_mrl << "\" does not have "
291
+ ERRORMACRO( m_audioStream != NULL, Error, , "Video \"" << m_mrl << "\" does not have "
278
292
  "an audio stream" );
279
- AVCodecContext *c = m_audio_st->codec;
293
+ AVCodecContext *c = m_audioStream->codec;
280
294
  ERRORMACRO( frame->size() == c->frame_size * 2 * c->channels, Error, , "Size of "
281
295
  "audio frame is " << frame->size() << " bytes (but should be "
282
296
  << c->frame_size * 2 * c->channels << " bytes)" );
283
- int packetSize = avcodec_encode_audio( c, (uint8_t *)m_audio_buf,
297
+ int packetSize = avcodec_encode_audio( c, (uint8_t *)m_audioBuf,
284
298
  AUDIO_BUF_SIZE, (short *)frame->data() );
285
299
  ERRORMACRO( packetSize >= 0, Error, , "Error encoding audio frame" );
286
300
  if ( packetSize > 0 ) {
@@ -288,10 +302,10 @@ void AVOutput::writeAudio( SequencePtr frame ) throw (Error)
288
302
  av_init_packet( &packet );
289
303
  if ( c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE )
290
304
  packet.pts = av_rescale_q( c->coded_frame->pts, c->time_base,
291
- m_audio_st->time_base );
305
+ m_audioStream->time_base );
292
306
  packet.flags |= PKT_FLAG_KEY;
293
- packet.stream_index = m_audio_st->index;
294
- packet.data = (uint8_t *)m_audio_buf;
307
+ packet.stream_index = m_audioStream->index;
308
+ packet.data = (uint8_t *)m_audioBuf;
295
309
  packet.size = packetSize;
296
310
  ERRORMACRO( av_interleaved_write_frame( m_oc, &packet ) >= 0, Error, ,
297
311
  "Error writing audio frame of video \"" << m_mrl << "\": "
@@ -775,6 +789,10 @@ VALUE AVOutput::registerRubyClass( VALUE rbModule )
775
789
  rb_define_const( cRubyClass, "CODEC_ID_MP1",
776
790
  INT2FIX( CODEC_ID_MP1 ) );
777
791
  rb_define_method( cRubyClass, "close", RUBY_METHOD_FUNC( wrapClose ), 0 );
792
+ rb_define_method( cRubyClass, "video_time_base",
793
+ RUBY_METHOD_FUNC( wrapVideoTimeBase ), 0 );
794
+ rb_define_method( cRubyClass, "audio_time_base",
795
+ RUBY_METHOD_FUNC( wrapAudioTimeBase ), 0 );
778
796
  rb_define_method( cRubyClass, "frame_size", RUBY_METHOD_FUNC( wrapFrameSize ), 0 );
779
797
  rb_define_method( cRubyClass, "channels", RUBY_METHOD_FUNC( wrapChannels ), 0 );
780
798
  rb_define_method( cRubyClass, "write_video", RUBY_METHOD_FUNC( wrapWriteVideo ), 1 );
@@ -819,6 +837,34 @@ VALUE AVOutput::wrapClose( VALUE rbSelf )
819
837
  return rbSelf;
820
838
  }
821
839
 
840
+ VALUE AVOutput::wrapVideoTimeBase( VALUE rbSelf )
841
+ {
842
+ VALUE retVal = Qnil;
843
+ try {
844
+ AVOutputPtr *self; Data_Get_Struct( rbSelf, AVOutputPtr, self );
845
+ AVRational videoTimeBase = (*self)->videoTimeBase();
846
+ retVal = rb_funcall( rb_cObject, rb_intern( "Rational" ), 2,
847
+ INT2NUM( videoTimeBase.num ), INT2NUM( videoTimeBase.den ) );
848
+ } catch ( exception &e ) {
849
+ rb_raise( rb_eRuntimeError, "%s", e.what() );
850
+ };
851
+ return retVal;
852
+ }
853
+
854
+ VALUE AVOutput::wrapAudioTimeBase( VALUE rbSelf )
855
+ {
856
+ VALUE retVal = Qnil;
857
+ try {
858
+ AVOutputPtr *self; Data_Get_Struct( rbSelf, AVOutputPtr, self );
859
+ AVRational audioTimeBase = (*self)->audioTimeBase();
860
+ retVal = rb_funcall( rb_cObject, rb_intern( "Rational" ), 2,
861
+ INT2NUM( audioTimeBase.num ), INT2NUM( audioTimeBase.den ) );
862
+ } catch ( exception &e ) {
863
+ rb_raise( rb_eRuntimeError, "%s", e.what() );
864
+ };
865
+ return retVal;
866
+ }
867
+
822
868
  VALUE AVOutput::wrapFrameSize( VALUE rbSelf )
823
869
  {
824
870
  VALUE rbRetVal = Qnil;
data/ext/avoutput.hh CHANGED
@@ -48,6 +48,8 @@ public:
48
48
  enum CodecID audioCodec ) throw (Error);
49
49
  virtual ~AVOutput(void);
50
50
  void close(void);
51
+ AVRational videoTimeBase(void) throw (Error);
52
+ AVRational audioTimeBase(void) throw (Error);
51
53
  int frameSize(void) throw (Error);
52
54
  int channels(void) throw (Error);
53
55
  void writeVideo( FramePtr frame ) throw (Error);
@@ -61,6 +63,8 @@ public:
61
63
  VALUE rbVideoCodec, VALUE rbAudioBitRate, VALUE rbSampleRate,
62
64
  VALUE rbChannels, VALUE rbAudioCodec );
63
65
  static VALUE wrapClose( VALUE rbSelf );
66
+ static VALUE wrapVideoTimeBase( VALUE rbSelf );
67
+ static VALUE wrapAudioTimeBase( VALUE rbSelf );
64
68
  static VALUE wrapFrameSize( VALUE rbSelf );
65
69
  static VALUE wrapChannels( VALUE rbSelf );
66
70
  static VALUE wrapWriteVideo( VALUE rbSelf, VALUE rbFrame );
@@ -68,14 +72,14 @@ public:
68
72
  protected:
69
73
  std::string m_mrl;
70
74
  AVFormatContext *m_oc;
71
- AVStream *m_video_st;
72
- AVStream *m_audio_st;
73
- bool m_video_codec_open;
74
- bool m_audio_codec_open;
75
- char *m_video_buf;
76
- char *m_audio_buf;
77
- bool m_file_open;
78
- bool m_header_written;
75
+ AVStream *m_videoStream;
76
+ AVStream *m_audioStream;
77
+ bool m_videoCodecOpen;
78
+ bool m_audioCodecOpen;
79
+ char *m_videoBuf;
80
+ char *m_audioBuf;
81
+ bool m_fileOpen;
82
+ bool m_headerWritten;
79
83
  struct SwsContext *m_swsContext;
80
84
  AVFrame *m_frame;
81
85
  };
@@ -93,10 +93,18 @@ module Hornetseye
93
93
  orig_duration == AV_NOPTS_VALUE ? nil : orig_duration * video_time_base
94
94
  end
95
95
 
96
- alias_method :orig_start_time, :start_time
96
+ alias_method :orig_video_start_time, :video_start_time
97
97
 
98
98
  def video_start_time
99
- orig_start_time == AV_NOPTS_VALUE ? nil : orig_start_time * video_time_base
99
+ retval = orig_video_start_time
100
+ retval == AV_NOPTS_VALUE ? nil : retval * video_time_base
101
+ end
102
+
103
+ alias_method :orig_audio_start_time, :audio_start_time
104
+
105
+ def audio_start_time
106
+ retval = orig_audio_start_time
107
+ retval == AV_NOPTS_VALUE ? nil : retval * audio_time_base
100
108
  end
101
109
 
102
110
  alias_method :orig_aspect_ratio, :aspect_ratio
@@ -48,14 +48,14 @@ module Hornetseye
48
48
 
49
49
  end
50
50
 
51
- alias_method :write, :write_video
52
-
53
51
  alias_method :orig_write_video, :write_video
54
52
 
55
53
  def write_video( frame )
56
54
  orig_write_video frame.to_yv12
57
55
  end
58
56
 
57
+ alias_method :write, :write_video
58
+
59
59
  alias_method :orig_write_audio, :write_audio
60
60
 
61
61
  def write_audio( frame )
@@ -86,8 +86,9 @@ module Hornetseye
86
86
  end
87
87
  end
88
88
  if remaining.shape.last > 0
89
- @audio_buffer[ 0 ... channels, 0 ... remaining.shape.last ] = remaining
90
- @audio_samples = remaining.shape.last
89
+ @audio_buffer[ 0 ... channels, @audio_samples ... @audio_samples +
90
+ remaining.shape.last ] = remaining
91
+ @audio_samples += remaining.shape.last
91
92
  end
92
93
  frame
93
94
  end
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 8
8
- - 0
9
- version: 0.8.0
8
+ - 1
9
+ version: 0.8.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Jan Wedekind