cvcap.cpp.svn-base

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

SVN-BASE
1,486
字号

                for( i = 0; i < streams; i++ )
                {
                    /////////////// Streams' information ////////////////
                    if( read4(capture) != fourcc('L','I','S','T'))
                        goto exit_func;

                    list_len = read4(capture) - 4;
                    if( read4(capture) != fourcc('s','t','r','l'))
                        goto exit_func;

                    while( list_len > 0 )
                    {
                        val = read4(capture);
                        hdr_len = read4(capture);
                        list_len -= hdr_len + 8;

                        switch( val )
                        {
                        case fourcc('s','t','r','h'):
                            stream_index++;
                            val = read4(capture);
                            hdr_len -= 4;
                            if( val == fourcc('v','i','d','s') && capture->stream_index < 0 )
                            {
                                capture->stream_index = stream_index;
                                capture->codec_fourcc = read4( capture );
                                hdr_len -= 4;
                            }
                            break;
                        case fourcc('s','t','r','f'):
                            if( capture->stream_index == stream_index )
                            {
                                read4(capture); // header size
                                capture->frame_size.width = read4(capture);
                                capture->frame_size.height = read4(capture);
                                read4(capture); // planes & bit count
                                capture->codec_sub_fourcc = read4(capture);
                                hdr_len -= 20;
                            }
                            break;
                        }

                        skip( capture, hdr_len );
                    }
                }
            }
            break;
            }
        }
        else if( val == fourcc('i','d','x','1'))
        {
            int i, k = 0, size = (int)(new_offset - capture->offset);
            int fourcc1 = fourcc( '0', (capture->stream_index + '0'), 'd', 'b' );
            int fourcc2 = fourcc( '0', (capture->stream_index + '0'), 'd', 'c' );

            avi_entry* entries = (avi_entry*)cvAlloc( size );
            fread( entries, 1, size, capture->file );
            capture->offset = new_offset;
            size /= sizeof(entries[0]);

            capture->entries = (avi_entry_compact*)cvAlloc( capture->film_range.endIndex*
                                                            sizeof(capture->entries[0]) );
            for( i = 0; i < size; i++ )
            {
                if( entries[i].id == fourcc1 || entries[i].id == fourcc2 )
                {
                    int flags = entries[i].flags & 16;
                    int offset = entries[i].offset;
                    capture->entries[k].flags = flags;
                    capture->entries[k].offset = offset;
                    k++;
                }
            }
            cvFree( (void**)&entries );
        }
  
        skip( capture, (long)(new_offset - capture->offset) );
    }

    if( capture->codec_fourcc && capture->data_offset )
    {
        int fcc = capture->codec_sub_fourcc;
        CodecID id = fcc == fourcc('U','2','6','3') ? CODEC_ID_H263 :
                     fcc == fourcc('I','2','6','3') ? CODEC_ID_H263I :
                     fcc == fourcc('D', 'I', 'V', '3') ? CODEC_ID_MSMPEG4V3 :
                     fcc == fourcc('D', 'I', 'V', 'X') ? CODEC_ID_MPEG4 :
                     fcc == fourcc('D', 'X', '5', '0') ? CODEC_ID_MPEG4 :
                     fcc == fourcc('M', 'P', '4', '2') ? CODEC_ID_MSMPEG4V2 :
                     fcc == fourcc('M', 'J', 'P', 'G') ? CODEC_ID_MJPEG :
                     fcc == fourcc('P', 'I', 'M', '1') ? CODEC_ID_MPEG1VIDEO :
                     fcc == 0x50 ? CODEC_ID_MP2 :
                     fcc == 0x55 ? CODEC_ID_MP2 : CODEC_ID_NONE;

        capture->codec = avcodec_find_decoder( id );

        if( capture->codec )
        {
            capture->avctx = avcodec_alloc_context();
            capture->avctx->width = capture->frame_size.width;
            capture->avctx->height = capture->frame_size.height;
            capture->avctx->codec_tag = capture->codec_sub_fourcc;
            capture->avctx->codec_type = CODEC_TYPE_VIDEO;
            capture->avctx->codec_id = id;
            
            err = avcodec_open( capture->avctx, capture->codec );
            if( err >= 0 )
            {
                capture->rgb_picture.data[0] = (uchar*)cvAlloc(
                                avpicture_get_size( PIX_FMT_RGB24,
                                capture->avctx->width, capture->avctx->height ));
                avpicture_fill( (AVPicture*)&capture->rgb_picture, capture->rgb_picture.data[0],
                                PIX_FMT_RGB24, capture->avctx->width, capture->avctx->height );

                cvInitImageHeader( &capture->frame, cvSize( capture->avctx->width,
                                   capture->avctx->height ), 8, 3, 0, 4 );
                cvSetData( &capture->frame, capture->rgb_picture.data[0],
                           capture->rgb_picture.linesize[0] );

                capture->picture = avcodec_alloc_frame();
                capture->pos = 0;
                capture->fps = capture->avctx->frame_rate*1e-4;
                fseek( capture->file, (long)capture->data_offset, SEEK_SET );
                capture->offset = capture->data_offset;
                valid = 1;
                avcodec_flush_buffers( capture->avctx );
            }
        }
    }

exit_func:

    if( !valid )
        icvCloseAVI_FFMPEG( capture );

    return valid;
}


static int icvGrabFrameAVI_FFMPEG( CvCaptureAVI_FFMPEG* capture )
{
    if( capture && capture->avctx )
    {
        for(;;)
        {
            int val = read4( capture );
            if( val == -1 )
                return 0;

            if( isdigit((char)val) && isdigit((char)(val>>8)) &&
                ((char)(val>>16) == 'd' || (char)(val>>16) == 'w') &&
                ((char)(val>>24) == 'b' || (char)(val>>24) == 'c'))
            {
                int stream_index = ((char)(val>>8) - '0') + ((char)val - '0')*10;
                int size0 = read4( capture );
				int size = (size0 + 1) & -2;

                if( stream_index == capture->stream_index )
                {
                    int got_picture = 0, ret;

                    if( !capture->buffer || capture->buffer_size < size )
                    {
                        cvFree( (void**)&capture->buffer );
                        if( capture->buffer_size < size )
                            capture->buffer_size = size;
                        capture->buffer = (char*)cvAlloc( capture->buffer_size );
                    }
                    fread( capture->buffer, 1, size, capture->file );
                    capture->offset += size;

                    ret = avcodec_decode_video( capture->avctx, capture->picture,
                                                &got_picture, (uchar*)capture->buffer, size0 );
                    
                    if( ret >= 0 && got_picture )
                    {
                        capture->pos++;
                        return 1;
                    }
                    return 0;
                }
                else
                    skip( capture, size );
            }
        }
    }

    return 0;
}


static const IplImage* icvRetrieveFrameAVI_FFMPEG( CvCaptureAVI_FFMPEG* capture )
{
    if( capture && capture->avctx )
    {
        img_convert( &capture->rgb_picture, PIX_FMT_RGB24,
                     (AVPicture*)capture->picture, capture->avctx->pix_fmt,
                     capture->avctx->width, capture->avctx->height );
        cvCvtColor( &capture->frame, &capture->frame, CV_RGB2BGR );
        return &capture->frame;
    }

    return 0;
}


static double icvGetPropertyAVI_FFMPEG( CvCaptureAVI_FFMPEG* capture, int property_id )
{
    switch( property_id )
    {
    case CV_CAP_PROP_POS_MSEC:
        return cvRound(capture->pos*1000./capture->fps);
        break;
    case CV_CAP_PROP_POS_FRAMES:
        return capture->pos;
    case CV_CAP_PROP_POS_AVI_RATIO:
        return ((double)capture->offset)/((double)capture->file_size);
    case CV_CAP_PROP_FRAME_WIDTH:
        return capture->frame.width;
    case CV_CAP_PROP_FRAME_HEIGHT:
        return capture->frame.height;
    case CV_CAP_PROP_FPS:
        return capture->fps;
    case CV_CAP_PROP_FOURCC:
        return capture->codec_sub_fourcc;
    }
    return 0;
}


static int icvSetPropertyAVI_FFMPEG( CvCaptureAVI_FFMPEG* capture,
                                     int property_id, double value )
{
    switch( property_id )
    {
    case CV_CAP_PROP_POS_MSEC:
    case CV_CAP_PROP_POS_FRAMES:
    case CV_CAP_PROP_POS_AVI_RATIO:
        if( capture->entries )
        {
            int pos;
            switch( property_id )
            {
            case CV_CAP_PROP_POS_MSEC:
                pos = cvRound(value*capture->fps*0.001);
                break;
            case CV_CAP_PROP_POS_AVI_RATIO:
                pos = cvRound(value*(capture->film_range.endIndex - 
                                     capture->film_range.startIndex) +
                              capture->film_range.startIndex);
                break;
            default:
                pos = cvRound(value);
            }
            pos -= 10; // to make sure the frame is updated properly
            if( pos < capture->film_range.startIndex )
                pos = capture->film_range.startIndex;
            if( pos > capture->film_range.endIndex )
                pos = capture->film_range.endIndex;
            for( ; pos > 0; pos-- )
                if( capture->entries[pos].flags & 16 )
                    break;
            capture->pos = pos;
            capture->offset = capture->entries[pos].offset + capture->data_offset;
            fseek( capture->file, (long)capture->offset, SEEK_SET );
			avcodec_flush_buffers( capture->avctx );
        }
        break;
    default:
        return 0;
    }

    return 1;
}

static CvCaptureVTable captureAVI_FFMPEG_vtable = 
{
    6,
    (CvCaptureCloseFunc)icvCloseAVI_FFMPEG,
    (CvCaptureGrabFrameFunc)icvGrabFrameAVI_FFMPEG,
    (CvCaptureRetrieveFrameFunc)icvRetrieveFrameAVI_FFMPEG,
    (CvCaptureGetPropertyFunc)icvGetPropertyAVI_FFMPEG,
    (CvCaptureSetPropertyFunc)icvSetPropertyAVI_FFMPEG,
    (CvCaptureGetDescriptionFunc)0
};

HIGHGUI_IMPL CvCapture* cvCaptureFromAVI( const char* filename )
{
    CvCaptureAVI_FFMPEG* capture = (CvCaptureAVI_FFMPEG*)cvAlloc( sizeof(*capture));
    memset( capture, 0, sizeof(*capture));

    capture->vtable = &captureAVI_FFMPEG_vtable;

    if( !icvOpenAVI_FFMPEG( capture, filename ))
        cvReleaseCapture( (CvCapture**)&capture );

    return (CvCapture*)capture;
}

#else

HIGHGUI_IMPL CvCapture* cvCaptureFromAVI( const char* filename )
{
    return 0;
}

#endif

HIGHGUI_IMPL CvCapture* cvCaptureFromCAM( int /*index*/ )
{
    return 0;
}


HIGHGUI_IMPL CvAVIWriter* cvCreateAVIWriter( const char* /*filename*/, int /*fourcc*/,
                                             double /*fps*/, CvSize /*frameSize*/ )
{
    return 0;
}


HIGHGUI_IMPL int cvWriteToAVI( CvAVIWriter* /*writer*/, const IplImage* /*image*/ )
{
    return 0;
}


HIGHGUI_IMPL void cvReleaseAVIWriter( CvAVIWriter** /*writer*/ )
{
}


#endif


#if 0
int main( int argc, char** argv )
{
    CvCapture* capture;

    if( argc != 2 )
    {
        printf("Usage: %s <avifile>\n", argv[0] );
        return 0;
    }

    cvvNamedWindow( "window", 1 );
    capture = cvCaptureFromAVI( argv[1] );

    if( capture )
    {
        for( ;; )
        {
            IplImage* frame = cvQueryFrame( capture );
            if( frame )
                cvvShowImage( "window", frame );
            else
                break;
            int ch = cvvWaitKeyEx( 0, 10 );
            if( ch == '\x1b' )
                break;
        }

        cvReleaseCapture( &capture );
    }

    return 1;
}
#endif

⌨️ 快捷键说明

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