00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "OStreamVideoDecoder.hh"
00021
00022
00023 OStreamVideoDecoder::OStreamVideoDecoder( unsigned int io_buf_size, ostream_decoding_type decoding_type,
00024 int fps ,
00025 PixelFormat opencv_pix_fmt ) :
00026 _internal_buffer_size( io_buf_size ),
00027 _decoding_type( decoding_type ),
00028 _fps( fps ),
00029 _opencv_pix_fmt( opencv_pix_fmt )
00030
00031 {
00032 _initialized = false;
00033
00034 _opencv_ready_frame = NULL;
00035 if ( io_buf_size <= 1 ) {
00036 DEBUG_PRINT ("io_buf_size is wrong\n.");
00037 return;
00038 }
00039
00040
00041 _internal_buffer = new unsigned char[_internal_buffer_size];
00042
00043 if ( decoder_initialize () == true ) {
00044 _initialized = true;
00045 }
00046 }
00047
00048
00049 OStreamVideoDecoder::~OStreamVideoDecoder()
00050 {
00051 if ( _internal_buffer )
00052 delete _internal_buffer;
00053
00054 avcodec_close( _codec_context );
00055 }
00056
00057
00058 bool OStreamVideoDecoder::decoder_initialize ()
00059 {
00060
00061 av_register_all();
00062
00063 switch ( _decoding_type ) {
00064 case OSTREAM_DECODING_MJPEG:
00065 _codec_decode = avcodec_find_decoder( CODEC_ID_MJPEG );
00066 break;
00067
00068 case OSTREAM_DECODING_H263P:
00069
00070 _codec_decode = avcodec_find_decoder( CODEC_ID_H263 );
00071 break;
00072
00073 default:
00074 DEBUG_PRINT ("could not find known OSTREAM_DECODING type.\n" );
00075 break;
00076 }
00077
00078 if ( !_codec_decode ) {
00079 DEBUG_PRINT( "codec for decoding not found\n" );
00080 return false;
00081 }
00082
00083 _codec_context = avcodec_alloc_context();
00084 _decoded_frame = avcodec_alloc_frame();
00085
00086
00087
00088 if ( avcodec_open( _codec_context, _codec_decode ) < 0 ) {
00089 DEBUG_PRINT( "could not open codec\n" );
00090 return false;
00091 }
00092
00093
00094 return true;
00095 }
00096
00097 AVFrame* OStreamVideoDecoder::create_avframe( int pixel_format, int frame_width, int frame_height )
00098 {
00099 AVFrame *frame;
00100 unsigned char *picture_buf;
00101 int pic_size;
00102
00103 frame = avcodec_alloc_frame ();
00104 if ( !frame )
00105 return NULL;
00106
00107 pic_size = avpicture_get_size( pixel_format, frame_width, frame_height );
00108 picture_buf = (unsigned char*)calloc( pic_size, sizeof(unsigned char) );
00109
00110 if ( !picture_buf ) {
00111 av_free( frame );
00112 return NULL;
00113 }
00114
00115
00116 avpicture_fill((AVPicture *)frame, picture_buf, pixel_format, frame_width, frame_height );
00117 return frame;
00118 }
00119
00120 IplImage* OStreamVideoDecoder::decode_video_frame( unsigned char* buf, int buf_size )
00121 {
00122 int err_status;
00123 int got_decoded_frame_size;
00124 IplImage *ipl_image = NULL;
00125
00126
00127
00128
00129
00130 err_status = avcodec_decode_video( _codec_context, _decoded_frame, &got_decoded_frame_size,
00131 buf, buf_size );
00132 if ( err_status < 0) {
00133 DEBUG_PRINT( "Error while decoding frame.");
00134 return NULL;
00135 }
00136
00137
00138
00139 if ( _opencv_ready_frame == NULL) {
00140
00141
00142 _opencv_ready_frame = create_avframe( _opencv_pix_fmt, _codec_context->width,
00143 _codec_context->height );
00144 }
00145
00146 if ( got_decoded_frame_size ) {
00147 switch ( _decoding_type ) {
00148 case OSTREAM_DECODING_MJPEG:
00149 img_convert( (AVPicture *)_opencv_ready_frame, _opencv_pix_fmt,
00150 (AVPicture *)_decoded_frame, PIX_FMT_YUVJ420P,
00151 _codec_context->width, _codec_context->height );
00152 break;
00153
00154 case OSTREAM_DECODING_H263P:
00155 img_convert( (AVPicture *)_opencv_ready_frame, _opencv_pix_fmt,
00156 (AVPicture *)_decoded_frame, PIX_FMT_YUV420P,
00157 _codec_context->width, _codec_context->height );
00158
00159 break;
00160
00161 default:
00162 DEBUG_PRINT ("img_convert doesn't know what to do.\n" );
00163 break;
00164 }
00165
00166
00167
00168
00169 ipl_image = cvCreateImage( cvSize( _codec_context->width, _codec_context->height ), IPL_DEPTH_8U, 3 );
00170 memcpy( ipl_image->imageData, _opencv_ready_frame->data[0], ipl_image->imageSize );
00171 ipl_image->widthStep = _opencv_ready_frame->linesize[0];
00172 }
00173
00174 return ipl_image;
00175 }
00176
00177
00178
00179