- メインページ
- モジュール
- ネームスペース
- データ構造
- ファイル

- ファイル一覧
- グローバル

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名前空間の始まり
66 _MIST_BEGIN
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_;
1003 double frame_aspect_ratio_;
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_;
1010 size_type audio_sampling_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 {
2137 array2< rgb< unsigned char > > tmp;
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