hornetseye-ffmpeg 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
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