cvcap.cpp.svn-base

来自「非结构化路识别」· SVN-BASE 代码 · 共 1,486 行 · 第 1/4 页

SVN-BASE
1,486
字号
    (CvCaptureSetPropertyFunc)0,
    (CvCaptureGetDescriptionFunc)0
};

#endif //USE_MIL 
//#endif //WIN32

HIGHGUI_IMPL CvCapture* cvCaptureFromCAM( int index )
{
    if( index < 100 ) //try VFW 
    {
        CvCaptureCAM_VFW* capture = (CvCaptureCAM_VFW*)cvAlloc( sizeof(*capture));
        memset( capture, 0, sizeof(*capture));

        capture->vtable = &captureCAM_VFW_vtable;

        if( !icvOpenCAM_VFW( capture, index ))
            cvReleaseCapture( (CvCapture**)&capture );
        else return (CvCapture*)capture;
    }
#ifdef USE_MIL
    if( index >= 100 || index < 0 ) //try MIL 
    {
        CvCaptureCAM_MIL* capture = (CvCaptureCAM_MIL*)cvAlloc( sizeof(*capture));
        memset( capture, 0, sizeof(*capture));

        capture->vtable = &captureCAM_MIL_vtable;

        if( !icvOpenCAM_MIL( capture, index ))
            cvReleaseCapture( (CvCapture**)&capture );
        else return (CvCapture*)capture;
    }
#endif
    return 0;
}


/*************************** writing AVIs ******************************/

typedef struct CvAVIWriter
{
    PAVIFILE avifile;
    PAVISTREAM compressed;
    PAVISTREAM uncompressed;
    double fps;
    CvSize frameSize;
    IplImage* tempFrame;
    long pos;
    int fourcc;
}
CvAVIWriter;


static void icvCloseAVIWriter( CvAVIWriter* writer )
{
    if( writer )
    {
        if( writer->uncompressed )
            AVIStreamRelease( writer->uncompressed );
        if( writer->compressed )
            AVIStreamRelease( writer->compressed );
        if( writer->avifile )
            AVIFileRelease( writer->avifile );
        cvReleaseImage( &writer->tempFrame );
        memset( writer, 0, sizeof(*writer));
    }
}


static int icvInitAVIWriter( CvAVIWriter* writer, int fourcc,
                             double fps, CvSize frameSize )
{
    if( writer && writer->avifile )
    {
        AVICOMPRESSOPTIONS copts, *pcopts = &copts;
        AVISTREAMINFO aviinfo;

        assert( frameSize.width > 0 && frameSize.height > 0 );

        BITMAPINFOHEADER bmih = icvBitmapHeader( frameSize.width, frameSize.height, 24 );
        
        memset( &aviinfo, 0, sizeof(aviinfo));
        aviinfo.fccType = streamtypeVIDEO;
        aviinfo.fccHandler = 0;
        aviinfo.dwScale = 1;
        aviinfo.dwRate = cvRound(fps);
        aviinfo.rcFrame.top = aviinfo.rcFrame.left = 0;
        aviinfo.rcFrame.right = frameSize.width;
        aviinfo.rcFrame.bottom = frameSize.height;

        if( AVIFileCreateStream( writer->avifile,
            &writer->uncompressed, &aviinfo ) == AVIERR_OK )
        {
            copts.fccType = streamtypeVIDEO;
            copts.fccHandler = fourcc != -1 ? fourcc : 0; 
            copts.dwKeyFrameEvery = 1; 
            copts.dwQuality = 90; 
            copts.dwBytesPerSecond = 0; 
            copts.dwFlags = AVICOMPRESSF_VALID; 
            copts.lpFormat = &bmih; 
            copts.cbFormat = sizeof(bmih); 
            copts.lpParms = 0; 
            copts.cbParms = 0; 
            copts.dwInterleaveEvery = 0;

            if( fourcc != -1 ||
                AVISaveOptions( 0, 0, 1, &writer->uncompressed, &pcopts ) == TRUE )
            {
                if( AVIMakeCompressedStream( &writer->compressed,
                    writer->uncompressed, pcopts, 0 ) == AVIERR_OK &&
                    // check that the resolution was not changed
                    bmih.biWidth == frameSize.width &&
                    bmih.biHeight == frameSize.height &&
                    AVIStreamSetFormat( writer->compressed, 0, &bmih, sizeof(bmih)) == AVIERR_OK )
                    {
                        writer->fps = fps;
                        writer->fourcc = (int)copts.fccHandler;
                        writer->frameSize = frameSize;
                        writer->tempFrame = cvCreateImage( frameSize, 8, 3 );
                        return 1;
                    }
            }
        }
    }
    icvCloseAVIWriter( writer );
    return 0;
}


HIGHGUI_IMPL CvAVIWriter* cvCreateAVIWriter( const char* filename, int fourcc,
                                             double fps, CvSize frameSize )
{
    CvAVIWriter* writer = (CvAVIWriter*)cvAlloc( sizeof(CvAVIWriter));
    memset( writer, 0, sizeof(*writer));

    icvInitCapture_VFW();
    
    if( AVIFileOpen( &writer->avifile, filename, OF_CREATE | OF_WRITE, 0 ) == AVIERR_OK )
    {
        if( frameSize.width > 0 && frameSize.height > 0 )
        {
            if( !icvInitAVIWriter( writer, fourcc, fps, frameSize ))
                cvReleaseAVIWriter( &writer );
        }
        else if( fourcc == -1 )
        {
            icvCloseAVIWriter( writer );
        }
        else
        {
            /* postpone initialization until the first frame is written */
            writer->fourcc = fourcc;
            writer->fps = fps;
            writer->frameSize = frameSize;
        }
    }
    
    return writer;
}


HIGHGUI_IMPL int cvWriteToAVI( CvAVIWriter* writer, const IplImage* image )
{
    if( writer && (writer->compressed ||
        icvInitAVIWriter( writer, writer->fourcc, writer->fps, writer->frameSize )))
    {
        if( image->origin == 0 )
        {
            cvFlip( image, writer->tempFrame, 0 );
            image = (const IplImage*)writer->tempFrame;
        }
        if( AVIStreamWrite( writer->compressed, writer->pos++, 1, image->imageData,
                            image->imageSize, AVIIF_KEYFRAME, 0, 0 ) == AVIERR_OK )
        {
            return 1;
        }
    }
    return 0;
}


HIGHGUI_IMPL void cvReleaseAVIWriter( CvAVIWriter** writer )
{
    if( writer && *writer )
    {
        icvCloseAVIWriter( *writer );
        cvFree( (void**)writer );
    }
}

#else /* Linux version */

#ifdef HAVE_FFMPEG

typedef struct avi_entry
{
    int id;
    int flags;
    int offset;
    int size;
}
avi_entry;

typedef struct avi_entry_compact
{
    int flags;
    int offset;
}
avi_entry_compact;


typedef struct CvCaptureAVI_FFMPEG
{
    CvCaptureVTable* vtable;
    AVCodec *codec;
    AVCodecContext *avctx;
    AVFrame* picture;
    AVPicture rgb_picture;

    int codec_fourcc;
    int codec_sub_fourcc;

    CvSlice film_range;
    int pos;

    CvSize frame_size;
    double fps;
    FILE* file;
    int64 data_offset;
    int64 file_size;
    int64 offset;
    int stream_index;
    char* buffer;
    int buffer_size;
    avi_entry_compact* entries;
    IplImage frame;
}
CvCaptureAVI_FFMPEG;


#define fourcc(c1,c2,c3,c4) \
    (((c1)&255) + (((c2)&255)<<8) + (((c3)&255)<<16) + (((c4)&255)<<24))

static int read4( CvCaptureAVI_FFMPEG* capture )
{
    unsigned char buffer[4];
    if( fread( buffer, 1, 4, capture->file ) == 4 )
    {
        capture->offset += 4;
        return fourcc(buffer[0],buffer[1],buffer[2],buffer[3]);
    }
    else
        return -1;
}

static void skip( CvCaptureAVI_FFMPEG* capture, int bytes )
{
    if( bytes != 0 )
    {
        fseek( capture->file, bytes, SEEK_CUR );
        capture->offset += bytes;
    }
}

static void icvInitCapture_FFMPEG()
{
    static int isInitialized = 0;
    if( !isInitialized )
    {
        avcodec_init();
        avcodec_register_all();
        isInitialized = 1;
    }
}

static void icvCloseAVI_FFMPEG( CvCaptureAVI_FFMPEG* capture )
{
    cvFree( (void**)&(capture->entries) );
    
    if( capture->avctx )
    {
        avcodec_close( capture->avctx );
        cvFree( (void**)&capture->avctx );
        //capture->avctx = 0;
    }

    if( capture->file )
    {
        fclose( capture->file );
        capture->file = 0;
    }

    if( capture->picture )
    {
        free( capture->picture );
        capture->picture = 0;
    }
    
    if( capture->rgb_picture.data[0] )
        cvFree( (void**)&capture->rgb_picture.data[0] );

    cvFree( (void**)&capture->buffer );

    capture->codec = 0;
    capture->pos = 0;
    capture->film_range.startIndex = capture->film_range.endIndex = 0;
    memset( &capture->frame, 0, sizeof(capture->frame));
}


static int icvOpenAVI_FFMPEG( CvCaptureAVI_FFMPEG* capture, const char* filename )
{
    int err, valid = 0;
    int val;
    icvInitCapture_FFMPEG();
    
    capture->file = fopen( filename, "rb" );
    if(!capture->file)
        return 0;

    capture->stream_index = -1;
    capture->file = fopen( filename, "rb" );
    if( !capture->file )
        goto exit_func;

    val = read4( capture );
    if( val != fourcc('R','I','F','F'))
        goto exit_func;

    capture->file_size = read4( capture );
    val = read4( capture );
    if( val != fourcc('A','V','I',' '))
        goto exit_func;

    for(;;)
    {
        int64 new_offset;
        val = read4( capture );

        if( val == -1 )
            break;

        new_offset = read4( capture );
        new_offset += capture->offset;

        if( val == fourcc('L','I','S','T'))
        {
            val = read4( capture );

            switch( val )
            {
            case fourcc('m','o','v','i'):
                capture->data_offset = capture->offset;
                break;
            case fourcc('h','d','r','l'):
            {
                int hdr_len, list_len, stream_index = -1;
                int i, streams;
                
                ///////////////  read AVI header  ////////////////
                val = read4( capture );
                hdr_len = read4( capture );
                
                capture->fps = (float)(1e6/read4(capture));
                read4( capture ); // bit-rate
                read4( capture ); // reserved
                read4( capture ); // flags
                capture->film_range.endIndex = read4( capture );
                read4( capture ); // initial frames
                streams = read4( capture ); // nstreams
                capture->buffer_size = read4( capture );
                skip( capture, hdr_len - 32 );

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?