OpenCV VideoCapture 在大视频尺寸上崩溃
OpenCV VideoCapture Crashes on Large Video Size
我正在尝试读取大小为 2448x2050 的原始 avi 视频。每次我尝试读取一个帧时,程序都会因段错误而崩溃。同一程序适用于较小尺寸的视频。
这是一个示例程序:
#include <iostream>
#include <opencv2/opencv.hpp>
int main( int argc, char** argv )
{
cv::VideoCapture cap(argv[1]);
if(!cap.isOpened())
return -1;
cv::Mat frames;
cv::namedWindow("Window", CV_WINDOW_NORMAL);
for(;;)
{
// error here
cap >> frames;
// ........
cv::imshow("Window", frames);
cv::waitKey(33);
}
return 0;
}
这是 valgrind 的输出:
==30166== Invalid read of size 1
==30166== at 0x9ECD550: sws_convertPalette8ToPacked24 (in /usr/lib/x86_64-linux-gnu/libswscale.so.2.1.1)
==30166== by 0x9ED13AA: ??? (in /usr/lib/x86_64-linux-gnu/libswscale.so.2.1.1)
==30166== by 0x9ED385A: sws_scale (in /usr/lib/x86_64-linux-gnu/libswscale.so.2.1.1)
==30166== by 0x4E5066D: CvCapture_FFMPEG::retrieveFrame(int, unsigned char**, int*, int*, int*, int*) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E5071A: cvRetrieveFrame_FFMPEG (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4FB88: CvCapture_FFMPEG_proxy::retrieveFrame(int) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E4BA: cv::VideoCapture::retrieve(cv::Mat&, int) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E2A6: cv::VideoCapture::read(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E209: cv::VideoCapture::operator>>(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x401330: main (in /home/rumman/temp/Video)
==30166== Address 0x18897a10 is 5,015,952 bytes inside a block of size 5,018,408 free'd
==30166== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30166== by 0x8CD0113: av_destruct_packet (in /usr/lib/x86_64-linux-gnu/libavcodec.so.54.35.0)
==30166== by 0x8CD04B3: av_free_packet (in /usr/lib/x86_64-linux-gnu/libavcodec.so.54.35.0)
==30166== by 0x4E50BB8: CvCapture_FFMPEG::grabFrame() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E50C38: cvGrabFrame_FFMPEG (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4F934: CvCapture_FFMPEG_proxy::grabFrame() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E450: cvGrabFrame (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E46C: cv::VideoCapture::grab() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E241: cv::VideoCapture::read(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E209: cv::VideoCapture::operator>>(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x401330: main (in /home/rumman/temp/Video)
原来这个问题只发生在使用原始视频时,与视频分辨率无关。
我正在尝试读取大小为 2448x2050 的原始 avi 视频。每次我尝试读取一个帧时,程序都会因段错误而崩溃。同一程序适用于较小尺寸的视频。
这是一个示例程序:
#include <iostream>
#include <opencv2/opencv.hpp>
int main( int argc, char** argv )
{
cv::VideoCapture cap(argv[1]);
if(!cap.isOpened())
return -1;
cv::Mat frames;
cv::namedWindow("Window", CV_WINDOW_NORMAL);
for(;;)
{
// error here
cap >> frames;
// ........
cv::imshow("Window", frames);
cv::waitKey(33);
}
return 0;
}
这是 valgrind 的输出:
==30166== Invalid read of size 1
==30166== at 0x9ECD550: sws_convertPalette8ToPacked24 (in /usr/lib/x86_64-linux-gnu/libswscale.so.2.1.1)
==30166== by 0x9ED13AA: ??? (in /usr/lib/x86_64-linux-gnu/libswscale.so.2.1.1)
==30166== by 0x9ED385A: sws_scale (in /usr/lib/x86_64-linux-gnu/libswscale.so.2.1.1)
==30166== by 0x4E5066D: CvCapture_FFMPEG::retrieveFrame(int, unsigned char**, int*, int*, int*, int*) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E5071A: cvRetrieveFrame_FFMPEG (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4FB88: CvCapture_FFMPEG_proxy::retrieveFrame(int) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E4BA: cv::VideoCapture::retrieve(cv::Mat&, int) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E2A6: cv::VideoCapture::read(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E209: cv::VideoCapture::operator>>(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x401330: main (in /home/rumman/temp/Video)
==30166== Address 0x18897a10 is 5,015,952 bytes inside a block of size 5,018,408 free'd
==30166== at 0x4C2BDEC: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30166== by 0x8CD0113: av_destruct_packet (in /usr/lib/x86_64-linux-gnu/libavcodec.so.54.35.0)
==30166== by 0x8CD04B3: av_free_packet (in /usr/lib/x86_64-linux-gnu/libavcodec.so.54.35.0)
==30166== by 0x4E50BB8: CvCapture_FFMPEG::grabFrame() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E50C38: cvGrabFrame_FFMPEG (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4F934: CvCapture_FFMPEG_proxy::grabFrame() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E450: cvGrabFrame (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E46C: cv::VideoCapture::grab() (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E241: cv::VideoCapture::read(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x4E4E209: cv::VideoCapture::operator>>(cv::Mat&) (in /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4.8)
==30166== by 0x401330: main (in /home/rumman/temp/Video)
原来这个问题只发生在使用原始视频时,与视频分辨率无关。