video.h
説明を見る。
1 //
2 // Copyright (c) 2003-2011, MIST Project, Nagoya University
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification,
6 // are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // 3. Neither the name of the Nagoya University nor the names of its contributors
16 // may be used to endorse or promote products derived from this software
17 // without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
20 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
21 // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 //
28 
33 
34 #ifndef __INCLUDE_IO_VIDEO_H__
35 #define __INCLUDE_IO_VIDEO_H__
36 
37 #ifndef __INCLUDE_MIST_H__
38 #include "../mist.h"
39 #endif
40 
41 #ifndef __INCLUDE_MIST_COLOR_H__
42 #include "../config/color.h"
43 #endif
44 
45 #ifndef __INCLUDE_MIST_SINGLETON__
46 #include "../singleton.h"
47 #endif
48 
49 #ifndef __INCLUDE_MIST_LIMITS__
50 #include "../limits.h"
51 #endif
52 
53 #include <string>
54 
55 extern "C"
56 {
57  #include <libavcodec/avcodec.h>
58  #include <libavformat/avformat.h>
59  #include <libswscale/swscale.h>
60  #include <libavutil/avutil.h>
61  #include <libavutil/mathematics.h>
62 }
63 
64 
65 // mist名前空間の始まり
67 
68 
69 
117 
118 
120 namespace video
121 {
122  class video_io_vase
123  {
124  public:
125  typedef size_t size_type;
126  typedef ptrdiff_t difference_type;
127 
128 #if LIBAVCODEC_VERSION_MAJOR < 55
129  typedef CodecID codec_id_type;
130 #else
131  typedef AVCodecID codec_id_type;
132 #endif
133 
134 #if LIBAVCODEC_VERSION_MAJOR < 53
135  static const CodecType avmedia_type_video_id = CODEC_TYPE_VIDEO;
136 #else
137  static const AVMediaType avmedia_type_video_id = AVMEDIA_TYPE_VIDEO;
138 #endif
139 
140  public:
141  virtual ~video_io_vase( ){ }
142 
143  bool open( const std::wstring &filename ){ return( open( wstr2str( filename ) ) ); }
144 
145  virtual bool open( const std::string &filename ) = 0;
146  virtual bool close( ) = 0;
147  virtual bool is_open( ) const = 0;
148  virtual bool is_eof( ) const = 0;
149  virtual bool dump( ) const = 0;
150  virtual long double time( ) const = 0;
151  virtual long double duration( ) const = 0;
152  virtual const std::string filename( ) const = 0;
153  virtual size_type bit_rate( ) const = 0;
154  virtual size_type width( ) const = 0;
155  virtual size_type height( ) const = 0;
156  virtual long double frame_rate_numerator( ) const = 0;
157  virtual long double frame_rate_denominator( ) const = 0;
158  virtual long double frame_aspect_ratio( ) const = 0;
159 
161  virtual long double frame_rate( ) const
162  {
163  return( frame_rate_denominator( ) / frame_rate_numerator( ) );
164  }
165 
167  virtual long double seconds_per_frame( ) const
168  {
169  return( frame_rate_numerator( ) / frame_rate_denominator( ) );
170  }
171 
172  protected:
173  AVOutputFormat *guess_video_format( const std::string &filename, const std::string &video_type, const std::string &mime_type )
174  {
175  AVOutputFormat *fmt = NULL;
176 
177  const char *fname = filename.empty( ) ? NULL : filename.c_str( );
178  const char *sname = video_type.empty( ) ? NULL : video_type.c_str( );
179  const char *mime = mime_type.empty( ) ? NULL : mime_type.c_str( );
180 
181  if( fname != NULL || sname != NULL || mime != NULL )
182  {
183  // ファイルの拡張子からフォーマットを推測する
184 #if LIBAVFORMAT_VERSION_MAJOR < 53
185  fmt = guess_format( sname, fname, mime );
186 #else
187  fmt = av_guess_format( sname, fname, mime );
188 #endif
189  if( fmt == NULL )
190  {
191  std::cout << "Could not determine output format from file extension. MPEG is used as default." << std::endl;
192 #if LIBAVFORMAT_VERSION_MAJOR < 53
193  fmt = guess_format( "mpeg", NULL, NULL );
194 #else
195  fmt = av_guess_format( "mpeg", NULL, NULL );
196 #endif
197  if( fmt == NULL )
198  {
199  std::cerr << "Could not find MPEG encoder." << std::endl;
200  return( NULL );
201  }
202  }
203  }
204  else
205  {
206 #if LIBAVFORMAT_VERSION_MAJOR < 53
207  fmt = guess_format( "mpeg", NULL, NULL );
208 #else
209  fmt = av_guess_format( "mpeg", NULL, NULL );
210 #endif
211 
212  if( fmt == NULL )
213  {
214  std::cerr << "Could not find specified video format." << std::endl;
215  return( NULL );
216  }
217  }
218 
219  return( fmt );
220  }
221 
222  AVOutputFormat *find_video_format( codec_id_type codec_id )
223  {
224  AVOutputFormat *fmt = av_oformat_next( NULL );
225  while( fmt != NULL )
226  {
227  if( fmt->video_codec == codec_id )
228  {
229  return( fmt );
230  }
231 
232  fmt = av_oformat_next( fmt );
233  }
234 
235  return( NULL );
236  }
237 
238  AVFrame *allocate_frame( int w, int h, PixelFormat pix_fmt )
239  {
240  // 処理用のフレームバッファを用意する
241  AVFrame *frame = avcodec_alloc_frame( );
242  if( frame == NULL )
243  {
244  return( NULL );
245  }
246  else
247  {
248  int size = avpicture_get_size( pix_fmt, w, h );
249  uint8_t *buff = ( uint8_t * )av_malloc( size );
250  avpicture_fill( ( AVPicture * )frame, buff, pix_fmt, w, h );
251 
252  return( frame );
253  }
254  }
255 
256  void free_frame( AVFrame **frame )
257  {
258  if( frame != NULL )
259  {
260  av_free( ( *frame )->data[ 0 ] );
261  av_free( ( *frame ) );
262  *frame = NULL;
263  }
264  }
265  };
266 
271  class decoder : public video_io_vase
272  {
273  private:
274  AVFormatContext *p_fctx_;
275  AVFrame *p_frame_src_;
276  AVFrame *p_frame_rgb_;
277  bool is_open_;
278  bool is_eof_;
279  int video_stream_index_;
280  SwsContext *p_swscale_;
281  int64_t frame_pts_;
282 
283  public:
288  decoder( ) : p_fctx_( NULL ), p_frame_src_( NULL ), p_frame_rgb_( NULL ), is_open_( false ), is_eof_( true ), video_stream_index_( -1 ), p_swscale_( NULL ), frame_pts_( -1 )
289  {
290  bool &bInitialized = singleton< bool, 60602 >::get_instance( );
291  if( !bInitialized )
292  {
293  avcodec_register_all( );
294  //avdevice_register_all( );
295  av_register_all( );
296  bInitialized = true;
297  }
298  }
299 
304  decoder( const std::string &filename ) : p_fctx_( NULL ), p_frame_src_( NULL ), p_frame_rgb_( NULL ), is_open_( false ), is_eof_( true ), video_stream_index_( -1 ), p_swscale_( NULL ), frame_pts_( -1 )
305  {
306  bool &bInitialized = singleton< bool, 60602 >::get_instance( );
307  if( !bInitialized )
308  {
309  avcodec_register_all( );
310  //avdevice_register_all( );
311  av_register_all( );
312  bInitialized = true;
313  }
314 
315  if( !open( filename ) )
316  {
317  throw;
318  }
319  }
320 
323  virtual ~decoder( )
324  {
325  close( );
326  }
327 
328 
329  public:
331  virtual bool is_open( ) const { return( is_open_ ); }
332 
334  virtual bool is_eof( ) const { return( is_eof_ ); }
335 
337  virtual int codec_id( ) const
338  {
339  if( is_open( ) && video_stream_index_ >= 0 )
340  {
341  return( p_fctx_->streams[ video_stream_index_ ]->codec->codec_id );
342  }
343  else
344  {
345  return( CODEC_ID_NONE );
346  }
347  }
348 
350  virtual bool dump( ) const
351  {
352  if( is_open( ) )
353  {
354 #if LIBAVFORMAT_VERSION_MAJOR < 54
355  dump_format( p_fctx_, 0, p_fctx_->filename, false );
356 #else
357  av_dump_format( p_fctx_, 0, p_fctx_->filename, false );
358 #endif
359  return( true );
360  }
361  else
362  {
363  return( false );
364  }
365  }
366 
368  virtual long double time( ) const
369  {
370  if( is_open( ) )
371  {
372  return( static_cast< long double >( frame_pts_ ) / static_cast< long double >( AV_TIME_BASE ) );
373  }
374  else
375  {
376  return( -1.0 );
377  }
378  }
379 
381  virtual int64_t frame_id( ) const
382  {
383  if( is_open( ) )
384  {
385  AVStream *stream = p_fctx_->streams[ video_stream_index_ ];
386  return( av_rescale( frame_pts_, stream->time_base.den, stream->time_base.num, AV_TIME_BASE ) );
387  }
388  else
389  {
390  return( 0 );
391  }
392  }
393 
395  virtual long double duration( ) const
396  {
397  if( is_open( ) )
398  {
399  AVStream *stream = p_fctx_->streams[ video_stream_index_ ];
400  int64_t pts = p_fctx_->streams[ video_stream_index_ ]->duration * AV_TIME_BASE;
401  return( static_cast< long double >( av_rescale( pts, stream->time_base.num, stream->time_base.den, AV_TIME_BASE ) ) );
402  }
403  else
404  {
405  return( -1 );
406  }
407  }
408 
410  virtual int64_t number_of_frames( ) const
411  {
412  if( is_open( ) )
413  {
414  return( p_fctx_->streams[ video_stream_index_ ]->duration );
415  }
416  else
417  {
418  return( 0 );
419  }
420  }
421 
423  virtual const std::string filename( ) const
424  {
425  if( is_open( ) )
426  {
427  return( p_fctx_->filename );
428  }
429  else
430  {
431  return( "" );
432  }
433  }
434 
436  virtual size_type bit_rate( ) const
437  {
438  if( is_open( ) )
439  {
440  return( p_fctx_->streams[ video_stream_index_ ]->codec->bit_rate );
441  }
442  else
443  {
444  return( 0 );
445  }
446  }
447 
449  virtual size_type width( ) const
450  {
451  if( is_open( ) )
452  {
453  return( p_fctx_->streams[ video_stream_index_ ]->codec->width );
454  }
455  else
456  {
457  return( 0 );
458  }
459  }
460 
462  virtual size_type height( ) const
463  {
464  if( is_open( ) )
465  {
466  return( p_fctx_->streams[ video_stream_index_ ]->codec->height );
467  }
468  else
469  {
470  return( 0 );
471  }
472  }
473 
475  virtual long double frame_rate_numerator( ) const
476  {
477  if( is_open( ) )
478  {
479  return( p_fctx_->streams[ video_stream_index_ ]->codec->time_base.num );
480  }
481  else
482  {
483  return( 0 );
484  }
485  }
486 
488  virtual long double frame_rate_denominator( ) const
489  {
490  if( is_open( ) )
491  {
492  return( p_fctx_->streams[ video_stream_index_ ]->codec->time_base.den );
493  }
494  else
495  {
496  return( 0 );
497  }
498  }
499 
501  virtual long double frame_aspect_ratio( ) const
502  {
503  if( is_open( ) )
504  {
505  return( av_q2d( p_fctx_->streams[ video_stream_index_ ]->codec->sample_aspect_ratio ) * ( double )this->width( ) / this->height( ) );
506  }
507  else
508  {
509  return( 4.0 / 3.0 );
510  }
511  }
512 
513  public:
518  virtual bool open( const std::string &filename )
519  {
520  if( !is_open( ) )
521  {
522  if( p_fctx_ != NULL )
523  {
524  av_close_input_file( p_fctx_ );
525  p_fctx_ = NULL;
526  }
527 
528  p_fctx_ = avformat_alloc_context( );
529  if( p_fctx_ == NULL )
530  {
531  printf( "Couldn't allocate avformat context\n" );
532  return( false );
533  }
534 
535  //p_fctx_->flags |= AVFMT_FLAG_NONBLOCK;
536  //p_fctx_->flags |= AVFMT_FLAG_GENPTS;
537  //p_fctx_->flags |= AVFMT_FLAG_SORT_DTS;
538 
539  // ファイルのヘッダ情報を読み取ってビデオフォーマットを取得する
540 #if LIBAVFORMAT_VERSION_MAJOR < 54
541  if( av_open_input_file( &p_fctx_, filename.c_str( ), NULL, 0, NULL ) != 0 )
542 #else
543  if( avformat_open_input( &p_fctx_, filename.c_str( ), NULL, NULL ) != 0 )
544 #endif
545  {
546  printf( "Couldn't open file %s\n", filename.c_str( ) );
547  return( false );
548  }
549 
550  // ファイルからストリーム情報を取得する
551 #if LIBAVFORMAT_VERSION_MAJOR < 55
552  if( av_find_stream_info( p_fctx_ ) < 0 )
553 #else
554  if( avformat_find_stream_info( p_fctx_, NULL ) < 0 )
555 #endif
556  {
557  printf( "Couldn't find stream information\n" );
558  return( false );
559  }
560 
561  // ビデオストリームを探す
562  video_stream_index_ = -1;
563  for( unsigned int i = 0 ; i < p_fctx_->nb_streams ; i++ )
564  {
565  if( p_fctx_->streams[ i ]->codec->codec_type == avmedia_type_video_id )
566  {
567  video_stream_index_ = i;
568  break;
569  }
570  }
571 
572  // ビデオストリームが見つからなかったので終了する
573  if( video_stream_index_ == -1 )
574  {
575  printf( "Didn't find a video stream\n" );
576  return( false );
577  }
578 
579  AVCodecContext *p_cctx = p_fctx_->streams[ video_stream_index_ ]->codec;
580 
581  // 対応するコーデックを取得する
582  AVCodec *p_codec = avcodec_find_decoder( p_cctx->codec_id );
583  if( p_codec == NULL )
584  {
585  printf( "Codec %d not found\n", p_cctx->codec_id );
586  return( false );
587  }
588 
589  // コーデックを開く
590 #if LIBAVCODEC_VERSION_MAJOR < 55
591  if( avcodec_open( p_cctx, p_codec ) < 0 )
592 #else
593  if( avcodec_open2( p_cctx, p_codec, NULL ) < 0 )
594 #endif
595  {
596  printf( "Could not open codec\n" );
597  return( false );
598  }
599 
600  // フレームを管理するオブジェクトを作成する
601  p_frame_src_ = avcodec_alloc_frame( );
602  p_frame_rgb_ = allocate_frame( p_cctx->width, p_cctx->height, PIX_FMT_BGR24 );
603 
604  // 画像の変換用のフィルタを設定する
605  p_swscale_ = sws_getContext( p_cctx->width, p_cctx->height, p_cctx->pix_fmt, p_cctx->width, p_cctx->height, PIX_FMT_BGR24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
606 
607  // ファイルのオープンに成功したフラグを設定する
608  is_open_ = true;
609  is_eof_ = false;
610 
611  // 先頭フレームを読み込んでおく
612  this->skip( 1 );
613 
614  // 先頭をうまく読めない場合は再度先頭に戻す
615  if( frame_pts_ != 0 )
616  {
617  this->seek_frame( 0 );
618  }
619 
620  return( true );
621  }
622 
623  return( false );
624  }
625 
628  virtual bool close( )
629  {
630  if( is_open( ) )
631  {
632  // フィルタを解放する
633  sws_freeContext( p_swscale_ );
634 
635  // コーデックを閉じる
636  avcodec_close( p_fctx_->streams[ video_stream_index_ ]->codec );
637 
638  // ファイルを閉じる
639  av_close_input_file( p_fctx_ );
640  p_fctx_ = NULL;
641 
642  // 一時フレーム領域を解放する
643  av_free( p_frame_src_);
644 
645  // 画像変換用フレーム領域を解放する
646  free_frame( &p_frame_rgb_ );
647 
648  is_open_ = false;
649 
650  return( true );
651  }
652 
653  return( false );
654  }
655 
660  bool skip( difference_type nskips = 1 )
661  {
662  if( is_open( ) && !this->is_eof( ) )
663  {
664  return( decode( nskips ) && !is_eof( ) );
665  }
666  else
667  {
668  return( false );
669  }
670  }
671 
676  bool seek( long double tm )
677  {
678  if( is_open( ) && tm >= 0 )
679  {
680  AVStream *stream = p_fctx_->streams[ video_stream_index_ ];
681  int64_t tgt = static_cast< int64_t >( AV_TIME_BASE * tm );
682  int64_t pts = av_rescale( tgt, stream->time_base.den, stream->time_base.num, AV_TIME_BASE );
683 
684  if( av_seek_frame( p_fctx_, video_stream_index_, pts, AVSEEK_FLAG_BACKWARD ) >= 0 )
685  {
686  return( decode( -1, tgt ) );
687  }
688  }
689 
690  return( false );
691  }
692 
697  bool seek_frame( int64_t fno )
698  {
699  if( is_open( ) && fno >= 0 )
700  {
701  if( av_seek_frame( p_fctx_, video_stream_index_, fno, AVSEEK_FLAG_BACKWARD ) >= 0 )
702  {
703  AVStream *stream = p_fctx_->streams[ video_stream_index_ ];
704  return( decode( -1, av_rescale_( AV_TIME_BASE, fno, stream->time_base.num, stream->time_base.den ) ) );
705  }
706  }
707 
708  return( false );
709  }
710 
715  template < class T, class Allocator >
716  bool read_buffer( array2< T, Allocator > &image )
717  {
718  typedef _pixel_converter_< T > pixel_converter;
719  typedef typename pixel_converter::color_type color_type;
720 
721  if( is_open( ) && !this->is_eof( ) )
722  {
723  AVCodecContext *p_cctx = p_fctx_->streams[ video_stream_index_ ]->codec;
724 
725  // 画像のサイズを調整する
726  image.resize( p_cctx->width, p_cctx->height );
727 
728  unsigned char *p = p_frame_rgb_->data[ 0 ];
729 
730  if( ( image.width( ) % 2 ) == 0 )
731  {
732  for( size_type i = 0 ; i < image.size( ) ; i++ )
733  {
734  image[ i ] = pixel_converter::convert_to( p[ 2 ], p[ 1 ], p[ 0 ] );
735  p += 3;
736  }
737  }
738  else
739  {
740  typename array2< T, Allocator >::pointer pi = &image[ 0 ];
741  size_type stride = p_frame_rgb_->linesize[ 0 ];
742  for( size_type j = 0 ; j < image.height( ) ; j++ )
743  {
744  for( size_type i = 0 ; i < stride ; i += 3 )
745  {
746  *pi++ = pixel_converter::convert_to( p[ i + 2 ], p[ i + 1 ], p[ i ] );
747  }
748  p += stride;
749  }
750  }
751 
752  return( true );
753  }
754  else
755  {
756  return( false );
757  }
758  }
759 
766  template < class T >
767  bool read( array2< T > &image )
768  {
769  if( read_buffer( image ) )
770  {
771  this->skip( 1 );
772  return( true );
773  }
774  else
775  {
776  return( false );
777  }
778  }
779 
787  template < class T >
788  bool read( array2< T > &image, long double &frame_time )
789  {
790  frame_time = this->time( );
791  if( read_buffer( image ) )
792  {
793  this->skip( 1 );
794  return( true );
795  }
796  else
797  {
798  return( false );
799  }
800  }
801 
802  protected:
808  bool decode( difference_type ntimes = 1, int64_t pts = type_limits< int64_t >::maximum( ) )
809  {
810  if( is_open( ) && !this->is_eof( ) && pts >= 0 )
811  {
812  if( ntimes >= 0 )
813  {
814  if( ntimes == 0 )
815  {
816  return( true );
817  }
818 
819  AVPacket packet;
820  AVStream *stream = p_fctx_->streams[ video_stream_index_ ];
821  AVCodecContext *p_cctx = stream->codec;
822  int bFinished = 0;
823 
824  frame_pts_ = 0;
825  for( difference_type i = 1 ; !is_eof( ) && i <= ntimes && frame_pts_ < pts ; i++ )
826  {
827  bFinished = 0;
828  while( bFinished == 0 && !is_eof( ) )
829  {
830  is_eof_ = av_read_frame( p_fctx_, &packet ) < 0;
831 
832  // 動画ストリームを探す
833  if( packet.stream_index == video_stream_index_ )
834  {
835  frame_pts_ = av_rescale_( AV_TIME_BASE, packet.pts < 0 ? packet.dts : packet.pts, ( int64_t ) stream->time_base.num, stream->time_base.den );
836 
837  if( !is_eof( ) )
838  {
839  // パケットをでコードする
840  avcodec_get_frame_defaults( p_frame_src_ );
841 #if LIBAVCODEC_VERSION_MAJOR < 53
842  avcodec_decode_video( p_cctx, p_frame_src_, &bFinished, packet.data, packet.size );
843 #else
844  avcodec_decode_video2( p_cctx, p_frame_src_, &bFinished, &packet );
845 #endif
846  }
847  }
848 
849  if( bFinished != 0 && ( i == ntimes || frame_pts_ >= pts ) )
850  {
851  // 一時バッファにデータをコピーする
852  sws_scale( p_swscale_, p_frame_src_->data, p_frame_src_->linesize, 0, p_cctx->height, p_frame_rgb_->data, p_frame_rgb_->linesize );
853  }
854 
855  av_free_packet( &packet );
856  }
857  }
858 
859  return( bFinished != 0 );
860  }
861  else
862  {
863  AVPacket packet;
864  AVStream *stream = p_fctx_->streams[ video_stream_index_ ];
865  AVCodecContext *p_cctx = stream->codec;
866  int bFinished = 0;
867 
868  frame_pts_ = pts - 1;
869  for( difference_type i = 1 ; !is_eof( ) && frame_pts_ < pts ; i++ )
870  {
871  bFinished = 0;
872  while( bFinished == 0 && !is_eof( ) )
873  {
874  is_eof_ = av_read_frame( p_fctx_, &packet ) < 0;
875 
876  // 動画ストリームを探す
877  if( packet.stream_index == video_stream_index_ )
878  {
879  frame_pts_ = av_rescale_( AV_TIME_BASE, packet.pts < 0 ? packet.dts : packet.pts, ( int64_t ) stream->time_base.num, stream->time_base.den );
880 
881  if( !is_eof( ) )
882  {
883  // パケットをでコードする
884  avcodec_get_frame_defaults( p_frame_src_ );
885 #if defined( LIBAVCODEC_VERSION_MAJOR ) && LIBAVCODEC_VERSION_MAJOR >= 53
886  avcodec_decode_video2( p_cctx, p_frame_src_, &bFinished, &packet );
887 #else
888  avcodec_decode_video( p_cctx, p_frame_src_, &bFinished, packet.data, packet.size );
889 #endif
890  }
891  }
892 
893  if( bFinished != 0 && frame_pts_ >= pts )
894  {
895  // 一時バッファにデータをコピーする
896  sws_scale( p_swscale_, p_frame_src_->data, p_frame_src_->linesize, 0, p_cctx->height, p_frame_rgb_->data, p_frame_rgb_->linesize );
897  }
898 
899  av_free_packet( &packet );
900  }
901  }
902 
903  return( bFinished != 0 );
904  }
905  }
906  else
907  {
908  return( false );
909  }
910  }
911 
912  int64_t av_rescale( int64_t a, int64_t b, int64_t c ) const
913  {
914  long double A = static_cast< long double >( a );
915  long double B = static_cast< long double >( b );
916  long double C = static_cast< long double >( c );
917  long double D = A * ( B / C );
918  return( static_cast< int64_t >( D + 0.5 ) );
919  }
920 
921  int64_t av_rescale_( int64_t s, int64_t a, int64_t b, int64_t c ) const
922  {
923  long double S = static_cast< long double >( s );
924  long double A = static_cast< long double >( a );
925  long double B = static_cast< long double >( b );
926  long double C = static_cast< long double >( c );
927  long double D = S * ( A * ( B / C ) );
928  return( static_cast< int64_t >( D + 0.5 ) );
929  }
930 
931  int64_t av_rescale( int64_t a, int64_t b, int64_t c, int64_t d ) const
932  {
933  long double A = static_cast< long double >( a );
934  long double B = static_cast< long double >( b );
935  long double C = static_cast< long double >( c );
936  long double D = static_cast< long double >( d );
937  long double BC = B / C;
938  long double AD = A / D;
939  return( static_cast< int64_t >( AD * BC + 0.5 ) );
940  }
941 
942  public: // オペレータの実装
944  decoder & operator ++( )
945  {
946  this->skip( 1 );
947  return( *this );
948  }
949 
951  decoder & operator --( )
952  {
953  this->seek_frame( this->frame_id( ) - 1 );
954  //this->seek( this->time( ) - this->seconds_per_frame( ) );
955  return( *this );
956  }
957 
962  decoder & operator +=( difference_type fno )
963  {
964  this->skip( fno );
965  return( *this );
966  }
967 
972  decoder & operator -=( difference_type fno )
973  {
974  this->seek_frame( this->frame_id( ) - fno );
975  return( *this );
976  }
977  };
978 
979 
980 
985  class encoder : public video_io_vase
986  {
987  protected:
988  AVFormatContext *p_fctx_;
989  AVFrame *p_frame_dst_;
990  AVFrame *p_frame_rgb_;
991  SwsContext *p_swscale_;
992  int64_t frame_pts_;
993 
994  bool is_open_;
995  uint8_t* encode_buf_;
996  size_type encode_buf_size_;
997  size_type width_;
998  size_type height_;
999  size_type source_width_;
1000  size_type source_height_;
1001  size_type frame_rate_num_;
1002  size_type frame_rate_den_;
1004  size_type bit_rate_;
1005  size_type qmin_;
1006  size_type qmax_;
1007  size_type gop_size_;
1008  size_type max_b_frames_;
1009  size_type audio_bit_rate_;
1011  size_type audio_channels_;
1012 
1013  public:
1030  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0,
1031  size_type bit_rate = 1150000, size_type qmin = 0, size_type qmax = 0, size_type gop_size = 12, size_type max_b_frames = 2, size_type audio_bit_rate = 64000, size_type audio_sampling_rate = 44100, size_type audio_channels = 2 )
1032  : p_fctx_( NULL ), p_frame_dst_( NULL ), p_frame_rgb_( NULL ), p_swscale_( NULL ), frame_pts_( 0 ), is_open_( false ), encode_buf_( NULL ), encode_buf_size_( 0 ),
1033  width_( w ), height_( h ), source_width_( w ), source_height_( h ), frame_rate_num_( frame_rate_num ), frame_rate_den_( frame_rate_den ), frame_aspect_ratio_( frame_aspect_ratio ), bit_rate_( bit_rate ), qmin_( qmin ), qmax_( qmax ),
1034  gop_size_( gop_size ), max_b_frames_( max_b_frames ), audio_bit_rate_( audio_bit_rate ), audio_sampling_rate_( audio_bit_rate ), audio_channels_( audio_channels )
1035  {
1036  bool &bInitialized = singleton< bool, 60602 >::get_instance( );
1037  if( !bInitialized )
1038  {
1039  avcodec_register_all( );
1040  //avdevice_register_all( );
1041  av_register_all( );
1042  bInitialized = true;
1043  }
1044  }
1045 
1048  virtual ~encoder( )
1049  {
1050  close( );
1051  }
1052 
1053  public:
1055  virtual bool is_open( ) const { return( is_open_ ); }
1056 
1058  virtual bool is_eof( ) const { return( false ); }
1059 
1061  virtual bool dump( ) const
1062  {
1063  if( is_open( ) )
1064  {
1065 #if LIBAVFORMAT_VERSION_MAJOR < 54
1066  dump_format( p_fctx_, 0, p_fctx_->filename, true );
1067 #else
1068  av_dump_format( p_fctx_, 0, p_fctx_->filename, true );
1069 #endif
1070  return( true );
1071  }
1072  else
1073  {
1074  return( false );
1075  }
1076  }
1077 
1079  virtual long double time( ) const
1080  {
1081  if( is_open( ) )
1082  {
1083  AVStream *stream = p_fctx_->streams[ 0 ];
1084  int64_t pts = av_rescale( frame_pts_ * AV_TIME_BASE, stream->time_base.num, stream->time_base.den );
1085  return( static_cast< long double >( pts ) / static_cast< long double >( AV_TIME_BASE ) );
1086  }
1087  else
1088  {
1089  return( -1 );
1090  }
1091  }
1092 
1094  virtual long double duration( ) const
1095  {
1096  if( is_open( ) )
1097  {
1098  return( time( ) );
1099  }
1100  else
1101  {
1102  return( -1 );
1103  }
1104  }
1105 
1107  virtual const std::string filename( ) const
1108  {
1109  if( is_open( ) )
1110  {
1111  return( p_fctx_->filename );
1112  }
1113  else
1114  {
1115  return( "" );
1116  }
1117  }
1118 
1120  virtual size_type bit_rate( ) const
1121  {
1122  return( bit_rate_ );
1123  }
1124 
1126  virtual size_type width( ) const
1127  {
1128  return( width_ );
1129  }
1130 
1132  virtual size_type height( ) const
1133  {
1134  return( height_ );
1135  }
1136 
1138  virtual long double frame_rate_numerator( ) const
1139  {
1140  return( frame_rate_num_ );
1141  }
1142 
1144  virtual long double frame_rate_denominator( ) const
1145  {
1146  return( frame_rate_den_ );
1147  }
1148 
1150  virtual long double frame_aspect_ratio( ) const
1151  {
1152  return( frame_aspect_ratio_ );
1153  }
1154 
1155  public:
1156  virtual bool open( const std::string &filename )
1157  {
1158  return( open( filename, filename, "", "" ) );
1159  }
1160 
1169  bool open( const std::string &filename, const std::string &format_type, const std::string &video_type, const std::string &mime_type, codec_id_type codec_id = CODEC_ID_NONE )
1170  {
1171  if( !is_open_ )
1172  {
1173  // 出力フォーマットを取得する
1174  AVOutputFormat *format = guess_video_format( format_type, video_type, mime_type );
1175  if( format == NULL )
1176  {
1177  std::cerr << "Could not find specified video format" << std::endl;
1178  return( false );
1179  }
1180  else
1181  {
1182  return( open( filename, format, codec_id ) );
1183  }
1184  }
1185  else
1186  {
1187  return( false );
1188  }
1189  }
1190 
1193  bool close( )
1194  {
1195  if( is_open_ )
1196  {
1197  // フィルタを解放する
1198  sws_freeContext( p_swscale_ );
1199 
1200  // ビデオファイル閉じる
1201  av_write_trailer( p_fctx_ );
1202 
1203  if( ( p_fctx_->oformat->flags & AVFMT_NOFILE ) == 0 )
1204  {
1205 #if defined( LIBAVCODEC_VERSION_MAJOR ) && LIBAVCODEC_VERSION_MAJOR >= 53
1206  if( avio_close( p_fctx_->pb ) < 0 )
1207 #else
1208  if( url_fclose( p_fctx_->pb ) < 0 )
1209 #endif
1210  {
1211  std::cerr << "Failed to close output file." << std::endl;
1212  return( false );
1213  }
1214  }
1215 
1216  // すべてのストリームを解放する
1217  for( size_type i = 0 ; i < p_fctx_->nb_streams ; i++ )
1218  {
1219  // CODECを閉じる
1220  if( p_fctx_->streams[ i ]->codec->codec_id != CODEC_ID_NONE )
1221  {
1222  avcodec_close( p_fctx_->streams[ i ]->codec );
1223  }
1224 
1225  av_freep( &( p_fctx_->streams[ i ] ->codec ) );
1226  av_freep( &( p_fctx_->streams[ i ] ) );
1227  }
1228 
1229  // エンコードに使用したバッファを解放
1230  if( encode_buf_ != NULL )
1231  {
1232  av_freep( &encode_buf_ );
1233  }
1234 
1235  // 残りのデータを解放する
1236  free_frame( &p_frame_dst_ );
1237  free_frame( &p_frame_rgb_ );
1238  av_freep( &p_fctx_ );
1239 
1240  is_open_ = false;
1241 
1242  return( true );
1243  }
1244  else
1245  {
1246  return( false );
1247  }
1248  }
1249 
1250  protected:
1259  bool open( const std::string &filename, AVOutputFormat *format, codec_id_type video_codec_id = CODEC_ID_NONE, codec_id_type audio_codec_id = CODEC_ID_NONE, PixelFormat default_pixel_format = PIX_FMT_YUV420P )
1260  {
1261  if( !is_open_ )
1262  {
1263  if( format == NULL )
1264  {
1265  std::cerr << "Could not find specified video format" << std::endl;
1266  return( false );
1267  }
1268 
1269 #if LIBAVFORMAT_VERSION_MAJOR < 53
1270  p_fctx_ = av_alloc_format_context( );
1271 #else
1272  p_fctx_ = avformat_alloc_context( );
1273 #endif
1274 
1275  if( p_fctx_ == NULL )
1276  {
1277  std::cerr << "Could not allocate format context" << std::endl;
1278  return( false );
1279  }
1280 
1281  p_fctx_->oformat = format;
1282 #ifdef WIN32
1283  _snprintf( p_fctx_->filename, sizeof( p_fctx_->filename ), "%s", filename.c_str( ) );
1284 #else
1285  snprintf( p_fctx_->filename, sizeof( p_fctx_->filename ), "%s", filename.c_str( ) );
1286 #endif
1287 
1288  AVStream *vstream = NULL;
1289  if( p_fctx_->oformat->video_codec != CODEC_ID_NONE )
1290  {
1291  vstream = av_new_stream( p_fctx_, 0 );
1292  if( vstream == NULL )
1293  {
1294  std::cerr << "Could not allocate video encode stream" << std::endl;
1295  return( false );
1296  }
1297 
1298  // コーデックを推測する
1299  if( video_codec_id == CODEC_ID_NONE )
1300  {
1301  video_codec_id = av_guess_codec( p_fctx_->oformat, NULL, p_fctx_->filename, NULL, avmedia_type_video_id );
1302  }
1303 
1304  // コーデックを探す
1305  AVCodec *codec = avcodec_find_encoder( video_codec_id );
1306  if( codec == NULL && p_fctx_->oformat->video_codec != CODEC_ID_NONE )
1307  {
1308  std::cerr << "Could not find appropriate Video Codec from the database." << std::endl;
1309  return( false );
1310  }
1311 
1312  // コーデックのデフォルト設定を行う
1313 #if LIBAVCODEC_VERSION_MAJOR < 55
1314  avcodec_get_context_defaults2( vstream->codec, avmedia_type_video_id );
1315 #else
1316  avcodec_get_context_defaults3( vstream->codec, codec );
1317 #endif
1318 
1319  // ビデオストリームにコーデック情報を指定する
1320  AVCodecContext *cctx = vstream->codec;
1321  cctx->codec_id = codec == NULL ? video_codec_id : codec->id;
1322  cctx->codec_type = avmedia_type_video_id;
1323 
1324  // 画像のサイズを設定
1325  cctx->width = static_cast< int >( width( ) );
1326  cctx->height = static_cast< int >( height( ) );
1327 
1328  // 画素フォーマットを設定
1329  cctx->pix_fmt = default_pixel_format;
1330 
1331  // ピクセルフォーマットの対応状況を調べる
1332  if( codec->pix_fmts )
1333  {
1334  const PixelFormat *p = codec->pix_fmts;
1335  for( ; *p != -1 ; p++ )
1336  {
1337  if( *p == cctx->pix_fmt )
1338  {
1339  break;
1340  }
1341  }
1342 
1343  /* 非対応の場合は対応する物に差し替え */
1344  if( *p == -1 )
1345  {
1346  cctx->pix_fmt = codec->pix_fmts[ 0 ];
1347  }
1348  }
1349 
1350  // ビットレートを設定
1351  cctx->bit_rate = static_cast< int >( bit_rate( ) );
1352 
1353  // 固定クオリティーが設定されている場合の処理
1354  if( qmin_ > 0 && qmax_ > 0 )
1355  {
1356  cctx->qmin = qmin_;
1357  cctx->qmax = qmax_;
1358  }
1359 
1360  // フレームレートを設定
1361  cctx->time_base.den = static_cast< int >( frame_rate_denominator( ) );
1362  cctx->time_base.num = static_cast< int >( frame_rate_numerator( ) );
1363 
1364  cctx->gop_size = gop_size_;
1365 
1366  // フレームのアスペクト比を設定する
1367  cctx->sample_aspect_ratio = vstream->sample_aspect_ratio = av_d2q( frame_aspect_ratio_ * cctx->height / cctx->width, 255 );
1368 
1369  if( cctx->codec_id == CODEC_ID_MPEG2VIDEO )
1370  {
1371  cctx->max_b_frames = static_cast< int >( max_b_frames_ );
1372  }
1373  if( cctx->codec_id == CODEC_ID_MPEG1VIDEO )
1374  {
1375  cctx->mb_decision = 2;
1376  }
1377 
1378  // グローバルヘッダの要求を調べる
1379  if( ( format->flags & AVFMT_GLOBALHEADER ) != 0 )
1380  {
1381  cctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
1382  }
1383 
1384 #if LIBAVFORMAT_VERSION_MAJOR < 54
1385  // パラメータを設定する
1386  if( av_set_parameters( p_fctx_, NULL ) < 0 )
1387  {
1388  std::cerr << "Invalid output format parameters" << std::endl;
1389  return( false );
1390  }
1391 #endif
1392 
1393  // コーデックを開く
1394 #if LIBAVCODEC_VERSION_MAJOR < 55
1395  if( avcodec_open( cctx, codec ) < 0 )
1396 #else
1397  if( avcodec_open2( cctx, codec, NULL ) < 0 )
1398 #endif
1399  {
1400  std::cerr << "Could not open codec." << std::endl;
1401  return( false );
1402  }
1403  }
1404 
1405  if( audio_codec_id != CODEC_ID_NONE )
1406  {
1407  AVStream *astream = av_new_stream( p_fctx_, 1 );
1408  if( astream == NULL )
1409  {
1410  std::cerr << "Could not allocate audio encode stream" << std::endl;
1411  return( false );
1412  }
1413 
1414  astream->codec->codec_id = audio_codec_id;
1415  astream->codec->codec_type = avmedia_type_video_id;
1416 
1417  // オーディオのストリームを設定する
1418  astream->codec->bit_rate = static_cast< int >( audio_bit_rate_ );
1419  astream->codec->sample_rate = static_cast< int >( audio_sampling_rate_ );
1420  astream->codec->channels = static_cast< int >( audio_channels_ );
1421 
1422  // コーデックを探す
1423  AVCodec *codec = avcodec_find_encoder( astream->codec->codec_id );
1424  if( codec == NULL )
1425  {
1426  std::cerr << "Could not find appropriate Audio Codec from the database." << std::endl;
1427  return( false );
1428  }
1429 
1430  // コーデックを開く
1431 #if LIBAVCODEC_VERSION_MAJOR < 55
1432  if( avcodec_open( astream->codec, codec ) < 0 )
1433 #else
1434  if( avcodec_open2( astream->codec, codec, NULL ) < 0 )
1435 #endif
1436  {
1437  std::cerr << "Could not open codec." << std::endl;
1438  return( false );
1439  }
1440  }
1441 
1442  // ファイルを開く
1443  if( ( p_fctx_->oformat->flags & AVFMT_NOFILE ) == 0 )
1444  {
1445 #if defined( AVIO_FLAG_WRITE )
1446  if( avio_open( &p_fctx_->pb, p_fctx_->filename, AVIO_FLAG_WRITE ) < 0 )
1447 #elif defined( URL_WRONLY )
1448  if( url_fopen( &p_fctx_->pb, p_fctx_->filename, URL_WRONLY ) < 0 )
1449 #else
1450  if( avio_open( &p_fctx_->pb, p_fctx_->filename, AVIO_WRONLY ) < 0 )
1451 #endif
1452  {
1453  std::cerr << "Could not open file " << filename << std::endl;
1454  return( false );
1455  }
1456  }
1457 
1458  //p_fctx_->preload = static_cast< int >( 0.5 * AV_TIME_BASE );
1459  p_fctx_->max_delay = static_cast< int >( 0.7 * AV_TIME_BASE );
1460  //p_fctx_->loop_output = AVFMT_NOOUTPUTLOOP;
1461 
1462  // ヘッダ情報を書き込む
1463 #if LIBAVFORMAT_VERSION_MAJOR < 54
1464  if( av_write_header( p_fctx_ ) != 0 )
1465 #else
1466  if( avformat_write_header( p_fctx_, NULL ) != 0 )
1467 #endif
1468  {
1469  std::cerr << "Failed to write video header" << std::endl;
1470  return( false );
1471  }
1472 
1473  encode_buf_ = NULL;
1474  encode_buf_size_ = width( ) * height( ) * 4;
1475  if( encode_buf_size_ < FF_MIN_BUFFER_SIZE )
1476  {
1477  encode_buf_size_ = FF_MIN_BUFFER_SIZE;
1478  }
1479 
1480  if( ( p_fctx_->oformat->flags & AVFMT_RAWPICTURE ) == 0 )
1481  {
1482  encode_buf_ = ( uint8_t * )av_malloc( encode_buf_size_ );
1483  }
1484 
1485  PixelFormat pix_fmt = vstream == NULL ? PIX_FMT_BGR24 : vstream->codec->pix_fmt;
1486 
1487  // エンコード用のフレームバッファを用意する
1488  p_frame_dst_ = allocate_frame( width( ), height( ), pix_fmt );
1489  if( p_frame_dst_ == NULL )
1490  {
1491  std::cerr << "Could not allocate frame buffer." << std::endl;
1492  return( false );
1493  }
1494 
1495  // 一時領域用のフレームバッファを用意する
1496  p_frame_rgb_ = allocate_frame( width( ), height( ), PIX_FMT_BGR24 );
1497  if( p_frame_dst_ == NULL )
1498  {
1499  std::cerr << "Could not allocate temporal frame buffer." << std::endl;
1500  return( false );
1501  }
1502 
1503  // 画像の変換用のフィルタを設定する
1504  source_width_ = width( );
1505  source_height_ = height( );
1506  p_swscale_ = sws_getContext( source_width_, source_height_, PIX_FMT_BGR24, width( ), height( ), pix_fmt, SWS_LANCZOS, NULL, NULL, NULL);
1507 
1508  is_open_ = true;
1509  frame_pts_ = 0;
1510 
1511  return( true );
1512  }
1513  else
1514  {
1515  return( false );
1516  }
1517  }
1518 
1519  public:
1525  template < class T, class Allocator >
1526  bool write( const array2< T, Allocator > &image, long double tm = -1.0 )
1527  {
1528  if( is_open( ) )
1529  {
1530  int ret = 0;
1531 
1532  if( source_width_ != image.width( ) || source_height_ != image.height( ) )
1533  {
1534  if( p_swscale_ != NULL )
1535  {
1536  // フィルタを解放する
1537  sws_freeContext( p_swscale_ );
1538 
1539  // フレームを解放する
1540  free_frame( &p_frame_rgb_ );
1541  }
1542 
1543  PixelFormat pix_fmt = p_fctx_->streams[ 0 ] == NULL ? PIX_FMT_BGR24 : p_fctx_->streams[ 0 ]->codec->pix_fmt;
1544 
1545  if( source_width_ < image.width( ) )
1546  {
1547  p_swscale_ = sws_getContext( image.width( ), image.height( ), PIX_FMT_BGR24, width( ), height( ), pix_fmt, SWS_AREA, NULL, NULL, NULL);
1548  }
1549  else
1550  {
1551  p_swscale_ = sws_getContext( image.width( ), image.height( ), PIX_FMT_BGR24, width( ), height( ), pix_fmt, SWS_LANCZOS, NULL, NULL, NULL);
1552  }
1553 
1554  source_width_ = image.width( );
1555  source_height_ = image.height( );
1556  p_frame_rgb_ = allocate_frame( source_width_, source_height_, PIX_FMT_BGR24 );
1557  }
1558 
1559  typedef _pixel_converter_< T > pixel_converter;
1560  typedef typename pixel_converter::color_type color_type;
1561 
1562  unsigned char *p = p_frame_rgb_->data[ 0 ];
1563  if( ( source_width_ % 2 ) == 0 )
1564  {
1565  for( size_type i = 0 ; i < image.size( ) ; i++ )
1566  {
1567  color_type c = pixel_converter::convert_from( image[ i ] );
1568  p[ 0 ] = c.b;
1569  p[ 1 ] = c.g;
1570  p[ 2 ] = c.r;
1571  p += 3;
1572  }
1573  }
1574  else
1575  {
1576  typename array2< T, Allocator >::const_pointer pi = &image[ 0 ];
1577  size_type stride = p_frame_rgb_->linesize[ 0 ];
1578  for( size_type j = 0 ; j < image.height( ) ; j++ )
1579  {
1580  for( size_type i = 0 ; i < stride ; i += 3 )
1581  {
1582  color_type c = pixel_converter::convert_from( *pi++ );
1583  p[ i + 0 ] = c.b;
1584  p[ i + 1 ] = c.g;
1585  p[ i + 2 ] = c.r;
1586  }
1587 
1588  p += stride;
1589  }
1590  }
1591 
1592  // 画像の形式を変換する
1593  sws_scale( p_swscale_, p_frame_rgb_->data, p_frame_rgb_->linesize, 0, source_height_, p_frame_dst_->data, p_frame_dst_->linesize );
1594 
1595  if( ( p_fctx_->oformat->flags & AVFMT_RAWPICTURE ) != 0 )
1596  {
1597  AVPacket packet;
1598  av_init_packet( &packet );
1599 
1600 #if defined( AV_PKT_FLAG_KEY )
1601  packet.flags |= AV_PKT_FLAG_KEY;
1602 #else
1603  packet.flags |= PKT_FLAG_KEY;
1604 #endif
1605  packet.stream_index = p_fctx_->streams[ 0 ]->index;
1606  packet.data = ( uint8_t * )p_frame_dst_;
1607  packet.size = sizeof( AVPicture );
1608  frame_pts_++;
1609 
1610  ret = av_write_frame( p_fctx_, &packet );
1611  }
1612  else
1613  {
1614  // 画像をエンコードする
1615  AVStream *stream = p_fctx_->streams[ 0 ];
1616  AVCodecContext *c = stream->codec;
1617  //p_frame_dst_->quality = static_cast< int >( stream->quality );
1618  p_frame_dst_->quality = 1;
1619  int out_size = avcodec_encode_video( c, encode_buf_, encode_buf_size_, p_frame_dst_ );
1620 
1621  if( out_size > 0 )
1622  {
1623  AVPacket packet;
1624  av_init_packet( &packet );
1625 
1626  packet.stream_index = stream->index;
1627  packet.data = encode_buf_;
1628  packet.size = out_size;
1629  if( tm < 0 )
1630  {
1631  packet.pts = av_rescale_q( c->coded_frame->pts, c->time_base, stream->time_base );
1632  frame_pts_ = static_cast< difference_type >( packet.pts );
1633  }
1634  else
1635  {
1636  packet.pts = av_rescale( static_cast< int64_t >( tm * AV_TIME_BASE ), stream->time_base.den, stream->time_base.num * AV_TIME_BASE );
1637  frame_pts_ = static_cast< difference_type >( packet.pts );
1638  }
1639 
1640  if( c->coded_frame->key_frame )
1641  {
1642 #if defined( AV_PKT_FLAG_KEY )
1643  packet.flags |= AV_PKT_FLAG_KEY;
1644 #else
1645  packet.flags |= PKT_FLAG_KEY;
1646 #endif
1647  }
1648 
1649  ret = av_interleaved_write_frame( p_fctx_, &packet );
1650  //ret = av_write_frame( p_fctx_, &packet );
1651  }
1652  else
1653  {
1654  ret = 0;
1655  }
1656  }
1657 
1658  return( ret != 0 );
1659  }
1660  else
1661  {
1662  return( false );
1663  }
1664  }
1665  };
1666 
1667  namespace mpeg1
1668  {
1673  class encoder : public video::encoder
1674  {
1675  private:
1676  typedef video::encoder base;
1677 
1678  public:
1692  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000, size_type qmin = 0, size_type qmax = 0, size_type gop_size = 12, size_type max_b_frames = 2 )
1693  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate, qmin, qmax, gop_size, max_b_frames )
1694  {
1695  }
1696 
1713  encoder( const std::string &filename, size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000, size_type qmin = 0, size_type qmax = 0, size_type gop_size = 12, size_type max_b_frames = 2 )
1714  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate, qmin, qmax, gop_size, max_b_frames )
1715  {
1716  if( !open( filename ) )
1717  {
1718  throw;
1719  }
1720  }
1721 
1724  virtual ~encoder( )
1725  {
1726  base::close( );
1727  }
1728 
1729  public:
1730  virtual bool open( const std::string &filename )
1731  {
1732  return( base::open( filename, ".mpg", "mpeg", "" ) );
1733  }
1734  };
1735  }
1736 
1737  namespace mpeg4
1738  {
1743  class encoder : public video::encoder
1744  {
1745  private:
1746  typedef video::encoder base;
1747 
1748  public:
1758  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000 )
1759  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate )
1760  {
1761  }
1762 
1775  encoder( const std::string &filename, size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000 )
1776  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate )
1777  {
1778  if( !open( filename ) )
1779  {
1780  throw;
1781  }
1782  }
1783 
1786  virtual ~encoder( )
1787  {
1788  base::close( );
1789  }
1790 
1791  public:
1792  virtual bool open( const std::string &filename )
1793  {
1794  //return( base::open( filename, "m4v", "" ) );
1795  return( base::open( filename, ".avi", "", "" ) );
1796  }
1797  };
1798  }
1799 
1800  namespace mjpeg
1801  {
1806  class encoder : public video::encoder
1807  {
1808  private:
1809  typedef video::encoder base;
1810 
1811  public:
1823  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 11500000, size_type qmin = 0, size_type qmax = 0 )
1824  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate, qmin, qmax, 0 )
1825  {
1826  }
1827 
1842  encoder( const std::string &filename, size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 11500000, size_type qmin = 0, size_type qmax = 0 )
1843  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate, qmin, qmax, 0 )
1844  {
1845  if( !open( filename ) )
1846  {
1847  throw;
1848  }
1849  }
1850 
1853  virtual ~encoder( )
1854  {
1855  base::close( );
1856  }
1857 
1858  public:
1859  virtual bool open( const std::string &filename )
1860  {
1861  //return( base::open( filename, "m4v", "" ) );
1862  return( base::open( filename, ".avi", "", "", CODEC_ID_MJPEG ) );
1863  }
1864  };
1865  }
1866 
1867  namespace h264
1868  {
1873  class encoder : public video::encoder
1874  {
1875  private:
1876  typedef video::encoder base;
1877 
1878  public:
1888  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000 )
1889  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate )
1890  {
1891  }
1892 
1905  encoder( const std::string &filename, size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000 )
1906  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate )
1907  {
1908  if( !open( filename ) )
1909  {
1910  throw;
1911  }
1912  }
1913 
1916  virtual ~encoder( )
1917  {
1918  base::close( );
1919  }
1920 
1921  public:
1922  virtual bool open( const std::string &filename )
1923  {
1924  //return( base::open( filename, "m4v", "" ) );
1925  return( base::open( filename, ".avi", "", "", CODEC_ID_H264 ) );
1926  }
1927  };
1928  }
1929 
1930  namespace wmv
1931  {
1936  class encoder : public video::encoder
1937  {
1938  private:
1939  typedef video::encoder base;
1940 
1941  public:
1951  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000 )
1952  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate )
1953  {
1954  }
1955 
1968  encoder( const std::string &filename, size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0, size_type bit_rate = 1150000 )
1969  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio, bit_rate )
1970  {
1971  if( !open( filename ) )
1972  {
1973  throw;
1974  }
1975  }
1976 
1979  virtual ~encoder( )
1980  {
1981  base::close( );
1982  }
1983 
1984  public:
1985  virtual bool open( const std::string &filename )
1986  {
1987  //return( base::open( filename, "m4v", "" ) );
1988  return( base::open( filename, ".wmv", "", "", CODEC_ID_WMV2 ) );
1989  }
1990  };
1991  }
1992 
1993  namespace dv
1994  {
1999  class encoder : public video::encoder
2000  {
2001  private:
2002  typedef video::encoder base;
2003 
2004  public:
2011  encoder( size_type w = 720, size_type h = 480, double frame_aspect_ratio = 4.0 / 3.0 )
2012  : base( w, h, 1001, 30000, frame_aspect_ratio )
2013  {
2014  audio_sampling_rate_ = 48000;
2015  }
2016 
2026  encoder( const std::string &filename, size_type w = 720, size_type h = 480, double frame_aspect_ratio = 4.0 / 3.0 )
2027  : base( w, h, 1001, 30000, frame_aspect_ratio )
2028  {
2029  audio_sampling_rate_ = 48000;
2030 
2031  if( !open( filename ) )
2032  {
2033  throw;
2034  }
2035  }
2036 
2039  virtual ~encoder( )
2040  {
2041  base::close( );
2042  }
2043 
2044  public:
2045  virtual bool open( const std::string &filename )
2046  {
2047  AVOutputFormat *fmt = guess_video_format( ".avi", "", "" );
2048  return( base::open( filename, fmt, CODEC_ID_DVVIDEO, CODEC_ID_NONE, PIX_FMT_YUV411P ) );
2049  }
2050  };
2051  }
2052 
2053  namespace raw
2054  {
2059  class encoder : public video::encoder
2060  {
2061  private:
2062  typedef video::encoder base;
2063 
2064  public:
2073  encoder( size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0 )
2074  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio )
2075  {
2076  }
2077 
2089  encoder( const std::string &filename, size_type w = 320, size_type h = 240, size_type frame_rate_num = 1, size_type frame_rate_den = 30, double frame_aspect_ratio = 4.0 / 3.0 )
2090  : base( w, h, frame_rate_num, frame_rate_den, frame_aspect_ratio )
2091  {
2092  if( !open( filename ) )
2093  {
2094  throw;
2095  }
2096  }
2097 
2100  virtual ~encoder( )
2101  {
2102  base::close( );
2103  }
2104 
2105  public:
2106  virtual bool open( const std::string &filename )
2107  {
2108  return( base::open( filename, ".avi", "", "", CODEC_ID_RAWVIDEO ) );
2109  }
2110  };
2111  }
2112 
2113 
2114  template < class T, class Allocator >
2115  inline decoder &operator >>( decoder &in, array2< T, Allocator > &img )
2116  {
2117  in.read( img );
2118  return( in );
2119  }
2120 
2121  template < class T, class Allocator >
2122  inline encoder &operator <<( encoder &in, array2< T, Allocator > &img )
2123  {
2124  in.write( img );
2125  return( in );
2126  }
2127 
2134  template< typename Stream1, typename Stream2 >
2135  inline bool copy_frames( Stream1 &src, Stream2 &dst, const size_t num = 1 )
2136  {
2138 
2139  for( size_t i = 0 ; i < num ; i ++ )
2140  {
2141  if( src.read( tmp ) )
2142  {
2143  if( !dst.write( tmp ) )
2144  {
2145  return( false );
2146  }
2147  }
2148  else
2149  {
2150  return( false );
2151  }
2152  }
2153 
2154  return( true );
2155  }
2156 }
2157 
2158 
2160 // video_group ビデオファイルの入出力を行うライブラリの終わり
2161 
2162 
2163 // mist名前空間の終わり
2164 _MIST_END
2165 
2166 
2167 
2168 #endif // __INCLUDE_IO_VIDEO_H__
2169 

Generated on Wed Nov 12 2014 19:44:27 for MIST by doxygen 1.8.1.2