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 + -
显示快捷键?