From: Alexander Reshetnikov Date: Mon, 9 Apr 2012 15:38:37 +0000 (+0000) Subject: Code style refactoring for ffmpeg wrappers X-Git-Tag: accepted/2.0/20130307.220821~771 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d9e4ad3f50b514746fc8abff4d40c4c764a332ff;p=profile%2Fivi%2Fopencv.git Code style refactoring for ffmpeg wrappers --- diff --git a/modules/highgui/src/cap_ffmpeg_impl.hpp b/modules/highgui/src/cap_ffmpeg_impl.hpp index a73ee77..aa9f8ee 100644 --- a/modules/highgui/src/cap_ffmpeg_impl.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl.hpp @@ -245,7 +245,7 @@ void CvCapture_FFMPEG::init() void CvCapture_FFMPEG::close() { if( picture ) - av_free(picture); + av_free(picture); if( video_st ) { @@ -316,13 +316,13 @@ bool CvCapture_FFMPEG::reopen() } #ifndef AVSEEK_FLAG_FRAME - #define AVSEEK_FLAG_FRAME 0 +#define AVSEEK_FLAG_FRAME 0 #endif #ifndef AVSEEK_FLAG_ANY - #define AVSEEK_FLAG_ANY 1 +#define AVSEEK_FLAG_ANY 1 #endif #ifndef SHORTER_DISTANCE_FOR_SEEK_TO_MAKE_IT_FASTER - #define SHORTER_DISTANCE_FOR_SEEK_TO_MAKE_IT_FASTER 25 +#define SHORTER_DISTANCE_FOR_SEEK_TO_MAKE_IT_FASTER 25 #endif bool CvCapture_FFMPEG::open( const char* _filename ) @@ -358,24 +358,24 @@ bool CvCapture_FFMPEG::open( const char* _filename ) avcodec_thread_init(enc, get_number_of_cpus()); - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO - #endif +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) +#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO +#endif if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) { AVCodec *codec = avcodec_find_decoder(enc->codec_id); if (!codec || - avcodec_open(enc, codec) < 0) - goto exit_func; + avcodec_open(enc, codec) < 0) + goto exit_func; video_stream = i; video_st = ic->streams[i]; picture = avcodec_alloc_frame(); rgb_picture.data[0] = (uint8_t*)malloc( - avpicture_get_size( PIX_FMT_BGR24, - enc->width, enc->height )); + avpicture_get_size( PIX_FMT_BGR24, + enc->width, enc->height )); avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0], - PIX_FMT_BGR24, enc->width, enc->height ); + PIX_FMT_BGR24, enc->width, enc->height ); frame.width = enc->width; frame.height = enc->height; @@ -406,7 +406,7 @@ bool CvCapture_FFMPEG::open( const char* _filename ) int flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD; av_seek_frame(ic, video_stream, ts, flags); } -exit_func: + exit_func: if( !valid ) close(); @@ -445,22 +445,22 @@ bool CvCapture_FFMPEG::grabFrame() break; if( packet.stream_index != video_stream ) { - av_free_packet (&packet); - continue; - } + av_free_packet (&packet); + continue; + } #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); + avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); +#else +#if LIBAVFORMAT_BUILD > 4628 + avcodec_decode_video(video_st->codec, + picture, &got_picture, + packet.data, packet.size); #else - #if LIBAVFORMAT_BUILD > 4628 - avcodec_decode_video(video_st->codec, - picture, &got_picture, - packet.data, packet.size); - #else - avcodec_decode_video(&video_st->codec, - picture, &got_picture, - packet.data, packet.size); - #endif + avcodec_decode_video(&video_st->codec, + picture, &got_picture, + packet.data, packet.size); +#endif #endif if (got_picture) { @@ -496,18 +496,18 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* #endif #else img_convert_ctx = sws_getContext(video_st->codec->width, - video_st->codec->height, - video_st->codec->pix_fmt, - video_st->codec->width, - video_st->codec->height, - PIX_FMT_BGR24, - SWS_BICUBIC, - NULL, NULL, NULL); - - sws_scale(img_convert_ctx, picture->data, - picture->linesize, 0, - video_st->codec->height, - rgb_picture.data, rgb_picture.linesize); + video_st->codec->height, + video_st->codec->pix_fmt, + video_st->codec->width, + video_st->codec->height, + PIX_FMT_BGR24, + SWS_BICUBIC, + NULL, NULL, NULL); + + sws_scale(img_convert_ctx, picture->data, + picture->linesize, 0, + video_st->codec->height, + rgb_picture.data, rgb_picture.linesize); sws_freeContext(img_convert_ctx); #endif *data = frame.data; @@ -556,41 +556,41 @@ double CvCapture_FFMPEG::getProperty( int property_id ) break; case CV_FFMPEG_CAP_PROP_FRAME_COUNT: { - int64_t nbf = ic->streams[video_stream]->nb_frames; - double eps = 0.000025; - if (nbf == 0) - { - double fps = static_cast(ic->streams[video_stream]->r_frame_rate.num) / static_cast(ic->streams[video_stream]->r_frame_rate.den); - if (fps < eps) + int64_t nbf = ic->streams[video_stream]->nb_frames; + double eps = 0.000025; + if (nbf == 0) { - fps = 1.0 / (static_cast(ic->streams[video_stream]->codec->time_base.num) / static_cast(ic->streams[video_stream]->codec->time_base.den)); + double fps = static_cast(ic->streams[video_stream]->r_frame_rate.num) / static_cast(ic->streams[video_stream]->r_frame_rate.den); + if (fps < eps) + { + fps = 1.0 / (static_cast(ic->streams[video_stream]->codec->time_base.num) / static_cast(ic->streams[video_stream]->codec->time_base.den)); + } + nbf = static_cast(round(ic->duration * fps) / AV_TIME_BASE); } - nbf = static_cast(round(ic->duration * fps) / AV_TIME_BASE); - } - return nbf; + return nbf; } break; case CV_FFMPEG_CAP_PROP_FRAME_WIDTH: return (double)frame.width; - break; + break; case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT: return (double)frame.height; - break; + break; case CV_FFMPEG_CAP_PROP_FPS: #if LIBAVCODEC_BUILD > 4753 return av_q2d (video_st->r_frame_rate); #else return (double)video_st->codec.frame_rate - / (double)video_st->codec.frame_rate_base; + / (double)video_st->codec.frame_rate_base; #endif - break; + break; case CV_FFMPEG_CAP_PROP_FOURCC: #if LIBAVFORMAT_BUILD > 4628 return (double)video_st->codec->codec_tag; #else return (double)video_st->codec.codec_tag; #endif - break; + break; } return 0; @@ -617,24 +617,24 @@ bool CvCapture_FFMPEG::seekKeyAndRunOverFrames(int framenumber) { int ret; if (framenumber > video_st->cur_dts-1) { - if (framenumber-(video_st->cur_dts-1) > SHORTER_DISTANCE_FOR_SEEK_TO_MAKE_IT_FASTER) { - ret = av_seek_frame(ic, video_stream, framenumber, 1); - assert(ret >= 0); - if( ret < 0 ) - return false; - } - grabFrame(); - while ((video_st->cur_dts-1) < framenumber) - if ( !grabFrame() ) return false; + if (framenumber-(video_st->cur_dts-1) > SHORTER_DISTANCE_FOR_SEEK_TO_MAKE_IT_FASTER) { + ret = av_seek_frame(ic, video_stream, framenumber, 1); + assert(ret >= 0); + if( ret < 0 ) + return false; + } + grabFrame(); + while ((video_st->cur_dts-1) < framenumber) + if ( !grabFrame() ) return false; } else if ( framenumber < (video_st->cur_dts-1) ) { - ret=av_seek_frame(ic, video_stream, framenumber, 1); - assert( ret >= 0 ); - if( ret < 0 ) - return false; - grabFrame(); - while ((video_st->cur_dts-1) < framenumber ) - if ( !grabFrame() ) return false; + ret=av_seek_frame(ic, video_stream, framenumber, 1); + assert( ret >= 0 ); + if( ret < 0 ) + return false; + grabFrame(); + while ((video_st->cur_dts-1) < framenumber ) + if ( !grabFrame() ) return false; } return true; } @@ -678,7 +678,7 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value ) if (!slowSeek((int)timestamp)) { fprintf(stderr, "HIGHGUI ERROR: AVI: could not (slow) seek to position %0.3f\n", - (double)timestamp / AV_TIME_BASE); + (double)timestamp / AV_TIME_BASE); return false; } } @@ -686,7 +686,7 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value ) { int flags = AVSEEK_FLAG_ANY; if (timestamp < ic->streams[video_stream]->cur_dts) - flags |= AVSEEK_FLAG_BACKWARD; + flags |= AVSEEK_FLAG_BACKWARD; int ret = av_seek_frame(ic, video_stream, timestamp, flags); if (ret < 0) { @@ -710,7 +710,7 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value ) struct CvVideoWriter_FFMPEG { bool open( const char* filename, int fourcc, - double fps, int width, int height, bool isColor ); + double fps, int width, int height, bool isColor ); void close(); bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin ); @@ -736,34 +736,34 @@ static const char * icvFFMPEGErrStr(int err) { #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) switch(err) { - case AVERROR_BSF_NOT_FOUND: - return "Bitstream filter not found"; - case AVERROR_DECODER_NOT_FOUND: - return "Decoder not found"; - case AVERROR_DEMUXER_NOT_FOUND: - return "Demuxer not found"; - case AVERROR_ENCODER_NOT_FOUND: - return "Encoder not found"; - case AVERROR_EOF: - return "End of file"; - case AVERROR_EXIT: - return "Immediate exit was requested; the called function should not be restarted"; - case AVERROR_FILTER_NOT_FOUND: - return "Filter not found"; - case AVERROR_INVALIDDATA: - return "Invalid data found when processing input"; - case AVERROR_MUXER_NOT_FOUND: - return "Muxer not found"; - case AVERROR_OPTION_NOT_FOUND: - return "Option not found"; - case AVERROR_PATCHWELCOME: - return "Not yet implemented in FFmpeg, patches welcome"; - case AVERROR_PROTOCOL_NOT_FOUND: - return "Protocol not found"; - case AVERROR_STREAM_NOT_FOUND: - return "Stream not found"; - default: - break; + case AVERROR_BSF_NOT_FOUND: + return "Bitstream filter not found"; + case AVERROR_DECODER_NOT_FOUND: + return "Decoder not found"; + case AVERROR_DEMUXER_NOT_FOUND: + return "Demuxer not found"; + case AVERROR_ENCODER_NOT_FOUND: + return "Encoder not found"; + case AVERROR_EOF: + return "End of file"; + case AVERROR_EXIT: + return "Immediate exit was requested; the called function should not be restarted"; + case AVERROR_FILTER_NOT_FOUND: + return "Filter not found"; + case AVERROR_INVALIDDATA: + return "Invalid data found when processing input"; + case AVERROR_MUXER_NOT_FOUND: + return "Muxer not found"; + case AVERROR_OPTION_NOT_FOUND: + return "Option not found"; + case AVERROR_PATCHWELCOME: + return "Not yet implemented in FFmpeg, patches welcome"; + case AVERROR_PROTOCOL_NOT_FOUND: + return "Protocol not found"; + case AVERROR_STREAM_NOT_FOUND: + return "Stream not found"; + default: + break; } #else switch(err) { @@ -830,7 +830,7 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo return NULL; } avpicture_fill((AVPicture *)picture, picture_buf, - (PixelFormat) pix_fmt, width, height); + (PixelFormat) pix_fmt, width, height); } else { } @@ -887,11 +887,11 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, of which frame timestamps are represented. for fixed-fps content, timebase should be 1/framerate and timestamp increments should be identically 1. */ - frame_rate = static_cast(fps+0.5); - frame_rate_base = 1; - while (fabs(static_cast(frame_rate)/frame_rate_base) - fps > 0.001){ - frame_rate_base *= 10; - frame_rate = static_cast(fps*frame_rate_base + 0.5); + frame_rate = static_cast(fps+0.5); + frame_rate_base = 1; + while (fabs(static_cast(frame_rate)/frame_rate_base) - fps > 0.001){ + frame_rate_base *= 10; + frame_rate = static_cast(fps*frame_rate_base + 0.5); } #if LIBAVFORMAT_BUILD > 4752 c->time_base.den = frame_rate; @@ -959,9 +959,9 @@ int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_ AVPacket pkt; av_init_packet(&pkt); - #ifndef PKT_FLAG_KEY - #define PKT_FLAG_KEY AV_PKT_FLAG_KEY - #endif +#ifndef PKT_FLAG_KEY +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif pkt.flags |= PKT_FLAG_KEY; pkt.stream_index= video_st->index; @@ -979,7 +979,7 @@ int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_ #if LIBAVFORMAT_BUILD > 4752 if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE) - pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base); + pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base); #else pkt.pts = c->coded_frame->pts; #endif @@ -1067,7 +1067,7 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int } // check if buffer sizes match, i.e. image has expected format (size, channels, bitdepth, alignment) -/*#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(37<<8)+0) + /*#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(37<<8)+0) assert (image->imageSize == avpicture_get_size( (PixelFormat)input_pix_fmt, image->width, image->height )); #else assert (image->imageSize == avpicture_get_size( input_pix_fmt, image->width, image->height )); @@ -1077,38 +1077,38 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int assert( input_picture ); // let input_picture point to the raw data buffer of 'image' avpicture_fill((AVPicture *)input_picture, (uint8_t *) data, - (PixelFormat)input_pix_fmt, width, height); + (PixelFormat)input_pix_fmt, width, height); #if !defined(HAVE_FFMPEG_SWSCALE) // convert to the color format needed by the codec if( img_convert((AVPicture *)picture, c->pix_fmt, - (AVPicture *)input_picture, (PixelFormat)input_pix_fmt, - width, height) < 0){ + (AVPicture *)input_picture, (PixelFormat)input_pix_fmt, + width, height) < 0){ return false; } #else img_convert_ctx = sws_getContext(width, - height, - (PixelFormat)input_pix_fmt, - c->width, - c->height, - c->pix_fmt, - SWS_BICUBIC, - NULL, NULL, NULL); - - if ( sws_scale(img_convert_ctx, input_picture->data, - input_picture->linesize, 0, - height, - picture->data, picture->linesize) < 0 ) - { - return false; - } + height, + (PixelFormat)input_pix_fmt, + c->width, + c->height, + c->pix_fmt, + SWS_BICUBIC, + NULL, NULL, NULL); + + if ( sws_scale(img_convert_ctx, input_picture->data, + input_picture->linesize, 0, + height, + picture->data, picture->linesize) < 0 ) + { + return false; + } sws_freeContext(img_convert_ctx); #endif } else{ avpicture_fill((AVPicture *)picture, (uint8_t *) data, - (PixelFormat)input_pix_fmt, width, height); + (PixelFormat)input_pix_fmt, width, height); } ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0; @@ -1137,306 +1137,306 @@ void CvVideoWriter_FFMPEG::close() #if LIBAVFORMAT_BUILD > 4628 if( video_st->codec->pix_fmt != input_pix_fmt){ #else - if( video_st->codec.pix_fmt != input_pix_fmt){ + if( video_st->codec.pix_fmt != input_pix_fmt){ #endif - if(picture->data[0]) - free(picture->data[0]); - picture->data[0] = 0; - } - av_free(picture); + if(picture->data[0]) + free(picture->data[0]); + picture->data[0] = 0; + } + av_free(picture); - if (input_picture) { - av_free(input_picture); - } + if (input_picture) { + av_free(input_picture); + } - /* close codec */ + /* close codec */ #if LIBAVFORMAT_BUILD > 4628 - avcodec_close(video_st->codec); + avcodec_close(video_st->codec); #else - avcodec_close(&(video_st->codec)); + avcodec_close(&(video_st->codec)); #endif - av_free(outbuf); + av_free(outbuf); - /* free the streams */ - for(i = 0; i < oc->nb_streams; i++) { - av_freep(&oc->streams[i]->codec); - av_freep(&oc->streams[i]); - } + /* free the streams */ + for(i = 0; i < oc->nb_streams; i++) { + av_freep(&oc->streams[i]->codec); + av_freep(&oc->streams[i]); + } - if (!(fmt->flags & AVFMT_NOFILE)) { - /* close the output file */ + if (!(fmt->flags & AVFMT_NOFILE)) { + /* close the output file */ #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) - url_fclose(oc->pb); + url_fclose(oc->pb); #else - url_fclose(&oc->pb); + url_fclose(&oc->pb); #endif - } + } - /* free the stream */ - av_free(oc); + /* free the stream */ + av_free(oc); - if( temp_image.data ) - { - free(temp_image.data); - temp_image.data = 0; - } + if( temp_image.data ) + { + free(temp_image.data); + temp_image.data = 0; + } - init(); -} + init(); + } -/// Create a video writer object that uses FFMPEG -bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, - double fps, int width, int height, bool is_color ) -{ - CodecID codec_id = CODEC_ID_NONE; + /// Create a video writer object that uses FFMPEG + bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + double fps, int width, int height, bool is_color ) + { + CodecID codec_id = CODEC_ID_NONE; int err, codec_pix_fmt, bitrate_scale = 64; - close(); + close(); - // check arguments + // check arguments assert(filename); assert(fps > 0); assert(width > 0 && height > 0); - // tell FFMPEG to register codecs + // tell FFMPEG to register codecs av_register_all(); - /* auto detect the output format from the name and fourcc code. */ + /* auto detect the output format from the name and fourcc code. */ #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - fmt = av_guess_format(NULL, filename, NULL); + fmt = av_guess_format(NULL, filename, NULL); #else - fmt = guess_format(NULL, filename, NULL); + fmt = guess_format(NULL, filename, NULL); #endif - - if (!fmt) - return false; - /* determine optimal pixel format */ - if (is_color) { - input_pix_fmt = PIX_FMT_BGR24; - } - else { - input_pix_fmt = PIX_FMT_GRAY8; - } + if (!fmt) + return false; + + /* determine optimal pixel format */ + if (is_color) { + input_pix_fmt = PIX_FMT_BGR24; + } + else { + input_pix_fmt = PIX_FMT_GRAY8; + } - /* Lookup codec_id for given fourcc */ + /* Lookup codec_id for given fourcc */ #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0) - if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE ) - return false; + if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE ) + return false; #else - const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL}; - if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ) - return false; + const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL}; + if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ) + return false; #endif - // alloc memory for context + // alloc memory for context #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - oc = avformat_alloc_context(); + oc = avformat_alloc_context(); #else - oc = av_alloc_format_context(); + oc = av_alloc_format_context(); #endif - assert (oc); + assert (oc); - /* set file name */ - oc->oformat = fmt; - snprintf(oc->filename, sizeof(oc->filename), "%s", filename); + /* set file name */ + oc->oformat = fmt; + snprintf(oc->filename, sizeof(oc->filename), "%s", filename); - /* set some options */ - oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ + /* set some options */ + oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ - // set a few optimal pixel formats for lossless codecs of interest.. - switch (codec_id) { + // set a few optimal pixel formats for lossless codecs of interest.. + switch (codec_id) { #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0) - case CODEC_ID_JPEGLS: - // BGR24 or GRAY8 depending on is_color... - codec_pix_fmt = input_pix_fmt; - break; + case CODEC_ID_JPEGLS: + // BGR24 or GRAY8 depending on is_color... + codec_pix_fmt = input_pix_fmt; + break; #endif - case CODEC_ID_HUFFYUV: - codec_pix_fmt = PIX_FMT_YUV422P; - break; - case CODEC_ID_MJPEG: - case CODEC_ID_LJPEG: - codec_pix_fmt = PIX_FMT_YUVJ420P; - bitrate_scale = 128; - break; - case CODEC_ID_RAWVIDEO: - codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 || - input_pix_fmt == PIX_FMT_GRAY16LE || - input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P; - break; - default: - // good for lossy formats, MPEG, etc. - codec_pix_fmt = PIX_FMT_YUV420P; - break; - } + case CODEC_ID_HUFFYUV: + codec_pix_fmt = PIX_FMT_YUV422P; + break; + case CODEC_ID_MJPEG: + case CODEC_ID_LJPEG: + codec_pix_fmt = PIX_FMT_YUVJ420P; + bitrate_scale = 128; + break; + case CODEC_ID_RAWVIDEO: + codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 || + input_pix_fmt == PIX_FMT_GRAY16LE || + input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P; + break; + default: + // good for lossy formats, MPEG, etc. + codec_pix_fmt = PIX_FMT_YUV420P; + break; + } - // TODO -- safe to ignore output audio stream? - video_st = icv_add_video_stream_FFMPEG(oc, codec_id, - width, height, width*height*bitrate_scale, - fps, codec_pix_fmt); + // TODO -- safe to ignore output audio stream? + video_st = icv_add_video_stream_FFMPEG(oc, codec_id, + width, height, width*height*bitrate_scale, + fps, codec_pix_fmt); - /* set the output parameters (must be done even if no + /* set the output parameters (must be done even if no parameters). */ - if (av_set_parameters(oc, NULL) < 0) { - return false; - } + if (av_set_parameters(oc, NULL) < 0) { + return false; + } - dump_format(oc, 0, filename, 1); + dump_format(oc, 0, filename, 1); - /* now that all the parameters are set, we can open the audio and + /* now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers */ - if (!video_st){ - return false; - } + if (!video_st){ + return false; + } - AVCodec *codec; - AVCodecContext *c; + AVCodec *codec; + AVCodecContext *c; #if LIBAVFORMAT_BUILD > 4628 - c = (video_st->codec); + c = (video_st->codec); #else - c = &(video_st->codec); + c = &(video_st->codec); #endif - c->codec_tag = fourcc; - /* find the video encoder */ - codec = avcodec_find_encoder(c->codec_id); - if (!codec) { - return false; - } + c->codec_tag = fourcc; + /* find the video encoder */ + codec = avcodec_find_encoder(c->codec_id); + if (!codec) { + return false; + } - c->bit_rate_tolerance = c->bit_rate; + c->bit_rate_tolerance = c->bit_rate; - /* open the codec */ - if ( (err=avcodec_open(c, codec)) < 0) { - char errtext[256]; - sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); - return false; - } + /* open the codec */ + if ( (err=avcodec_open(c, codec)) < 0) { + char errtext[256]; + sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); + return false; + } - outbuf = NULL; + outbuf = NULL; - if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { - /* allocate output buffer */ - /* assume we will never get codec output with more than 4 bytes per pixel... */ - outbuf_size = width*height*4; - outbuf = (uint8_t *) av_malloc(outbuf_size); - } + if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { + /* allocate output buffer */ + /* assume we will never get codec output with more than 4 bytes per pixel... */ + outbuf_size = width*height*4; + outbuf = (uint8_t *) av_malloc(outbuf_size); + } - bool need_color_convert; - need_color_convert = (c->pix_fmt != input_pix_fmt); + bool need_color_convert; + need_color_convert = (c->pix_fmt != input_pix_fmt); - /* allocate the encoded raw picture */ - picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert); - if (!picture) { - return false; - } + /* allocate the encoded raw picture */ + picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert); + if (!picture) { + return false; + } - /* if the output format is not our input format, then a temporary + /* if the output format is not our input format, then a temporary picture of the input format is needed too. It is then converted to the required output format */ - input_picture = NULL; - if ( need_color_convert ) { - input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); - if (!input_picture) { - return false; + input_picture = NULL; + if ( need_color_convert ) { + input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); + if (!input_picture) { + return false; + } } - } - /* open the output file, if needed */ - if (!(fmt->flags & AVFMT_NOFILE)) { - if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) { - return false; + /* open the output file, if needed */ + if (!(fmt->flags & AVFMT_NOFILE)) { + if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) { + return false; + } } - } - /* write the stream header, if any */ - av_write_header( oc ); + /* write the stream header, if any */ + av_write_header( oc ); - return true; -} + return true; + } -CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) -{ - CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); - capture->init(); - if( capture->open( filename )) - return capture; - capture->close(); - free(capture); - return 0; -} + CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) + { + CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); + capture->init(); + if( capture->open( filename )) + return capture; + capture->close(); + free(capture); + return 0; + } -void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) -{ - if( capture && *capture ) + void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) { - (*capture)->close(); - free(*capture); - *capture = 0; + if( capture && *capture ) + { + (*capture)->close(); + free(*capture); + *capture = 0; + } } -} -int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value) -{ - return capture->setProperty(prop_id, value); -} + int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value) + { + return capture->setProperty(prop_id, value); + } -double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) -{ - return capture->getProperty(prop_id); -} + double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) + { + return capture->getProperty(prop_id); + } -int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture) -{ - return capture->grabFrame(); -} + int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture) + { + return capture->grabFrame(); + } -int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn) -{ - return capture->retrieveFrame(0, data, step, width, height, cn); -} + int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn) + { + return capture->retrieveFrame(0, data, step, width, height, cn); + } -CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps, - int width, int height, int isColor ) -{ - CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer)); - writer->init(); - if( writer->open( filename, fourcc, fps, width, height, isColor != 0 )) - return writer; - writer->close(); - free(writer); - return 0; -} + CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps, + int width, int height, int isColor ) + { + CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer)); + writer->init(); + if( writer->open( filename, fourcc, fps, width, height, isColor != 0 )) + return writer; + writer->close(); + free(writer); + return 0; + } -void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) -{ - if( writer && *writer ) + void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) { - (*writer)->close(); - free(*writer); - *writer = 0; + if( writer && *writer ) + { + (*writer)->close(); + free(*writer); + *writer = 0; + } } -} -int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer, - const unsigned char* data, int step, - int width, int height, int cn, int origin) -{ - return writer->writeFrame(data, step, width, height, cn, origin); -} + int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer, + const unsigned char* data, int step, + int width, int height, int cn, int origin) + { + return writer->writeFrame(data, step, width, height, cn, origin); + } diff --git a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp index a839874..dc2dcea 100755 --- a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp @@ -255,9 +255,9 @@ void CvCapture_FFMPEG::init() memset( &frame, 0, sizeof(frame) ); filename = 0; packet.data = NULL; - #if defined(HAVE_FFMPEG_SWSCALE) - img_convert_ctx = 0; - #endif +#if defined(HAVE_FFMPEG_SWSCALE) + img_convert_ctx = 0; +#endif avcodec = 0; frame_number = 0; @@ -268,29 +268,29 @@ void CvCapture_FFMPEG::init() void CvCapture_FFMPEG::close() { if( picture ) - av_free(picture); + av_free(picture); if( video_st ) { - #if LIBAVFORMAT_BUILD > 4628 - avcodec_close( video_st->codec ); +#if LIBAVFORMAT_BUILD > 4628 + avcodec_close( video_st->codec ); - #else - avcodec_close( &(video_st->codec) ); +#else + avcodec_close( &(video_st->codec) ); - #endif - video_st = NULL; +#endif + video_st = NULL; } if( ic ) { - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) av_close_input_file(ic); - #else +#else avformat_close_input(&ic); - #endif +#endif - ic = NULL; + ic = NULL; } if( rgb_picture.data[0] ) @@ -363,10 +363,10 @@ bool CvCapture_FFMPEG::reopen() } #ifndef AVSEEK_FLAG_FRAME - #define AVSEEK_FLAG_FRAME 0 +#define AVSEEK_FLAG_FRAME 0 #endif #ifndef AVSEEK_FLAG_ANY - #define AVSEEK_FLAG_ANY 1 +#define AVSEEK_FLAG_ANY 1 #endif bool CvCapture_FFMPEG::open( const char* _filename ) @@ -376,9 +376,9 @@ bool CvCapture_FFMPEG::open( const char* _filename ) close(); - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) - avformat_network_init(); - #endif +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 13, 0) + avformat_network_init(); +#endif /* register all codecs, demux and protocols */ av_register_all(); @@ -391,56 +391,56 @@ bool CvCapture_FFMPEG::open( const char* _filename ) goto exit_func; } err = - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0) - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 6, 0) +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 24, 2) avformat_find_stream_info(ic); - #else - avformat_find_stream_info(ic, NULL); - #endif - #else - av_find_stream_info(ic); - #endif +#else + avformat_find_stream_info(ic, NULL); +#endif +#else + av_find_stream_info(ic); +#endif if (err < 0) { CV_WARN("Could not find codec parameters"); goto exit_func; } for(i = 0; i < ic->nb_streams; i++) { - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext *enc = ic->streams[i]->codec; - #else - AVCodecContext *enc = &ic->streams[i]->codec; - #endif +#if LIBAVFORMAT_BUILD > 4628 + AVCodecContext *enc = ic->streams[i]->codec; +#else + AVCodecContext *enc = &ic->streams[i]->codec; +#endif - #ifdef FF_API_THREAD_INIT - avcodec_thread_init(enc, get_number_of_cpus()); - #else - enc->thread_count = get_number_of_cpus(); - #endif +#ifdef FF_API_THREAD_INIT + avcodec_thread_init(enc, get_number_of_cpus()); +#else + enc->thread_count = get_number_of_cpus(); +#endif - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - #define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO - #endif +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) +#define AVMEDIA_TYPE_VIDEO CODEC_TYPE_VIDEO +#endif if( AVMEDIA_TYPE_VIDEO == enc->codec_type && video_stream < 0) { AVCodec *codec = avcodec_find_decoder(enc->codec_id); if (!codec || - #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) - avcodec_open2(enc, codec, NULL) - #else - avcodec_open(enc, codec) - #endif - < 0) goto exit_func; +#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) + avcodec_open2(enc, codec, NULL) +#else + avcodec_open(enc, codec) +#endif + < 0) goto exit_func; video_stream = i; video_st = ic->streams[i]; picture = avcodec_alloc_frame(); rgb_picture.data[0] = (uint8_t*)malloc( - avpicture_get_size( PIX_FMT_BGR24, - enc->width, enc->height )); + avpicture_get_size( PIX_FMT_BGR24, + enc->width, enc->height )); avpicture_fill( (AVPicture*)&rgb_picture, rgb_picture.data[0], - PIX_FMT_BGR24, enc->width, enc->height ); + PIX_FMT_BGR24, enc->width, enc->height ); frame.width = enc->width; frame.height = enc->height; @@ -471,7 +471,7 @@ bool CvCapture_FFMPEG::open( const char* _filename ) int flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_BACKWARD; av_seek_frame(ic, video_stream, ts, flags); }*/ -exit_func: + exit_func: if( !valid ) close(); @@ -513,28 +513,28 @@ bool CvCapture_FFMPEG::grabFrame() if( packet.stream_index != video_stream ) { - av_free_packet (&packet); - count_errs++; - if (count_errs > max_number_of_attempts) break; else + av_free_packet (&packet); + count_errs++; + if (count_errs > max_number_of_attempts) break; else continue; } // Decode video frame avcodec_decode_video2(video_st->codec, picture, &got_picture, &packet); - // Did we get a video frame? - if(got_picture) - { - frame_number++; - picture_pts = packet.pts; - valid = true; - } - else - { - count_errs++; - if (count_errs > max_number_of_attempts) - break; - } + // Did we get a video frame? + if(got_picture) + { + frame_number++; + picture_pts = packet.pts; + valid = true; + } + else + { + count_errs++; + if (count_errs > max_number_of_attempts) + break; + } } @@ -553,42 +553,42 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* frame.width = video_st->codec->width; frame.height = video_st->codec->height; - img_convert_ctx = sws_getContext( - video_st->codec->width, video_st->codec->height, - video_st->codec->pix_fmt, - video_st->codec->width, video_st->codec->height, - PIX_FMT_BGR24, - SWS_BICUBIC, - NULL, NULL, NULL - ); + img_convert_ctx = sws_getContext( + video_st->codec->width, video_st->codec->height, + video_st->codec->pix_fmt, + video_st->codec->width, video_st->codec->height, + PIX_FMT_BGR24, + SWS_BICUBIC, + NULL, NULL, NULL + ); - img_convert_ctx = sws_getCachedContext( - img_convert_ctx, - video_st->codec->width, video_st->codec->height, - video_st->codec->pix_fmt, - video_st->codec->width, video_st->codec->height, - PIX_FMT_BGR24, - SWS_BICUBIC, - NULL, NULL, NULL - ); + img_convert_ctx = sws_getCachedContext( + img_convert_ctx, + video_st->codec->width, video_st->codec->height, + video_st->codec->pix_fmt, + video_st->codec->width, video_st->codec->height, + PIX_FMT_BGR24, + SWS_BICUBIC, + NULL, NULL, NULL + ); - if (img_convert_ctx == NULL) - CV_Error(0, "Cannot initialize the conversion context!"); + if (img_convert_ctx == NULL) + CV_Error(0, "Cannot initialize the conversion context!"); - sws_scale( - img_convert_ctx, - picture->data, - picture->linesize, - 0, video_st->codec->height, - rgb_picture.data, - rgb_picture.linesize - ); + sws_scale( + img_convert_ctx, + picture->data, + picture->linesize, + 0, video_st->codec->height, + rgb_picture.data, + rgb_picture.linesize + ); - sws_freeContext(img_convert_ctx); + sws_freeContext(img_convert_ctx); - frame_number++; + frame_number++; *data = frame.data; *step = frame.step; @@ -630,25 +630,25 @@ double CvCapture_FFMPEG::getProperty( int property_id ) break; case CV_FFMPEG_CAP_PROP_FRAME_WIDTH: return (double)frame.width; - break; + break; case CV_FFMPEG_CAP_PROP_FRAME_HEIGHT: return (double)frame.height; - break; + break; case CV_FFMPEG_CAP_PROP_FPS: #if LIBAVCODEC_BUILD > 4753 return av_q2d (video_st->r_frame_rate); #else return (double)video_st->codec.frame_rate - / (double)video_st->codec.frame_rate_base; + / (double)video_st->codec.frame_rate_base; #endif - break; - case CV_FFMPEG_CAP_PROP_FOURCC: + break; + case CV_FFMPEG_CAP_PROP_FOURCC: #if LIBAVFORMAT_BUILD > 4628 return (double)video_st->codec->codec_tag; #else return (double)video_st->codec.codec_tag; #endif - break; + break; } return 0; @@ -812,7 +812,7 @@ bool CvCapture_FFMPEG::setProperty( int property_id, double value ) struct CvVideoWriter_FFMPEG { bool open( const char* filename, int fourcc, - double fps, int width, int height, bool isColor ); + double fps, int width, int height, bool isColor ); void close(); bool writeFrame( const unsigned char* data, int step, int width, int height, int cn, int origin ); @@ -839,34 +839,34 @@ static const char * icvFFMPEGErrStr(int err) { #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) switch(err) { - case AVERROR_BSF_NOT_FOUND: - return "Bitstream filter not found"; - case AVERROR_DECODER_NOT_FOUND: - return "Decoder not found"; - case AVERROR_DEMUXER_NOT_FOUND: - return "Demuxer not found"; - case AVERROR_ENCODER_NOT_FOUND: - return "Encoder not found"; - case AVERROR_EOF: - return "End of file"; - case AVERROR_EXIT: - return "Immediate exit was requested; the called function should not be restarted"; - case AVERROR_FILTER_NOT_FOUND: - return "Filter not found"; - case AVERROR_INVALIDDATA: - return "Invalid data found when processing input"; - case AVERROR_MUXER_NOT_FOUND: - return "Muxer not found"; - case AVERROR_OPTION_NOT_FOUND: - return "Option not found"; - case AVERROR_PATCHWELCOME: - return "Not yet implemented in FFmpeg, patches welcome"; - case AVERROR_PROTOCOL_NOT_FOUND: - return "Protocol not found"; - case AVERROR_STREAM_NOT_FOUND: - return "Stream not found"; - default: - break; + case AVERROR_BSF_NOT_FOUND: + return "Bitstream filter not found"; + case AVERROR_DECODER_NOT_FOUND: + return "Decoder not found"; + case AVERROR_DEMUXER_NOT_FOUND: + return "Demuxer not found"; + case AVERROR_ENCODER_NOT_FOUND: + return "Encoder not found"; + case AVERROR_EOF: + return "End of file"; + case AVERROR_EXIT: + return "Immediate exit was requested; the called function should not be restarted"; + case AVERROR_FILTER_NOT_FOUND: + return "Filter not found"; + case AVERROR_INVALIDDATA: + return "Invalid data found when processing input"; + case AVERROR_MUXER_NOT_FOUND: + return "Muxer not found"; + case AVERROR_OPTION_NOT_FOUND: + return "Option not found"; + case AVERROR_PATCHWELCOME: + return "Not yet implemented in FFmpeg, patches welcome"; + case AVERROR_PROTOCOL_NOT_FOUND: + return "Protocol not found"; + case AVERROR_STREAM_NOT_FOUND: + return "Stream not found"; + default: + break; } #else switch(err) { @@ -906,9 +906,9 @@ void CvVideoWriter_FFMPEG::init() video_st = 0; input_pix_fmt = 0; memset(&temp_image, 0, sizeof(temp_image)); - #if defined(HAVE_FFMPEG_SWSCALE) - img_convert_ctx = 0; - #endif +#if defined(HAVE_FFMPEG_SWSCALE) + img_convert_ctx = 0; +#endif ok = false; } @@ -934,7 +934,7 @@ static AVFrame * icv_alloc_picture_FFMPEG(int pix_fmt, int width, int height, bo return NULL; } avpicture_fill((AVPicture *)picture, picture_buf, - (PixelFormat) pix_fmt, width, height); + (PixelFormat) pix_fmt, width, height); } else { } @@ -952,28 +952,28 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, int frame_rate, frame_rate_base; AVCodec *codec; - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0) - st = avformat_new_stream(oc, 0); - #else - st = av_new_stream(oc, 0); - #endif +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 10, 0) + st = avformat_new_stream(oc, 0); +#else + st = av_new_stream(oc, 0); +#endif if (!st) { CV_WARN("Could not allocate stream"); return NULL; } - #if LIBAVFORMAT_BUILD > 4628 - c = st->codec; - #else - c = &(st->codec); - #endif +#if LIBAVFORMAT_BUILD > 4628 + c = st->codec; +#else + c = &(st->codec); +#endif - #if LIBAVFORMAT_BUILD > 4621 - c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); - #else - c->codec_id = oc->oformat->video_codec; - #endif +#if LIBAVFORMAT_BUILD > 4621 + c->codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); +#else + c->codec_id = oc->oformat->video_codec; +#endif if(codec_id != CODEC_ID_NONE){ c->codec_id = codec_id; @@ -1001,30 +1001,30 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, frame_rate_base*=10; frame_rate=(int)(fps*frame_rate_base + 0.5); } - #if LIBAVFORMAT_BUILD > 4752 - c->time_base.den = frame_rate; - c->time_base.num = frame_rate_base; - /* adjust time base for supported framerates */ - if(codec && codec->supported_framerates){ - const AVRational *p= codec->supported_framerates; - AVRational req = {frame_rate, frame_rate_base}; - const AVRational *best=NULL; - AVRational best_error= {INT_MAX, 1}; - for(; p->den!=0; p++){ - AVRational error= av_sub_q(req, *p); - if(error.num <0) error.num *= -1; - if(av_cmp_q(error, best_error) < 0){ - best_error= error; - best= p; - } - } - c->time_base.den= best->num; - c->time_base.num= best->den; - } - #else - c->frame_rate = frame_rate; - c->frame_rate_base = frame_rate_base; - #endif +#if LIBAVFORMAT_BUILD > 4752 + c->time_base.den = frame_rate; + c->time_base.num = frame_rate_base; + /* adjust time base for supported framerates */ + if(codec && codec->supported_framerates){ + const AVRational *p= codec->supported_framerates; + AVRational req = {frame_rate, frame_rate_base}; + const AVRational *best=NULL; + AVRational best_error= {INT_MAX, 1}; + for(; p->den!=0; p++){ + AVRational error= av_sub_q(req, *p); + if(error.num <0) error.num *= -1; + if(av_cmp_q(error, best_error) < 0){ + best_error= error; + best= p; + } + } + c->time_base.den= best->num; + c->time_base.num= best->den; + } +#else + c->frame_rate = frame_rate; + c->frame_rate_base = frame_rate_base; +#endif c->gop_size = 12; /* emit one intra frame every twelve frames at most */ c->pix_fmt = (PixelFormat) pixel_format; @@ -1039,24 +1039,24 @@ static AVStream *icv_add_video_stream_FFMPEG(AVFormatContext *oc, /* avoid FFMPEG warning 'clipping 1 dct coefficients...' */ c->mb_decision=2; } - #if LIBAVCODEC_VERSION_INT>0x000409 - // some formats want stream headers to be seperate - if(oc->oformat->flags & AVFMT_GLOBALHEADER) - { - c->flags |= CODEC_FLAG_GLOBAL_HEADER; - } - #endif +#if LIBAVCODEC_VERSION_INT>0x000409 + // some formats want stream headers to be seperate + if(oc->oformat->flags & AVFMT_GLOBALHEADER) + { + c->flags |= CODEC_FLAG_GLOBAL_HEADER; + } +#endif return st; } int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_t * outbuf, uint32_t outbuf_size, AVFrame * picture ) { - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext * c = video_st->codec; - #else - AVCodecContext * c = &(video_st->codec); - #endif +#if LIBAVFORMAT_BUILD > 4628 + AVCodecContext * c = video_st->codec; +#else + AVCodecContext * c = &(video_st->codec); +#endif int out_size; int ret; @@ -1066,9 +1066,9 @@ int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_ AVPacket pkt; av_init_packet(&pkt); - #ifndef PKT_FLAG_KEY - #define PKT_FLAG_KEY AV_PKT_FLAG_KEY - #endif +#ifndef PKT_FLAG_KEY +#define PKT_FLAG_KEY AV_PKT_FLAG_KEY +#endif pkt.flags |= PKT_FLAG_KEY; pkt.stream_index= video_st->index; @@ -1084,12 +1084,12 @@ int icv_av_write_frame_FFMPEG( AVFormatContext * oc, AVStream * video_st, uint8_ AVPacket pkt; av_init_packet(&pkt); - #if LIBAVFORMAT_BUILD > 4752 - if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE) +#if LIBAVFORMAT_BUILD > 4752 + if(c->coded_frame->pts != (int64_t)AV_NOPTS_VALUE) pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_st->time_base); - #else - pkt.pts = c->coded_frame->pts; - #endif +#else + pkt.pts = c->coded_frame->pts; +#endif if(c->coded_frame->key_frame) pkt.flags |= PKT_FLAG_KEY; pkt.stream_index= video_st->index; @@ -1113,50 +1113,50 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int bool ret = false; // typecast from opaque data type to implemented struct - #if LIBAVFORMAT_BUILD > 4628 - AVCodecContext *c = video_st->codec; - #else - AVCodecContext *c = &(video_st->codec); - #endif +#if LIBAVFORMAT_BUILD > 4628 + AVCodecContext *c = video_st->codec; +#else + AVCodecContext *c = &(video_st->codec); +#endif - #if LIBAVFORMAT_BUILD < 5231 - // It is not needed in the latest versions of the ffmpeg - if( c->codec_id == CODEC_ID_RAWVIDEO && origin != 1 ) - { - if( !temp_image.data ) - { - temp_image.step = (width*cn + 3) & -4; - temp_image.width = width; - temp_image.height = height; - temp_image.cn = cn; - temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); - } - for( int y = 0; y < height; y++ ) - memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn); - data = temp_image.data; - step = temp_image.step; - } - #else - if( width*cn != step ) - { - if( !temp_image.data ) - { - temp_image.step = width*cn; - temp_image.width = width; - temp_image.height = height; - temp_image.cn = cn; - temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); - } - if (origin == 1) - for( int y = 0; y < height; y++ ) - memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step); - else - for( int y = 0; y < height; y++ ) - memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step); - data = temp_image.data; - step = temp_image.step; - } - #endif +#if LIBAVFORMAT_BUILD < 5231 + // It is not needed in the latest versions of the ffmpeg + if( c->codec_id == CODEC_ID_RAWVIDEO && origin != 1 ) + { + if( !temp_image.data ) + { + temp_image.step = (width*cn + 3) & -4; + temp_image.width = width; + temp_image.height = height; + temp_image.cn = cn; + temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); + } + for( int y = 0; y < height; y++ ) + memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, width*cn); + data = temp_image.data; + step = temp_image.step; + } +#else + if( width*cn != step ) + { + if( !temp_image.data ) + { + temp_image.step = width*cn; + temp_image.width = width; + temp_image.height = height; + temp_image.cn = cn; + temp_image.data = (unsigned char*)malloc(temp_image.step*temp_image.height); + } + if (origin == 1) + for( int y = 0; y < height; y++ ) + memcpy(temp_image.data + y*temp_image.step, data + (height-1-y)*step, temp_image.step); + else + for( int y = 0; y < height; y++ ) + memcpy(temp_image.data + y*temp_image.step, data + y*step, temp_image.step); + data = temp_image.data; + step = temp_image.step; + } +#endif // check parameters if (input_pix_fmt == PIX_FMT_BGR24) { @@ -1177,38 +1177,38 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int assert( input_picture ); // let input_picture point to the raw data buffer of 'image' avpicture_fill((AVPicture *)input_picture, (uint8_t *) data, - (PixelFormat)input_pix_fmt, width, height); + (PixelFormat)input_pix_fmt, width, height); #if !defined(HAVE_FFMPEG_SWSCALE) // convert to the color format needed by the codec if( img_convert((AVPicture *)picture, c->pix_fmt, - (AVPicture *)input_picture, (PixelFormat)input_pix_fmt, - width, height) < 0){ + (AVPicture *)input_picture, (PixelFormat)input_pix_fmt, + width, height) < 0){ return false; } #else img_convert_ctx = sws_getContext(width, - height, - (PixelFormat)input_pix_fmt, - c->width, - c->height, - c->pix_fmt, - SWS_BICUBIC, - NULL, NULL, NULL); - - if ( sws_scale(img_convert_ctx, input_picture->data, - input_picture->linesize, 0, - height, - picture->data, picture->linesize) < 0 ) - { - return false; - } + height, + (PixelFormat)input_pix_fmt, + c->width, + c->height, + c->pix_fmt, + SWS_BICUBIC, + NULL, NULL, NULL); + + if ( sws_scale(img_convert_ctx, input_picture->data, + input_picture->linesize, 0, + height, + picture->data, picture->linesize) < 0 ) + { + return false; + } sws_freeContext(img_convert_ctx); #endif } else{ avpicture_fill((AVPicture *)picture, (uint8_t *) data, - (PixelFormat)input_pix_fmt, width, height); + (PixelFormat)input_pix_fmt, width, height); } ret = icv_av_write_frame_FFMPEG( oc, video_st, outbuf, outbuf_size, picture) >= 0; @@ -1235,337 +1235,337 @@ void CvVideoWriter_FFMPEG::close() av_write_trailer(oc); // free pictures - #if LIBAVFORMAT_BUILD > 4628 - if( video_st->codec->pix_fmt != input_pix_fmt){ - #else +#if LIBAVFORMAT_BUILD > 4628 + if( video_st->codec->pix_fmt != input_pix_fmt){ +#else if( video_st->codec.pix_fmt != input_pix_fmt){ - #endif - if(picture->data[0]) - free(picture->data[0]); - picture->data[0] = 0; - } - av_free(picture); +#endif + if(picture->data[0]) + free(picture->data[0]); + picture->data[0] = 0; + } + av_free(picture); - if (input_picture) { - av_free(input_picture); - } + if (input_picture) { + av_free(input_picture); + } - /* close codec */ - #if LIBAVFORMAT_BUILD > 4628 + /* close codec */ +#if LIBAVFORMAT_BUILD > 4628 avcodec_close(video_st->codec); - #else +#else avcodec_close(&(video_st->codec)); - #endif +#endif - av_free(outbuf); + av_free(outbuf); - /* free the streams */ - for(i = 0; i < oc->nb_streams; i++) { - av_freep(&oc->streams[i]->codec); - av_freep(&oc->streams[i]); - } + /* free the streams */ + for(i = 0; i < oc->nb_streams; i++) { + av_freep(&oc->streams[i]->codec); + av_freep(&oc->streams[i]); + } - if (!(fmt->flags & AVFMT_NOFILE)) { - /* close the output file */ + if (!(fmt->flags & AVFMT_NOFILE)) { + /* close the output file */ - #if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0) - #if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) +#if LIBAVCODEC_VERSION_INT < ((52<<16)+(123<<8)+0) +#if LIBAVCODEC_VERSION_INT >= ((51<<16)+(49<<8)+0) url_fclose(oc->pb); - #else +#else url_fclose(&oc->pb); - #endif - #else +#endif +#else avio_close(oc->pb); - #endif +#endif - } + } - /* free the stream */ - av_free(oc); + /* free the stream */ + av_free(oc); - if( temp_image.data ) - { - free(temp_image.data); - temp_image.data = 0; - } + if( temp_image.data ) + { + free(temp_image.data); + temp_image.data = 0; + } - init(); -} + init(); + } -/// Create a video writer object that uses FFMPEG -bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, - double fps, int width, int height, bool is_color ) -{ - CodecID codec_id = CODEC_ID_NONE; - int err, codec_pix_fmt, bitrate_scale=64; + /// Create a video writer object that uses FFMPEG + bool CvVideoWriter_FFMPEG::open( const char * filename, int fourcc, + double fps, int width, int height, bool is_color ) + { + CodecID codec_id = CODEC_ID_NONE; + int err, codec_pix_fmt, bitrate_scale=64; - close(); + close(); - // check arguments - assert (filename); - assert (fps > 0); - assert (width > 0 && height > 0); + // check arguments + assert (filename); + assert (fps > 0); + assert (width > 0 && height > 0); - // tell FFMPEG to register codecs - av_register_all (); + // tell FFMPEG to register codecs + av_register_all (); - /* auto detect the output format from the name and fourcc code. */ + /* auto detect the output format from the name and fourcc code. */ - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) fmt = av_guess_format(NULL, filename, NULL); - #else +#else fmt = guess_format(NULL, filename, NULL); - #endif +#endif - if (!fmt) - return false; + if (!fmt) + return false; - /* determine optimal pixel format */ - if (is_color) { - input_pix_fmt = PIX_FMT_BGR24; - } - else { - input_pix_fmt = PIX_FMT_GRAY8; - } + /* determine optimal pixel format */ + if (is_color) { + input_pix_fmt = PIX_FMT_BGR24; + } + else { + input_pix_fmt = PIX_FMT_GRAY8; + } - /* Lookup codec_id for given fourcc */ - #if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0) + /* Lookup codec_id for given fourcc */ +#if LIBAVCODEC_VERSION_INT<((51<<16)+(49<<8)+0) if( (codec_id = codec_get_bmp_id( fourcc )) == CODEC_ID_NONE ) return false; - #else +#else const struct AVCodecTag * tags[] = { codec_bmp_tags, NULL}; if( (codec_id = av_codec_get_id(tags, fourcc)) == CODEC_ID_NONE ) return false; - #endif +#endif - // alloc memory for context - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + // alloc memory for context +#if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) oc = avformat_alloc_context(); - #else +#else oc = av_alloc_format_context(); - #endif - assert (oc); +#endif + assert (oc); - /* set file name */ - oc->oformat = fmt; - snprintf(oc->filename, sizeof(oc->filename), "%s", filename); + /* set file name */ + oc->oformat = fmt; + snprintf(oc->filename, sizeof(oc->filename), "%s", filename); - /* set some options */ - oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ + /* set some options */ + oc->max_delay = (int)(0.7*AV_TIME_BASE); /* This reduces buffer underrun warnings with MPEG */ - // set a few optimal pixel formats for lossless codecs of interest.. - switch (codec_id) { - #if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0) + // set a few optimal pixel formats for lossless codecs of interest.. + switch (codec_id) { +#if LIBAVCODEC_VERSION_INT>((50<<16)+(1<<8)+0) case CODEC_ID_JPEGLS: // BGR24 or GRAY8 depending on is_color... codec_pix_fmt = input_pix_fmt; break; - #endif - case CODEC_ID_HUFFYUV: - codec_pix_fmt = PIX_FMT_YUV422P; - break; - case CODEC_ID_MJPEG: - case CODEC_ID_LJPEG: - codec_pix_fmt = PIX_FMT_YUVJ420P; - bitrate_scale = 128; - break; - case CODEC_ID_RAWVIDEO: - codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 || - input_pix_fmt == PIX_FMT_GRAY16LE || - input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P; - break; - default: - // good for lossy formats, MPEG, etc. - codec_pix_fmt = PIX_FMT_YUV420P; - break; - } +#endif + case CODEC_ID_HUFFYUV: + codec_pix_fmt = PIX_FMT_YUV422P; + break; + case CODEC_ID_MJPEG: + case CODEC_ID_LJPEG: + codec_pix_fmt = PIX_FMT_YUVJ420P; + bitrate_scale = 128; + break; + case CODEC_ID_RAWVIDEO: + codec_pix_fmt = input_pix_fmt == PIX_FMT_GRAY8 || + input_pix_fmt == PIX_FMT_GRAY16LE || + input_pix_fmt == PIX_FMT_GRAY16BE ? input_pix_fmt : PIX_FMT_YUV420P; + break; + default: + // good for lossy formats, MPEG, etc. + codec_pix_fmt = PIX_FMT_YUV420P; + break; + } - // TODO -- safe to ignore output audio stream? - video_st = icv_add_video_stream_FFMPEG(oc, codec_id, - width, height, width*height*bitrate_scale, - fps, codec_pix_fmt); + // TODO -- safe to ignore output audio stream? + video_st = icv_add_video_stream_FFMPEG(oc, codec_id, + width, height, width*height*bitrate_scale, + fps, codec_pix_fmt); - /* set the output parameters (must be done even if no + /* set the output parameters (must be done even if no parameters). */ - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) if (av_set_parameters(oc, NULL) < 0) { - return false; - } - #endif + return false; + } +#endif - #if 0 - #if FF_API_DUMP_FORMAT +#if 0 +#if FF_API_DUMP_FORMAT dump_format(oc, 0, filename, 1); - #else +#else av_dump_format(oc, 0, filename, 1); - #endif - #endif +#endif +#endif - /* now that all the parameters are set, we can open the audio and + /* now that all the parameters are set, we can open the audio and video codecs and allocate the necessary encode buffers */ - if (!video_st){ - return false; - } + if (!video_st){ + return false; + } - AVCodec *codec; - AVCodecContext *c; + AVCodec *codec; + AVCodecContext *c; - #if LIBAVFORMAT_BUILD > 4628 +#if LIBAVFORMAT_BUILD > 4628 c = (video_st->codec); - #else +#else c = &(video_st->codec); - #endif +#endif - c->codec_tag = fourcc; - /* find the video encoder */ - codec = avcodec_find_encoder(c->codec_id); - if (!codec) { - return false; - } + c->codec_tag = fourcc; + /* find the video encoder */ + codec = avcodec_find_encoder(c->codec_id); + if (!codec) { + return false; + } - c->bit_rate_tolerance = c->bit_rate; + c->bit_rate_tolerance = c->bit_rate; - /* open the codec */ - if ((err= - #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) + /* open the codec */ + if ((err= +#if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) avcodec_open2(c, codec, NULL) - #else +#else avcodec_open(c, codec) - #endif - ) < 0) { - char errtext[256]; - sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); - return false; - } +#endif + ) < 0) { + char errtext[256]; + sprintf(errtext, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); + return false; + } - outbuf = NULL; + outbuf = NULL; - if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { - /* allocate output buffer */ - /* assume we will never get codec output with more than 4 bytes per pixel... */ - outbuf_size = width*height*4; - outbuf = (uint8_t *) av_malloc(outbuf_size); - } + if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { + /* allocate output buffer */ + /* assume we will never get codec output with more than 4 bytes per pixel... */ + outbuf_size = width*height*4; + outbuf = (uint8_t *) av_malloc(outbuf_size); + } - bool need_color_convert; - need_color_convert = (c->pix_fmt != input_pix_fmt); + bool need_color_convert; + need_color_convert = (c->pix_fmt != input_pix_fmt); - /* allocate the encoded raw picture */ - picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert); - if (!picture) { - return false; - } + /* allocate the encoded raw picture */ + picture = icv_alloc_picture_FFMPEG(c->pix_fmt, c->width, c->height, need_color_convert); + if (!picture) { + return false; + } - /* if the output format is not our input format, then a temporary + /* if the output format is not our input format, then a temporary picture of the input format is needed too. It is then converted to the required output format */ - input_picture = NULL; - if ( need_color_convert ) { - input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); - if (!input_picture) { - return false; + input_picture = NULL; + if ( need_color_convert ) { + input_picture = icv_alloc_picture_FFMPEG(input_pix_fmt, c->width, c->height, false); + if (!input_picture) { + return false; + } } - } - /* open the output file, if needed */ - if (!(fmt->flags & AVFMT_NOFILE)) { - #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) + /* open the output file, if needed */ + if (!(fmt->flags & AVFMT_NOFILE)) { +#if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) - #else +#else if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) - #endif +#endif + { + return false; + } + } + + /* write the stream header, if any */ + err=avformat_write_header(oc, NULL); + if(err < 0) { + close(); + remove(filename); return false; } + ok = true; + return true; } - /* write the stream header, if any */ - err=avformat_write_header(oc, NULL); - if(err < 0) - { - close(); - remove(filename); - return false; - } - ok = true; - return true; -} - -CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) -{ - CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); - capture->init(); - if( capture->open( filename )) - return capture; - capture->close(); - free(capture); - return 0; -} + CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) + { + CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); + capture->init(); + if( capture->open( filename )) + return capture; + capture->close(); + free(capture); + return 0; + } -void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) -{ - if( capture && *capture ) + void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) { - (*capture)->close(); - free(*capture); - *capture = 0; + if( capture && *capture ) + { + (*capture)->close(); + free(*capture); + *capture = 0; + } } -} -int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value) -{ - return capture->setProperty(prop_id, value); -} + int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double value) + { + return capture->setProperty(prop_id, value); + } -double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) -{ - return capture->getProperty(prop_id); -} + double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) + { + return capture->getProperty(prop_id); + } -int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture) -{ - return capture->grabFrame(); -} + int cvGrabFrame_FFMPEG(CvCapture_FFMPEG* capture) + { + return capture->grabFrame(); + } -int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn) -{ - return capture->retrieveFrame(0, data, step, width, height, cn); -} + int cvRetrieveFrame_FFMPEG(CvCapture_FFMPEG* capture, unsigned char** data, int* step, int* width, int* height, int* cn) + { + return capture->retrieveFrame(0, data, step, width, height, cn); + } -CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps, - int width, int height, int isColor ) -{ - CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer)); - writer->init(); - if( writer->open( filename, fourcc, fps, width, height, isColor != 0 )) - return writer; - writer->close(); - free(writer); - return 0; -} + CvVideoWriter_FFMPEG* cvCreateVideoWriter_FFMPEG( const char* filename, int fourcc, double fps, + int width, int height, int isColor ) + { + CvVideoWriter_FFMPEG* writer = (CvVideoWriter_FFMPEG*)malloc(sizeof(*writer)); + writer->init(); + if( writer->open( filename, fourcc, fps, width, height, isColor != 0 )) + return writer; + writer->close(); + free(writer); + return 0; + } -void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) -{ - if( writer && *writer ) + void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) { - (*writer)->close(); - free(*writer); - *writer = 0; + if( writer && *writer ) + { + (*writer)->close(); + free(*writer); + *writer = 0; + } } -} -int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer, - const unsigned char* data, int step, - int width, int height, int cn, int origin) -{ - return writer->writeFrame(data, step, width, height, cn, origin); -} + int cvWriteFrame_FFMPEG( CvVideoWriter_FFMPEG* writer, + const unsigned char* data, int step, + int width, int height, int cn, int origin) + { + return writer->writeFrame(data, step, width, height, cn, origin); + }