00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "OStreamVideoEncoder.hh"
00021
00022
00023 OStreamVideoEncoder::OStreamVideoEncoder( unsigned int io_buf_size, ostream_encoding_type encoding_type,
00024 int video_width, int video_height,
00025 int fps ,
00026 PixelFormat opencv_pix_fmt ) :
00027 _internal_buffer_size( io_buf_size ),
00028 _encoding_type( encoding_type ),
00029 _video_width( video_width ),
00030 _video_height( video_height ),
00031 _fps( fps ),
00032 _opencv_pix_fmt( opencv_pix_fmt )
00033 {
00034 _initialized = false;
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 ( encoder_initialize () == true ) {;
00044 _initialized = true;
00045 }
00046 }
00047
00048 OStreamVideoEncoder::~OStreamVideoEncoder()
00049 {
00050
00051 if ( _internal_buffer )
00052 delete _internal_buffer;
00053
00054
00055
00056
00057
00058 }
00059
00060 bool OStreamVideoEncoder::open_codec( AVStream *stream )
00061 {
00062 AVCodec *codec;
00063 AVCodecContext *codec_context;
00064
00065 codec_context = stream->codec;
00066
00067
00068 codec = avcodec_find_encoder( codec_context->codec_id );
00069 if ( !codec ) {
00070 DEBUG_PRINT ("codec not found\n");
00071 return false;
00072 }
00073
00074
00075 if ( avcodec_open( codec_context, codec ) < 0 ) {
00076 return false;
00077 }
00078
00079 return true;
00080 }
00081
00082 AVFrame* OStreamVideoEncoder::create_avframe( int pixel_format )
00083 {
00084 AVFrame *frame;
00085 unsigned char *picture_buf;
00086 int pic_size;
00087
00088 frame = avcodec_alloc_frame ();
00089 if ( !frame )
00090 return NULL;
00091
00092 pic_size = avpicture_get_size( pixel_format, _video_width, _video_height );
00093 picture_buf = (unsigned char*)calloc( pic_size, sizeof(unsigned char) );
00094
00095 if ( !picture_buf ) {
00096 av_free( frame );
00097 return NULL;
00098 }
00099
00100
00101 avpicture_fill((AVPicture *)frame, picture_buf, pixel_format, _video_width, _video_height );
00102 return frame;
00103 }
00104
00105
00106 AVStream* OStreamVideoEncoder::create_video_stream( AVFormatContext *io_fmt_context, int codec_id )
00107 {
00108 AVCodecContext *codec_context;
00109 AVStream *stream;
00110
00111
00112
00113
00114 stream = av_new_stream( io_fmt_context, 0 );
00115 if ( !stream ) {
00116 DEBUG_PRINT ("Could not alloc stream\n");
00117 return NULL;
00118 }
00119
00120
00121
00122 codec_context = stream->codec;
00123 codec_context->codec_id = (CodecID)codec_id;
00124 codec_context->codec_type = CODEC_TYPE_VIDEO;
00125
00126
00127 codec_context->bit_rate = 400000;
00128
00129 codec_context->width = _video_width;
00130 codec_context->height = _video_height;
00131 codec_context->time_base.den = _fps;
00132 codec_context->time_base.num = 1;
00133
00134
00135 codec_context->gop_size = 12;
00136
00137 switch ( _encoding_type ) {
00138 case OSTREAM_ENCODING_MJPEG:
00139 codec_context->pix_fmt = PIX_FMT_YUVJ420P;
00140 break;
00141
00142 case OSTREAM_ENCODING_H263P:
00143 codec_context->pix_fmt = PIX_FMT_YUV420P;
00144 break;
00145
00146 default:
00147 codec_context->pix_fmt = PIX_FMT_YUVJ420P;
00148 break;
00149 }
00150
00151 return stream;
00152 }
00153
00154 bool OStreamVideoEncoder::encoder_initialize ()
00155 {
00156 char *encoding_str;
00157
00158 av_register_all();
00159
00160 switch ( _encoding_type ) {
00161 case OSTREAM_ENCODING_MJPEG:
00162 encoding_str = "mjpeg";
00163 _out_fmt = guess_format ( encoding_str, NULL, NULL);
00164
00165 if( !_out_fmt ) {
00166 DEBUG_PRINT( "Could not find suitable output format.\n");
00167 return false;
00168 }
00169
00170 break;
00171
00172 case OSTREAM_ENCODING_H263P:
00173 encoding_str ="h263";
00174 _out_fmt = guess_format ( encoding_str, NULL, NULL);
00175
00176 if( !_out_fmt ) {
00177 DEBUG_PRINT( "Could not find suitable output format.\n");
00178 return false;
00179 }
00180
00181
00182
00183 _out_fmt->video_codec = CODEC_ID_H263P;
00184
00185 break;
00186
00187 default:
00188 DEBUG_PRINT ("could not find known OSTREAM_ENCODING type.\n" );
00189 break;
00190 }
00191
00192 _out_fmt_context = av_alloc_format_context ();
00193 if( !_out_fmt_context ) {
00194 DEBUG_PRINT( "Memory error.\n" );
00195 return false;
00196 }
00197
00198
00199 _out_fmt_context->oformat = _out_fmt;
00200
00201
00202 if ( _out_fmt->video_codec == CODEC_ID_NONE ) {
00203 DEBUG_PRINT( "CODEC_ID_NONE\n" );
00204 return false;
00205 }
00206
00207
00208 if(!( _video_stream = create_video_stream( _out_fmt_context, _out_fmt->video_codec ) )) {
00209 DEBUG_PRINT( "error in adding stream\n" );
00210 return false;
00211 }
00212
00213
00214 if ( av_set_parameters( _out_fmt_context, NULL ) < 0 ) {
00215 DEBUG_PRINT( "Invalid output format parameters\n" );
00216 return false;
00217 }
00218
00219
00220 if ( !open_codec( _video_stream ) ) {
00221 DEBUG_PRINT( "could not open codec\n" );
00222 return false;
00223 }
00224
00225
00226
00227 _ready_to_encode_frame = create_avframe( _video_stream->codec->pix_fmt );
00228 if ( !_ready_to_encode_frame ) {
00229 DEBUG_PRINT( "Could not allocate encoded_frame\n" );
00230 return false;
00231 }
00232
00233
00234
00235 _opencv_frame = create_avframe( _opencv_pix_fmt );
00236 if ( !_opencv_frame ) {
00237 DEBUG_PRINT( "Could not allocate opencv frame\n");
00238 return false;
00239 }
00240
00241 return true;
00242 }
00243
00244
00245 const unsigned char* OStreamVideoEncoder::encode_video_frame( IplImage *image, int *out_size )
00246 {
00247 AVCodecContext *codec_context;
00248 *out_size = 0;
00249
00250 if ( image == NULL )
00251 return NULL;
00252
00253 if ( !_initialized ) {
00254 DEBUG_PRINT( "initializing class failed.\n" );
00255 return NULL;
00256 }
00257
00258 if( image->imageSize > _internal_buffer_size ) {
00259 DEBUG_PRINT( "image_size too big.\n" );
00260 return NULL;
00261 }
00262
00263 codec_context = _video_stream->codec;
00264
00265
00266
00267 _opencv_frame->data[0] = (uint8_t*)image->imageData;
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287