diff --git a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp index 800d457e5..28e35a20a 100755 --- a/modules/highgui/src/cap_ffmpeg_impl_v2.hpp +++ b/modules/highgui/src/cap_ffmpeg_impl_v2.hpp @@ -63,6 +63,10 @@ extern "C" { #include #else +#ifndef HAVE_FFMPEG_SWSCALE + #error "libswscale is necessary to build the newer OpenCV ffmpeg wrapper" +#endif + // if the header path is not specified explicitly, let's deduce it #if !defined HAVE_FFMPEG_AVCODEC_H && !defined HAVE_LIBAVCODEC_AVCODEC_H @@ -232,9 +236,7 @@ struct CvCapture_FFMPEG AVPacket packet; Image_FFMPEG frame; - #if defined(HAVE_FFMPEG_SWSCALE) - struct SwsContext *img_convert_ctx; - #endif + struct SwsContext *img_convert_ctx; int64_t frame_number; @@ -260,9 +262,7 @@ void CvCapture_FFMPEG::init() memset( &frame, 0, sizeof(frame) ); filename = 0; packet.data = NULL; -#if defined(HAVE_FFMPEG_SWSCALE) img_convert_ctx = 0; -#endif avcodec = 0; frame_number = 0; @@ -272,6 +272,12 @@ void CvCapture_FFMPEG::init() void CvCapture_FFMPEG::close() { + if( img_convert_ctx ) + { + sws_freeContext(img_convert_ctx); + img_convert_ctx = 0; + } + if( picture ) av_free(picture); @@ -545,32 +551,32 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* if( !video_st || !picture->data[0] ) return false; - avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, video_st->codec->width, video_st->codec->height); + avpicture_fill((AVPicture*)&rgb_picture, rgb_picture.data[0], PIX_FMT_RGB24, + video_st->codec->width, video_st->codec->height); - frame.width = video_st->codec->width; - frame.height = video_st->codec->height; + if( img_convert_ctx == NULL || + frame.width != video_st->codec->width || + frame.height != video_st->codec->height ) + { + if( img_convert_ctx ) + sws_freeContext(img_convert_ctx); + + 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_getCachedContext( + NULL, + 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) - return false;//CV_Error(0, "Cannot initialize the conversion context!"); + if (img_convert_ctx == NULL) + return false;//CV_Error(0, "Cannot initialize the conversion context!"); + } sws_scale( img_convert_ctx, @@ -581,10 +587,6 @@ bool CvCapture_FFMPEG::retrieveFrame(int, unsigned char** data, int* step, int* rgb_picture.linesize ); - sws_freeContext(img_convert_ctx); - - - frame_number++; *data = frame.data; @@ -674,7 +676,8 @@ double CvCapture_FFMPEG::get_duration_sec() if (sec < eps_zero) { - sec = static_cast(static_cast(ic->streams[video_stream]->duration)) * r2d(ic->streams[video_stream]->time_base); + sec = static_cast(static_cast(ic->streams[video_stream]->duration)) * + r2d(ic->streams[video_stream]->time_base); } return sec; @@ -721,7 +724,8 @@ int64_t CvCapture_FFMPEG::dts_to_frame_number(int64_t dts) double CvCapture_FFMPEG::dts_to_sec(int64_t dts) { - return static_cast(dts - ic->streams[video_stream]->start_time) * r2d(ic->streams[video_stream]->time_base); + return static_cast(dts - ic->streams[video_stream]->start_time) * + r2d(ic->streams[video_stream]->time_base); } void CvCapture_FFMPEG::seek(int64_t _frame_number) @@ -828,9 +832,7 @@ struct CvVideoWriter_FFMPEG Image_FFMPEG temp_image; int frame_width, frame_height; bool ok; -#if defined(HAVE_FFMPEG_SWSCALE) struct SwsContext *img_convert_ctx; -#endif }; static const char * icvFFMPEGErrStr(int err) @@ -904,9 +906,7 @@ 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 frame_width = frame_height = 0; ok = false; } @@ -1190,32 +1190,25 @@ bool CvVideoWriter_FFMPEG::writeFrame( const unsigned char* data, int step, int avpicture_fill((AVPicture *)input_picture, (uint8_t *) data, (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){ - return false; + if( !img_convert_ctx ) + { + img_convert_ctx = sws_getContext(width, + height, + (PixelFormat)input_pix_fmt, + c->width, + c->height, + c->pix_fmt, + SWS_BICUBIC, + NULL, NULL, NULL); + if( !img_convert_ctx ) + 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; - } - sws_freeContext(img_convert_ctx); -#endif } else{ avpicture_fill((AVPicture *)picture, (uint8_t *) data, @@ -1235,7 +1228,7 @@ void CvVideoWriter_FFMPEG::close() // nothing to do if already released if ( !picture ) return; - + /* no more frame to compress. The codec has a latency of a few frames if using B frames, so we get the last frames by passing the same picture again */ @@ -1244,7 +1237,7 @@ void CvVideoWriter_FFMPEG::close() /* write the trailer, if any */ if(ok && oc) { - if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) + if( (oc->oformat->flags & AVFMT_RAWPICTURE) == 0 ) { for(;;) { @@ -1255,361 +1248,369 @@ void CvVideoWriter_FFMPEG::close() } av_write_trailer(oc); } + + if( img_convert_ctx ) + { + sws_freeContext(img_convert_ctx); + img_convert_ctx = 0; + } // free pictures #if LIBAVFORMAT_BUILD > 4628 - if( video_st->codec->pix_fmt != input_pix_fmt){ + 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 < ((52<<16)+(123<<8)+0) #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 #else - avio_close(oc->pb); + avio_close(oc->pb); #endif - } - - /* free the stream */ - av_free(oc); - - if( temp_image.data ) - { - free(temp_image.data); - temp_image.data = 0; - } - - 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 ) + /* free the stream */ + av_free(oc); + + if( temp_image.data ) { - CodecID codec_id = CODEC_ID_NONE; - int err, codec_pix_fmt; - double bitrate_scale = 1; + free(temp_image.data); + temp_image.data = 0; + } - close(); + init(); +} - // check arguments - if( !filename ) - return false; - if(fps <= 0) - return false; - - // we allow frames of odd width or height, but in this case we truncate - // the rightmost column/the bottom row. Probably, this should be handled more elegantly, - // but some internal functions inside FFMPEG swscale require even width/height. - width &= -2; - height &= -2; - if( width <= 0 || height <= 0 ) - return false; +/// 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; + double bitrate_scale = 1; - // tell FFMPEG to register codecs - av_register_all(); - av_log_set_level(AV_LOG_ERROR); + close(); - /* auto detect the output format from the name and fourcc code. */ + // check arguments + if( !filename ) + return false; + if(fps <= 0) + return false; + + // we allow frames of odd width or height, but in this case we truncate + // the rightmost column/the bottom row. Probably, this should be handled more elegantly, + // but some internal functions inside FFMPEG swscale require even width/height. + width &= -2; + height &= -2; + if( width <= 0 || height <= 0 ) + return false; + + // tell FFMPEG to register codecs + av_register_all(); + av_log_set_level(AV_LOG_ERROR); + + /* 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; + 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 */ + /* 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 = 3; - 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; - } - - double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2); + 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 = 3; + 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; + } + + double bitrate = MIN(bitrate_scale*fps*width*height, (double)INT_MAX/2); - // TODO -- safe to ignore output audio stream? - video_st = icv_add_video_stream_FFMPEG(oc, codec_id, - width, height, (int)(bitrate + 0.5), - fps, codec_pix_fmt); + // TODO -- safe to ignore output audio stream? + video_st = icv_add_video_stream_FFMPEG(oc, codec_id, + width, height, (int)(bitrate + 0.5), + fps, codec_pix_fmt); - /* set the output parameters (must be done even if no - parameters). */ + /* set the output parameters (must be done even if no + parameters). */ #if LIBAVFORMAT_BUILD < CALC_FFMPEG_VERSION(53, 2, 0) - if (av_set_parameters(oc, NULL) < 0) { - return false; - } + if (av_set_parameters(oc, NULL) < 0) { + return false; + } #endif #if 0 #if FF_API_DUMP_FORMAT - dump_format(oc, 0, filename, 1); + dump_format(oc, 0, filename, 1); #else - av_dump_format(oc, 0, filename, 1); + av_dump_format(oc, 0, filename, 1); #endif #endif - /* 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; - } + /* 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; + } - 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) { - fprintf(stderr, "Could not find encoder for codec id %d: %s", c->codec_id, icvFFMPEGErrStr( - #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) - AVERROR_ENCODER_NOT_FOUND - #else - -1 - #endif - )); - return false; - } + c->codec_tag = fourcc; + /* find the video encoder */ + codec = avcodec_find_encoder(c->codec_id); + if (!codec) { + fprintf(stderr, "Could not find encoder for codec id %d: %s", c->codec_id, icvFFMPEGErrStr( + #if LIBAVFORMAT_BUILD >= CALC_FFMPEG_VERSION(53, 2, 0) + AVERROR_ENCODER_NOT_FOUND + #else + -1 + #endif + )); + return false; + } - unsigned long long lbit_rate = static_cast(c->bit_rate); - lbit_rate += (bitrate / 2); - lbit_rate = std::min(lbit_rate, static_cast(std::numeric_limits::max())); - c->bit_rate_tolerance = static_cast(lbit_rate); - c->bit_rate = static_cast(lbit_rate); + unsigned long long lbit_rate = static_cast(c->bit_rate); + lbit_rate += (bitrate / 2); + lbit_rate = std::min(lbit_rate, static_cast(std::numeric_limits::max())); + c->bit_rate_tolerance = static_cast(lbit_rate); + c->bit_rate = static_cast(lbit_rate); - /* open the codec */ - if ((err= + /* open the codec */ + if ((err= #if LIBAVCODEC_VERSION_INT >= ((53<<16)+(8<<8)+0) - avcodec_open2(c, codec, NULL) + avcodec_open2(c, codec, NULL) #else - avcodec_open(c, codec) + avcodec_open(c, codec) #endif - ) < 0) { - fprintf(stderr, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); + ) < 0) { + fprintf(stderr, "Could not open codec '%s': %s", codec->name, icvFFMPEGErrStr(err)); + return false; + } + + 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); + } + + 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; + } + + /* 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; } + } - 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); - } - - 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; - } - - /* 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; - } - } - - /* open the output file, if needed */ - if (!(fmt->flags & AVFMT_NOFILE)) { + /* 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) + if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) #else - if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) + if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) #endif - { - return false; - } - } - - /* write the stream header, if any */ - err=avformat_write_header(oc, NULL); - if(err < 0) - { - close(); - remove(filename); + { return false; } - frame_width = width; - frame_height = height; - ok = true; - return true; } - - - CvCapture_FFMPEG* cvCreateFileCapture_FFMPEG( const char* filename ) + /* write the stream header, if any */ + err=avformat_write_header(oc, NULL); + if(err < 0) { - CvCapture_FFMPEG* capture = (CvCapture_FFMPEG*)malloc(sizeof(*capture)); - capture->init(); - if( capture->open( filename )) - return capture; - capture->close(); - free(capture); - return 0; + close(); + remove(filename); + return false; } + frame_width = width; + frame_height = height; + ok = true; + return true; +} - void cvReleaseCapture_FFMPEG(CvCapture_FFMPEG** capture) + +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 ) { - if( capture && *capture ) - { - (*capture)->close(); - free(*capture); - *capture = 0; - } + (*capture)->close(); + free(*capture); + *capture = 0; } +} - int cvSetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id, double 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); +} + +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); +} + +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 ) { - return capture->setProperty(prop_id, value); - } - - double cvGetCaptureProperty_FFMPEG(CvCapture_FFMPEG* capture, int prop_id) - { - return capture->getProperty(prop_id); - } - - 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); - } - - 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; + (*writer)->close(); + free(*writer); + *writer = 0; } +} - void cvReleaseVideoWriter_FFMPEG( CvVideoWriter_FFMPEG** writer ) - { - 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/test/test_precomp.hpp b/modules/highgui/test/test_precomp.hpp index 786ef3867..458a077e2 100644 --- a/modules/highgui/test/test_precomp.hpp +++ b/modules/highgui/test/test_precomp.hpp @@ -57,5 +57,11 @@ # define BUILD_WITH_VIDEO_OUTPUT_SUPPORT 0 #endif +namespace cvtest +{ + +string fourccToString(int fourcc); + +} #endif diff --git a/modules/highgui/test/test_video_io.cpp b/modules/highgui/test/test_video_io.cpp index bfaf25270..6c09c9ba0 100644 --- a/modules/highgui/test/test_video_io.cpp +++ b/modules/highgui/test/test_video_io.cpp @@ -46,76 +46,76 @@ using namespace cv; using namespace std; +string cvtest::fourccToString(int fourcc) +{ + return format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255); +} + +struct VideoFmt +{ + VideoFmt() { fourcc = -1; } + VideoFmt(const string& _ext, int _fourcc) : ext(_ext), fourcc(_fourcc) {} + bool empty() const { return ext.empty(); } + + string ext; + int fourcc; +}; + +static const VideoFmt specific_fmt_list[] = +{ + VideoFmt("avi", CV_FOURCC('m', 'p', 'e', 'g')), + VideoFmt("avi", CV_FOURCC('M', 'J', 'P', 'G')), + VideoFmt("avi", CV_FOURCC('I', 'Y', 'U', 'V')), + VideoFmt("mkv", CV_FOURCC('X', 'V', 'I', 'D')), + VideoFmt("mov", CV_FOURCC('m', 'p', '4', 'v')), + VideoFmt() +}; + class CV_HighGuiTest : public cvtest::BaseTest { protected: void ImageTest(const string& dir); - void VideoTest (const string& dir, int fourcc); + void VideoTest (const string& dir, const VideoFmt& fmt); void SpecificImageTest (const string& dir); - void SpecificVideoFileTest (const string& dir, const char codecchars[4]); - void SpecificVideoCameraTest (const string& dir, const char codecchars[4]); + void SpecificVideoTest (const string& dir, const VideoFmt& fmt); -public: - CV_HighGuiTest(); - ~CV_HighGuiTest(); + CV_HighGuiTest() {} + ~CV_HighGuiTest() {} virtual void run(int) = 0; }; class CV_ImageTest : public CV_HighGuiTest { public: - CV_ImageTest(); - ~CV_ImageTest(); + CV_ImageTest() {} + ~CV_ImageTest() {} void run(int); }; class CV_SpecificImageTest : public CV_HighGuiTest { public: - CV_SpecificImageTest(); - ~CV_SpecificImageTest(); + CV_SpecificImageTest() {} + ~CV_SpecificImageTest() {} void run(int); }; class CV_VideoTest : public CV_HighGuiTest { public: - CV_VideoTest(); - ~CV_VideoTest(); + CV_VideoTest() {} + ~CV_VideoTest() {} void run(int); }; -class CV_SpecificVideoFileTest : public CV_HighGuiTest +class CV_SpecificVideoTest : public CV_HighGuiTest { public: - CV_SpecificVideoFileTest(); - ~CV_SpecificVideoFileTest(); + CV_SpecificVideoTest() {} + ~CV_SpecificVideoTest() {} void run(int); }; -class CV_SpecificVideoCameraTest : public CV_HighGuiTest -{ -public: - CV_SpecificVideoCameraTest(); - ~CV_SpecificVideoCameraTest(); - void run(int); -}; - -CV_HighGuiTest::CV_HighGuiTest() {} -CV_HighGuiTest::~CV_HighGuiTest() {} - -CV_ImageTest::CV_ImageTest() : CV_HighGuiTest() {} -CV_VideoTest::CV_VideoTest() : CV_HighGuiTest() {} -CV_SpecificImageTest::CV_SpecificImageTest() : CV_HighGuiTest() {} -CV_SpecificVideoFileTest::CV_SpecificVideoFileTest() : CV_HighGuiTest() {} -CV_SpecificVideoCameraTest::CV_SpecificVideoCameraTest() : CV_HighGuiTest() {} - -CV_ImageTest::~CV_ImageTest() {} -CV_VideoTest::~CV_VideoTest() {} -CV_SpecificImageTest::~CV_SpecificImageTest() {} -CV_SpecificVideoFileTest::~CV_SpecificVideoFileTest() {} -CV_SpecificVideoCameraTest::~CV_SpecificVideoCameraTest() {} - double PSNR(const Mat& m1, const Mat& m2) { Mat tmp; @@ -232,10 +232,11 @@ void CV_HighGuiTest::ImageTest(const string& dir) ts->set_failed_test_info(ts->OK); } -void CV_HighGuiTest::VideoTest(const string& dir, int fourcc) + +void CV_HighGuiTest::VideoTest(const string& dir, const VideoFmt& fmt) { string src_file = dir + "../cv/shared/video_for_test.avi"; - string tmp_name = "video.avi"; + string tmp_name = format("video.%s", fmt.ext.c_str()); ts->printf(ts->LOG, "reading video : %s\n", src_file.c_str()); @@ -258,10 +259,11 @@ void CV_HighGuiTest::VideoTest(const string& dir, int fourcc) if (writer == 0) { - writer = cvCreateVideoWriter(tmp_name.c_str(), fourcc, 24, cvGetSize(img)); + writer = cvCreateVideoWriter(tmp_name.c_str(), fmt.fourcc, 24, cvGetSize(img)); if (writer == 0) { - ts->printf(ts->LOG, "can't create writer (with fourcc : %d)\n", fourcc); + ts->printf(ts->LOG, "can't create writer (with fourcc : %d)\n", + cvtest::fourccToString(fmt.fourcc).c_str()); cvReleaseCapture( &cap ); ts->set_failed_test_info(ts->FAIL_MISMATCH); return; @@ -325,7 +327,7 @@ void CV_HighGuiTest::SpecificImageTest(const string& dir) return; } - cv::resize(image, image, cv::Size(968, 757), 0.0, 0.0, cv::INTER_CUBIC); + resize(image, image, Size(968, 757), 0.0, 0.0, INTER_CUBIC); stringstream s_digit; s_digit << i; @@ -394,247 +396,99 @@ void CV_HighGuiTest::SpecificImageTest(const string& dir) ts->set_failed_test_info(ts->OK); } -void CV_HighGuiTest::SpecificVideoFileTest(const string& dir, const char codecchars[4]) -{ - const string exts[] = {"avi", "mov", "mpg", "wmv"}; - const size_t n = sizeof(exts)/sizeof(exts[0]); - int fourcc0 = CV_FOURCC(codecchars[0], codecchars[1], codecchars[2], codecchars[3]); - - for (size_t j = 0; j < n; ++j) - { - string ext = exts[j]; - int fourcc = fourcc0; - - if( (ext == "mov" && fourcc != CV_FOURCC('M', 'J', 'P', 'G')) || - (ext == "mpg" && fourcc != CV_FOURCC('m', 'p', 'e', 'g')) || - (ext == "wmv" && fourcc != CV_FOURCC('M', 'J', 'P', 'G'))) - continue; - if( ext == "mov" ) - fourcc = CV_FOURCC('m', 'p', '4', 'v'); - - string fourcc_str = format("%c%c%c%c", fourcc & 255, (fourcc >> 8) & 255, (fourcc >> 16) & 255, (fourcc >> 24) & 255); - const string video_file = "video_" + fourcc_str + "." + ext; - Size frame_size(968 & -2, 757 & -2); - //Size frame_size(968 & -16, 757 & -16); - //Size frame_size(640, 480); +void CV_HighGuiTest::SpecificVideoTest(const string& dir, const VideoFmt& fmt) +{ + string ext = fmt.ext; + int fourcc = fmt.fourcc; + + string fourcc_str = cvtest::fourccToString(fourcc); + const string video_file = "video_" + fourcc_str + "." + ext; + + Size frame_size(968 & -2, 757 & -2); + VideoWriter writer(video_file, fourcc, 25, frame_size, true); + + if (!writer.isOpened()) + { + // call it repeatedly for easier debugging VideoWriter writer(video_file, fourcc, 25, frame_size, true); - - if (!writer.isOpened()) - { - VideoWriter writer(video_file, fourcc, 25, frame_size, true); - ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); - ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - continue; - } - - const size_t IMAGE_COUNT = 30; - - for(size_t i = 0; i < IMAGE_COUNT; ++i) - { - stringstream s_digit; - if (i < 10) {s_digit << "0"; s_digit << i;} - else s_digit << i; - - const string file_path = dir+"../python/images/QCIF_"+s_digit.str()+".bmp"; - - cv::Mat img = imread(file_path, CV_LOAD_IMAGE_COLOR); - - if (img.empty()) - { - ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); - ts->printf(ts->LOG, "Error: cannot read frame from %s.\n", (ts->get_data_path()+"../python/images/QCIF_"+s_digit.str()+".bmp").c_str()); - ts->printf(ts->LOG, "Continue creating the video file...\n"); - ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); - break;//continue; - } - - cv::resize(img, img, frame_size, 0.0, 0.0, cv::INTER_CUBIC); - - for (int k = 0; k < img.rows; ++k) - for (int l = 0; l < img.cols; ++l) - if (img.at(k, l) == Vec3b::all(0)) - img.at(k, l) = Vec3b(0, 255, 0); - else img.at(k, l) = Vec3b(0, 0, 255); - - imwrite("QCIF_"+s_digit.str()+".bmp", img); - - writer << img; - } - - writer.release(); - cv::VideoCapture cap(video_file); - - size_t FRAME_COUNT = (size_t)cap.get(CV_CAP_PROP_FRAME_COUNT); - - if (FRAME_COUNT != IMAGE_COUNT && ext != "mpg" ) - { - ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); - ts->printf(ts->LOG, "Required frame count: %d; Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT); - ts->printf(ts->LOG, "Error: Incorrect frame count in the video.\n"); - ts->printf(ts->LOG, "Continue checking...\n"); - ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); - } - - //cap.set(CV_CAP_PROP_POS_FRAMES, -1); - - for (int i = 0; i < (int)std::min(FRAME_COUNT, IMAGE_COUNT)-1; i++) - { - cv::Mat frame; cap >> frame; - if (frame.empty()) - { - ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); - ts->printf(ts->LOG, "File name: video_%s.%s\n", fourcc_str.c_str(), ext.c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); - ts->printf(ts->LOG, "Error: cannot read the next frame with index %d.\n", i+1); - ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); - break; - } - - stringstream s_digit; - if (i+1 < 10) {s_digit << "0"; s_digit << i+1;} - else s_digit << i+1; - - cv::Mat img = imread("QCIF_"+s_digit.str()+".bmp", CV_LOAD_IMAGE_COLOR); - - if (img.empty()) - { - ts->printf(ts->LOG, "\nError: cannot read an image from %s.\n", ("QCIF_"+s_digit.str()+".bmp").c_str()); - ts->set_failed_test_info(ts->FAIL_MISMATCH); - continue; - } - - const double thresDbell = 40; - - double psnr = PSNR(img, frame); - - if (psnr > thresDbell) - { - ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); - ts->printf(ts->LOG, "Frame index: %d\n", i+1); - ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); - ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell); - ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); - break; - } - } - } -} - -void CV_HighGuiTest::SpecificVideoCameraTest(const string& dir, const char codecchars[4]) -{ - const string ext[] = {"avi", "mov", "mp4", "mpg", "wmv"}; - - const size_t n = sizeof(ext)/sizeof(ext[0]); - - const int IMAGE_COUNT = 125; - - cv::VideoCapture cap(0); - - if (!cap.isOpened()) - { - ts->printf(ts->LOG, "\nError: cannot start working with device.\n"); - ts->set_failed_test_info(ts->OK); + ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); + ts->printf(ts->LOG, "Cannot create VideoWriter object with codec %s.\n", fourcc_str.c_str()); + ts->set_failed_test_info(ts->FAIL_MISMATCH); return; } - for (size_t i = 0; i < n; ++i) - if ((ext[i]!="mp4")||(string(&codecchars[0], 4)!="IYUV")) - #if defined WIN32 || defined _WIN32 - if (((ext[i]!="mov")||(string(&codecchars[0], 4)=="XVID"))&&(ext[i]!="mp4")) - #endif + const size_t IMAGE_COUNT = 30; + vector images; + + for( size_t i = 0; i < IMAGE_COUNT; ++i ) { - Mat frame; int framecount = 0; - cv::VideoWriter writer; + string file_path = format("%s../python/images/QCIF_%02d.bmp", dir.c_str(), i); + Mat img = imread(file_path, CV_LOAD_IMAGE_COLOR); - std::vector tmp_img(IMAGE_COUNT); + if (img.empty()) + { + ts->printf(ts->LOG, "Creating a video in %s...\n", video_file.c_str()); + ts->printf(ts->LOG, "Error: cannot read frame from %s.\n", file_path.c_str()); + ts->printf(ts->LOG, "Continue creating the video file...\n"); + ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA); + break; + } - writer.open("video_"+string(&codecchars[0], 4)+"."+ext[i], CV_FOURCC(codecchars[0], codecchars[1], codecchars[2], codecchars[3]), 25, Size(968, 757), true); + for (int k = 0; k < img.rows; ++k) + for (int l = 0; l < img.cols; ++l) + if (img.at(k, l) == Vec3b::all(0)) + img.at(k, l) = Vec3b(0, 255, 0); + else img.at(k, l) = Vec3b(0, 0, 255); + + resize(img, img, frame_size, 0.0, 0.0, INTER_CUBIC); - if (!writer.isOpened()) + images.push_back(img); + writer << img; + } + + writer.release(); + VideoCapture cap(video_file); + + size_t FRAME_COUNT = (size_t)cap.get(CV_CAP_PROP_FRAME_COUNT); + + if (FRAME_COUNT != IMAGE_COUNT ) + { + ts->printf(ts->LOG, "\nFrame count checking for video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); + ts->printf(ts->LOG, "Required frame count: %d; Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT); + ts->printf(ts->LOG, "Error: Incorrect frame count in the video.\n"); + ts->printf(ts->LOG, "Continue checking...\n"); + ts->set_failed_test_info(ts->FAIL_BAD_ACCURACY); + return; + } + + for (int i = 0; i < FRAME_COUNT; i++) + { + Mat frame; cap >> frame; + if (frame.empty()) { ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); - ts->printf(ts->LOG, "Video codec: %s\n", std::string(&codecchars[0], 4).c_str()); - ts->printf(ts->LOG, "Error: cannot create VideoWriter object for video_%s.%s.\n", string(&codecchars[0]).c_str(), ext[i].c_str()); - ts->set_failed_test_info(ts->FAIL_EXCEPTION); - continue; + ts->printf(ts->LOG, "File name: video_%s.%s\n", fourcc_str.c_str(), ext.c_str()); + ts->printf(ts->LOG, "Video codec: %s\n", fourcc_str.c_str()); + ts->printf(ts->LOG, "Error: cannot read the next frame with index %d.\n", i+1); + ts->set_failed_test_info(ts->FAIL_MISSING_TEST_DATA); + break; } - for (;;) + Mat img = images[i]; + + const double thresDbell = 40; + double psnr = PSNR(img, frame); + + if (psnr > thresDbell) { - cap >> frame; - - if (frame.empty()) - { - ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); - ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); - ts->printf(ts->LOG, "Error: cannot read next frame with index %d from the device.\n", framecount); - break; - } - - cv::resize(frame, frame, Size(968, 757), 0, 0, INTER_CUBIC); - writer << frame; tmp_img[framecount] = frame; - - framecount++; - if (framecount == IMAGE_COUNT) break; - } - - cv::VideoCapture vcap(dir+"video_"+string(&codecchars[0], 4)+"."+ext[i]); - - if (!vcap.isOpened()) - { - ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); - ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); - ts->printf(ts->LOG, "Error: cannot open video file.\n"); - continue; - } - - int FRAME_COUNT = (int)vcap.get(CV_CAP_PROP_FRAME_COUNT); - - if (FRAME_COUNT != IMAGE_COUNT) - { - ts->printf(ts->LOG, "\nChecking frame count...\n"); - ts->printf(ts->LOG, "Video file directory: %s\n", "."); - ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); - ts->printf(ts->LOG, "Required frame count: %d Returned frame count: %d\n", IMAGE_COUNT, FRAME_COUNT); - ts->printf(ts->LOG, "Error: required and returned frame count are not matched.\n"); - ts->printf(ts->LOG, "Continue checking...\n"); - ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT); - } - - cv::Mat img; framecount = 0; - vcap.set(CV_CAP_PROP_POS_FRAMES, 0); - - for ( ; framecount < std::min(FRAME_COUNT, IMAGE_COUNT); framecount++ ) - { - vcap >> img; - - if (img.empty()) - { - ts->printf(ts->LOG, "\nVideo file directory: %s\n", "."); - ts->printf(ts->LOG, "File name: video_%s.%s\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); - ts->printf(ts->LOG, "Video codec: %s\n", string(&codecchars[0], 4).c_str()); - ts->printf(ts->LOG, "Error: cannot read frame with index %d from the video.\n", framecount); - break; - } - - const double thresDbell = 20; - double psnr = PSNR(img, tmp_img[framecount]); - - if (psnr > thresDbell) - { - ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", string(&codecchars[0], 4).c_str(), ext[i].c_str()); - ts->printf(ts->LOG, "Frame index: %d\n", framecount); - ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); - ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell); - ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); - continue; - } + ts->printf(ts->LOG, "\nReading frame from the file video_%s.%s...\n", fourcc_str.c_str(), ext.c_str()); + ts->printf(ts->LOG, "Frame index: %d\n", i+1); + ts->printf(ts->LOG, "Difference between saved and original images: %g\n", psnr); + ts->printf(ts->LOG, "Maximum allowed difference: %g\n", thresDbell); + ts->printf(ts->LOG, "Error: too big difference between saved and original images.\n"); + break; } } } @@ -651,48 +505,17 @@ void CV_SpecificImageTest::run(int) void CV_VideoTest::run(int) { - const char codecs[][4] = { {'I', 'Y', 'U', 'V'}, - {'X', 'V', 'I', 'D'}, - {'m', 'p', 'e', 'g'}, - {'M', 'J', 'P', 'G'} }; - - printf("%s", ts->get_data_path().c_str()); - - int count = sizeof(codecs)/(4*sizeof(char)); - - for (int i = 0; i < count; ++i) + for (int i = 0; !specific_fmt_list[i].empty(); ++i) { - VideoTest(ts->get_data_path(), CV_FOURCC(codecs[i][0], codecs[i][1], codecs[i][2], codecs[i][3])); + VideoTest(ts->get_data_path(), specific_fmt_list[i]); } } -void CV_SpecificVideoFileTest::run(int) +void CV_SpecificVideoTest::run(int) { - const char codecs[][4] = { {'m', 'p', 'e', 'g'}, - {'X', 'V', 'I', 'D'}, - {'M', 'J', 'P', 'G'}, - {'I', 'Y', 'U', 'V'} }; - - int count = sizeof(codecs)/(4*sizeof(char)); - - for (int i = 0; i < count; ++i) + for (int i = 0; !specific_fmt_list[i].empty(); ++i) { - SpecificVideoFileTest(ts->get_data_path(), codecs[i]); - } -} - -void CV_SpecificVideoCameraTest::run(int) -{ - const char codecs[][4] = { {'m', 'p', 'e', 'g'}, - {'X', 'V', 'I', 'D'}, - {'M', 'J', 'P', 'G'}, - {'I', 'Y', 'U', 'V'} }; - - int count = sizeof(codecs)/(4*sizeof(char)); - - for (int i = 0; i < count; ++i) - { - SpecificVideoCameraTest(ts->get_data_path(), codecs[i]); + SpecificVideoTest(ts->get_data_path(), specific_fmt_list[i]); } } @@ -702,11 +525,7 @@ TEST(Highgui_Image, regression) { CV_ImageTest test; test.safe_run(); } #if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT TEST(Highgui_Video, regression) { CV_VideoTest test; test.safe_run(); } -TEST(Highgui_SpecificVideoFile, regression) { CV_SpecificVideoFileTest test; test.safe_run(); } -#endif - -#if BUILD_WITH_VIDEO_INPUT_SUPPORT && BUILD_WITH_VIDEO_OUTPUT_SUPPORT && BUILD_WITH_CAMERA_SUPPORT -TEST(Highgui_SpecificVideoCamera, regression) { CV_SpecificVideoCameraTest test; test.safe_run(); } +TEST(Highgui_SpecificVideoFile, regression) { CV_SpecificVideoTest test; test.safe_run(); } #endif TEST(Highgui_SpecificImage, regression) { CV_SpecificImageTest test; test.safe_run(); }