/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // Intel License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000, Intel Corporation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of Intel Corporation may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // //M*/ // Authors: Konstantin Dols <dols@ient.rwth-aachen.de> // Mark Asbach <asbach@ient.rwth-aachen.de> // // Institute of Communications Engineering // RWTH Aachen University #include "precomp.hpp" // required to enable some functions used here... #define XINE_ENABLE_EXPERIMENTAL_FEATURES #include <cassert> extern "C" { #include <xine.h> //#include <xine/xineutils.h> // forward declaration from <xine/xineutils.h> const char *xine_get_homedir( void ); } typedef struct CvCaptureAVI_XINE { /// method call table xine_t * xine; xine_stream_t * stream; xine_video_port_t * vo_port; /// frame returned by xine_get_next_video_frame() xine_video_frame_t xine_frame; IplImage * yuv_frame; IplImage * bgr_frame; /// image dimansions of the input stream. CvSize size; /// framenumber of the last frame received from xine_get_next_video_frame(). /// note: always keep this value updated !!!! int frame_number; /// framerate of the opened stream double frame_rate; /// duration of a frame in stream double frame_duration; /// indicated if input is seekable bool seekable; } CvCaptureAVI_XINE; // 4:2:2 interleaved -> BGR static void icvYUY2toBGR( CvCaptureAVI_XINE * capture ) { uint8_t * v = capture->xine_frame.data; int offset; for ( int y = 0; y < capture->yuv_frame->height; y++ ) { offset = y * capture->yuv_frame->widthStep; for ( int x = 0; x < capture->yuv_frame->width; x++, offset += 3 ) { capture->yuv_frame->imageData[ offset + 1 ] = v[ 3 ]; capture->yuv_frame->imageData[ offset + 2 ] = v[ 1 ]; if ( x & 1 ) { capture->yuv_frame->imageData[ offset ] = v[ 2 ]; v += 4; } else { capture->yuv_frame->imageData[ offset ] = v[ 0 ]; } } } // convert to BGR cvCvtColor( capture->yuv_frame, capture->bgr_frame, CV_YCrCb2BGR ); } // 4:2:0 planary -> BGR static void icvYV12toBGR( CvCaptureAVI_XINE * capture ) { IplImage * yuv = capture->yuv_frame; int w_Y = capture->size.width; int h_Y = capture->size.height; int w_UV = w_Y >> 1; int size_Y = w_Y * h_Y; int size_UV = size_Y / 4; int line = yuv->widthStep; uint8_t * addr_Y = capture->xine_frame.data; uint8_t * addr_U = addr_Y + size_Y; uint8_t * addr_V = addr_U + size_UV; // YYYY..UU.VV. -> BGRBGRBGR... for ( int y = 0; y < h_Y; y++ ) { int offset = y * line; for ( int x = 0; x < w_Y; x++, offset += 3 ) { /* if ( x&1 ) { addr_U++; addr_V++; } */ int one_zero = x & 1; addr_U += one_zero; addr_V += one_zero; yuv->imageData[ offset ] = *( addr_Y++ ); yuv->imageData[ offset + 1 ] = *addr_U; yuv->imageData[ offset + 2 ] = *addr_V; } if ( y & 1 ) { addr_U -= w_UV; addr_V -= w_UV; } } /* convert to BGR */ cvCvtColor( capture->yuv_frame, capture->bgr_frame, CV_YCrCb2BGR ); } static void icvCloseAVI_XINE( CvCaptureAVI_XINE* capture ) { xine_free_video_frame( capture->vo_port, &capture->xine_frame ); if ( capture->yuv_frame ) cvReleaseImage( &capture->yuv_frame ); if ( capture->bgr_frame ) cvReleaseImage( &capture->bgr_frame ); xine_close( capture->stream ); // xine_dispose( capture->stream ); if ( capture->vo_port ) xine_close_video_driver( capture->xine, capture->vo_port ); xine_exit( capture->xine ); } /** * CHECKS IF THE STREAM IN * capture IS SEEKABLE. **/ static void icvCheckSeekAVI_XINE( CvCaptureAVI_XINE * capture ) { OPENCV_ASSERT ( capture, "icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvCheckSeekAVI_XINE( CvCaptureAVI_XINE* )", "illegal capture->vo_port"); #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE ... start\n" ); #endif // temp. frame for testing. xine_video_frame_t tmp; // try to seek to a future frame... xine_play( capture->stream, 0, 300 ); /* 300msec */ // try to receive the frame... xine_get_next_video_frame( capture->vo_port, &tmp ); // if the framenumber is still 0, we can't use the xine seek functionality capture->seekable = ( tmp.frame_number != 0 ); // reset stream xine_play( capture->stream, 0, 0 ); // release xine_frame xine_free_video_frame( capture->vo_port, &tmp ); #ifndef NDEBUG if ( capture->seekable ) fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE: Input is seekable, using XINE seek implementation.\n" ); else fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE: Input is NOT seekable, using fallback function.\n" ); fprintf( stderr, "(DEBUG) icvCheckSeekAVI_XINE ... end\n" ); #endif } static int icvOpenAVI_XINE( CvCaptureAVI_XINE* capture, const char* filename ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvOpenAVI_XINE ... start\n" ); #endif char configfile[ 2048 ]; capture->xine = xine_new(); sprintf( configfile, "%s%s", xine_get_homedir(), "/.xine/config" ); xine_config_load( capture->xine, configfile ); xine_init( capture->xine ); xine_engine_set_param( capture->xine, 0, 0 ); capture->vo_port = xine_new_framegrab_video_port( capture->xine ); if ( capture->vo_port == NULL ) { printf( "(ERROR)icvOpenAVI_XINE(): Unable to initialize video driver.\n" ); return 0; } capture->stream = xine_stream_new( capture->xine, NULL, capture->vo_port ); if ( !xine_open( capture->stream, filename ) ) { printf( "(ERROR)icvOpenAVI_XINE(): Unable to open source '%s'\n", filename ); return 0; } // reset stream... xine_play( capture->stream, 0, 0 ); // initialize some internals... capture->frame_number = 0; if ( !xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ) ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvOpenAVI_XINE ... failed!\n" ); #endif return 0; } capture->size = cvSize( capture->xine_frame.width, capture->xine_frame.height ); capture->yuv_frame = cvCreateImage( capture->size, IPL_DEPTH_8U, 3 ); capture->bgr_frame = cvCreateImage( capture->size, IPL_DEPTH_8U, 3 ); xine_free_video_frame( capture->vo_port, &capture->xine_frame ); capture->xine_frame.data[ 0 ] = 0; icvCheckSeekAVI_XINE( capture ); capture->frame_duration = xine_get_stream_info( capture->stream, XINE_STREAM_INFO_FRAME_DURATION ) / 90.; capture->frame_rate = 1000 / capture->frame_duration; #ifndef NDEBUG fprintf( stderr, "(DEBUG) frame_duration = %f, framerate = %f\n", capture->frame_duration, capture->frame_rate ); #endif OPENCV_ASSERT ( capture->yuv_frame, "icvOpenAVI_XINE( CvCaptureAVI_XINE *, const char *)", "couldn't create yuv frame"); OPENCV_ASSERT ( capture->bgr_frame, "icvOpenAVI_XINE( CvCaptureAVI_XINE *, const char *)", "couldn't create bgr frame"); #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvOpenAVI_XINE ... end\n" ); #endif return 1; } static int icvGrabFrameAVI_XINE( CvCaptureAVI_XINE* capture ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvGrabFrameAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvGrabFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture"); OPENCV_ASSERT ( capture->vo_port, "icvGrabFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture->vo_port"); int res = xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ); /* always keep internal framenumber updated !!! */ if ( res ) capture->frame_number++; #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvGrabFrameAVI_XINE ... end\n" ); #endif return res; } static const IplImage* icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE* capture, int ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvRetrieveFrameAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvRetrieveFrameAVI_XINE( CvCaptureAVI_XINE * )", "illegal capture->vo_port"); /* no frame grabbed yet? so let's do it now! */ int res = 0; if ( capture->xine_frame.data == 0 ) { res = icvGrabFrameAVI_XINE( capture ); } else { res = 1; } if ( res ) { switch ( capture->xine_frame.colorspace ) { case XINE_IMGFMT_YV12: icvYV12toBGR( capture ); #ifndef NDEBUG printf( "(DEBUG)icvRetrieveFrameAVI_XINE: converted YV12 to BGR.\n" ); #endif break; case XINE_IMGFMT_YUY2: icvYUY2toBGR( capture ); #ifndef NDEBUG printf( "(DEBUG)icvRetrieveFrameAVI_XINE: converted YUY2 to BGR.\n" ); #endif break; case XINE_IMGFMT_XVMC: printf( "(ERROR)icvRetrieveFrameAVI_XINE: XVMC format not supported!\n" ); break; case XINE_IMGFMT_XXMC: printf( "(ERROR)icvRetrieveFrameAVI_XINE: XXMC format not supported!\n" ); break; default: printf( "(ERROR)icvRetrieveFrameAVI_XINE: unknown color/pixel format!\n" ); } /* always release last xine_frame, not needed anymore, but store its frame_number in *capture ! */ xine_free_video_frame( capture->vo_port, &capture->xine_frame ); capture->xine_frame.data = 0; #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvRetrieveFrameAVI_XINE ... end\n" ); #endif return capture->bgr_frame; } #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvRetrieveFrameAVI_XINE ... failed!\n" ); #endif return 0; } /** * THIS FUNCTION IS A FALLBACK FUNCTION FOR THE CASE THAT THE XINE SEEK IMPLEMENTATION * DOESN'T WORK WITH THE ACTUAL INPUT. THIS FUNCTION IS ONLY USED IN THE CASE OF AN EMERGENCY, * BECAUSE IT IS VERY SLOW ! **/ static int icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE* capture, int f ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvOldSeekFrameAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvRetricvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvOldSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); // not needed tnx to asserts... // we need a valid capture context and it's stream to seek through // if ( !capture || !capture->stream ) return 0; // no need to seek if we are already there... if ( f == capture->frame_number ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvOldSeekFrameAVI_XINE ... end\n" ); #endif return 1; } // if the requested position is behind out actual position, // we just need to read the remaining amount of frames until we are there. else if ( f > capture->frame_number ) { for ( ;capture->frame_number < f;capture->frame_number++ ) /// un-increment framenumber grabbing failed if ( !xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ) ) { capture->frame_number--; break; } else { xine_free_video_frame( capture->vo_port, &capture->xine_frame ); } } // otherwise we need to reset the stream and // start reading frames from the beginning. else // f < capture->frame_number { /// reset stream, should also work with non-seekable input xine_play( capture->stream, 0, 0 ); /// read frames until we are at the requested frame for ( capture->frame_number = 0; capture->frame_number < f; capture->frame_number++ ) /// un-increment last framenumber if grabbing failed if ( !xine_get_next_video_frame( capture->vo_port, &capture->xine_frame ) ) { capture->frame_number--; break; } else { xine_free_video_frame( capture->vo_port, &capture->xine_frame ); } } #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvOldSeekFrameAVI_XINE ... end\n" ); #endif return ( f == capture->frame_number ) ? 1 : 0; } static int icvSeekFrameAVI_XINE( CvCaptureAVI_XINE* capture, int f ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvSeekFrameAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); // not needed tnx to asserts... // we need a valid capture context and it's stream to seek through // if ( !capture || !capture->stream ) return 0; if ( capture->seekable ) { /// use xinelib's seek functionality int new_time = ( int ) ( ( f + 1 ) * ( float ) capture->frame_duration ); #ifndef NDEBUG fprintf( stderr, "(DEBUG) calling xine_play()" ); #endif if ( xine_play( capture->stream, 0, new_time ) ) { #ifndef NDEBUG fprintf( stderr, "ok\n" ); fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... end\n" ); #endif capture->frame_number = f; return 1; } else { #ifndef NDEBUG fprintf( stderr, "failed\n" ); fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... failed\n" ); #endif return 0; } } else { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... end\n" ); #endif return icvOldSeekFrameAVI_XINE( capture, f ); } } static int icvSeekTimeAVI_XINE( CvCaptureAVI_XINE* capture, int t ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekTimeAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvSeekTimeAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekTimeAVI_XINE ... start\n" ); #endif // not needed tnx to asserts... // we need a valid capture context and it's stream to seek through // if ( !capture || !capture->stream ) return 0; if ( capture->seekable ) { /// use xinelib's seek functionality if ( xine_play( capture->stream, 0, t ) ) { capture->frame_number = ( int ) ( ( float ) t * capture->frame_rate / 1000 ); #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... end\n" ); #endif return 1; } else { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ... failed!\n" ); #endif return 0; } } else { int new_frame = ( int ) ( ( float ) t * capture->frame_rate / 1000 ); #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekFrameAVI_XINE ....end\n" ); #endif return icvOldSeekFrameAVI_XINE( capture, new_frame ); } } static int icvSeekRatioAVI_XINE( CvCaptureAVI_XINE* capture, double ratio ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvSeekRatioAVI_XINE( CvCaptureAVI_XINE *, double )", "illegal capture->vo_port"); // not needed tnx to asserts... // we need a valid capture context and it's stream to seek through // if ( !capture || !capture->stream ) return 0; /// ratio must be [0..1] if ( ratio > 1 || ratio < 0 ) return 0; if ( capture->seekable ) { // TODO: FIX IT, DOESN'T WORK PROPERLY, YET...! int pos_t, pos_l, length; xine_get_pos_length( capture->stream, &pos_l, &pos_t, &length ); fprintf( stderr, "ratio on GetProperty(): %d\n", pos_l ); /// use xinelib's seek functionality if ( xine_play( capture->stream, (int)(ratio*(float)length), 0 ) ) { capture->frame_number = ( int ) ( ratio*length / capture->frame_duration ); } else { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... failed!\n" ); #endif return 0; } } else { /// TODO: fill it ! fprintf( stderr, "icvSeekRatioAVI_XINE(): Seek not supported by stream !\n" ); fprintf( stderr, "icvSeekRatioAVI_XINE(): (seek in stream with NO seek support NOT implemented...yet!)\n" ); #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... failed!\n" ); #endif return 0; } #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSeekRatioAVI_XINE ... end!\n" ); #endif return 1; } static double icvGetPropertyAVI_XINE( CvCaptureAVI_XINE* capture, int property_id ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvGetPropertyAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->vo_port"); OPENCV_ASSERT ( capture->xine, "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->xine"); OPENCV_ASSERT ( capture->bgr_frame, "icvGetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->bgr_frame"); // not needed tnx to asserts... // we need a valid capture context and it's stream to seek through // if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0 int pos_t, pos_l, length; xine_get_pos_length( capture->stream, &pos_l, &pos_t, &length ); fprintf( stderr, "ratio on GetProperty(): %i\n", pos_l ); switch ( property_id ) { /// return actual position in msec case CV_CAP_PROP_POS_MSEC: if ( !capture->seekable ) { fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_MSEC:\n" ); fprintf( stderr, " Stream is NOT seekable, so position info may NOT be valid !!\n" ); } return pos_t; /// return actual frame number case CV_CAP_PROP_POS_FRAMES: /// we insist the capture->frame_number to be remain updated !!!! return capture->frame_number; /// return actual position ratio in the range [0..1] depending on /// the total length of the stream and the actual position case CV_CAP_PROP_POS_AVI_RATIO: if ( !capture->seekable ) { fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_POS_AVI_RATIO:\n" ); fprintf( stderr, " Stream is NOT seekable, so ratio info may NOT be valid !!\n" ); } if ( length == 0 ) break; else return pos_l / 65535; /// return width of image source case CV_CAP_PROP_FRAME_WIDTH: return capture->size.width; /// return height of image source case CV_CAP_PROP_FRAME_HEIGHT: return capture->size.height; /// return framerate of stream case CV_CAP_PROP_FPS: if ( !capture->seekable ) { fprintf( stderr, "(ERROR) GetPropertyAVI_XINE(CV_CAP_PROP_FPS:\n" ); fprintf( stderr, " Stream is NOT seekable, so FPS info may NOT be valid !!\n" ); } return capture->frame_rate; /// return four-character-code (FOURCC) of source's codec case CV_CAP_PROP_FOURCC: return ( double ) xine_get_stream_info( capture->stream, XINE_STREAM_INFO_VIDEO_FOURCC ); } #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvGetPropertyAVI_XINE ... failed!\n" ); #endif return 0; } static int icvSetPropertyAVI_XINE( CvCaptureAVI_XINE* capture, int property_id, double value ) { #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSetPropertyAVI_XINE ... start\n" ); #endif OPENCV_ASSERT ( capture, "icvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int, double )", "illegal capture"); OPENCV_ASSERT ( capture->stream, "icvGetPropericvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int )", "illegal capture->stream"); OPENCV_ASSERT ( capture->vo_port, "icvSetPropertyAVI_XINE( CvCaptureAVI_XINE *, int, double )", "illegal capture->vo_port"); // not needed tnx to asserts... // we need a valid capture context and it's stream to seek through // if ( !capture || !capture->stream || !capture->bgr_frame || !capture->xine || !capture->vo_port ) return 0 #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSetPropertyAVI_XINE: seeking to value %f ... ", value ); #endif switch ( property_id ) { /// set (seek to) position in msec case CV_CAP_PROP_POS_MSEC: return icvSeekTimeAVI_XINE( capture, ( int ) value ); /// set (seek to) frame number case CV_CAP_PROP_POS_FRAMES: return icvSeekFrameAVI_XINE( capture, ( int ) value ); /// set (seek to) position ratio in the range [0..1] depending on /// the total length of the stream and the actual position case CV_CAP_PROP_POS_AVI_RATIO: return icvSeekRatioAVI_XINE( capture, value ); default: #ifndef NDEBUG fprintf( stderr, "(DEBUG) icvSetPropertyAVI_XINE ... failed!\n" ); #endif return 0; } } static CvCaptureAVI_XINE* icvCaptureFromFile_XINE( const char* filename ) { // construct capture struct CvCaptureAVI_XINE * capture = ( CvCaptureAVI_XINE* ) cvAlloc ( sizeof ( CvCaptureAVI_XINE ) ); memset( capture, 0, sizeof ( CvCaptureAVI_XINE ) ); // initialize XINE if ( !icvOpenAVI_XINE( capture, filename ) ) return 0; OPENCV_ASSERT ( capture, "cvCaptureFromFile_XINE( const char * )", "couldn't create capture"); return capture; } class CvCaptureAVI_XINE_CPP : public CvCapture { public: CvCaptureAVI_XINE_CPP() { captureXINE = 0; } virtual ~CvCaptureAVI_XINE_CPP() { close(); } virtual bool open( const char* filename ); virtual void close(); virtual double getProperty(int); virtual bool setProperty(int, double); virtual bool grabFrame(); virtual IplImage* retrieveFrame(int); protected: CvCaptureAVI_XINE* captureXINE; }; bool CvCaptureAVI_XINE_CPP::open( const char* filename ) { close(); captureXINE = icvCaptureFromFile_XINE(filename); return captureXINE != 0; } void CvCaptureAVI_XINE_CPP::close() { if( captureXINE ) { icvCloseAVI_XINE( captureXINE ); cvFree( &captureXINE ); } } bool CvCaptureAVI_XINE_CPP::grabFrame() { return captureXINE ? icvGrabFrameAVI_XINE( captureXINE ) != 0 : false; } IplImage* CvCaptureAVI_XINE_CPP::retrieveFrame(int) { return captureXINE ? (IplImage*)icvRetrieveFrameAVI_XINE( captureXINE, 0 ) : 0; } double CvCaptureAVI_XINE_CPP::getProperty( int propId ) { return captureXINE ? icvGetPropertyAVI_XINE( captureXINE, propId ) : 0; } bool CvCaptureAVI_XINE_CPP::setProperty( int propId, double value ) { return captureXINE ? icvSetPropertyAVI_XINE( captureXINE, propId, value ) != 0 : false; } CvCapture* cvCreateFileCapture_XINE(const char* filename) { CvCaptureAVI_XINE_CPP* capture = new CvCaptureAVI_XINE_CPP; if( capture->open(filename)) return capture; delete capture; return 0; } #undef NDEBUG