c++ - cv::VideoWriter being bipolar -
edit
i think understand happening here, not quite how. libavcoded shipped opencv 2.1 not align stack variables, per message displayed time use ffmpeg (message below). depending on how local variables in code positioned before call ffmpeg made, variables or not in locations libavcodec expects them be.
compiler did not align stack variables. libavcodec has been miscompiled , may slow or crash. not bug in libavcodec, in compiler. may try recompiling using gcc >= 4.2. not report crashes ffmpeg developers.
to able explain , understand how happening requires better understanding of x86 assembly possess. perhaps on in forum shed more light on situation?
here more succinct version of source code demonstrates issue:
#include <opencv/highgui.h> #include <iostream> int main(int argc, char* argv[]) { if (argc < 3) { return -1; } cv::videocapture cap(argv[1]); std::string str = argv[2]; int fourcc = cv_fourcc('j', 'p', 'e', 'g'); double fps = cap.get(cv_cap_prop_fps); int width = int(cap.get(cv_cap_prop_frame_width)); int height = int(cap.get(cv_cap_prop_frame_height)); // comment out block make program crash // code creates variable on stack , preforms // operations it. somehow alligns memory // call "cv::videowriter vw(...)" in way // libavcoded expects , makes call "vw << img" not crash. // note these variables never used outside of block. char * name_c = new char[100]; strcpy(name_c, str.c_str()); delete[] name_c; // end comment out block make program crash cv::videowriter vw( str, fourcc, fps, cv::size(width, height)); int fnum = 0; cv::mat img; while(cap.grab() && cap.retrieve(img) && fnum < 30) { cv::imshow("img", img); vw << img; ++fnum; } return 0; }
when block not commented out, calls video writer compile assembly:
cv::videowriter vw( str, fourcc, fps, cv::size(width, height)); 00401290 fld qword ptr [esp+50h] 00401294 add esp,4 00401297 push 1 00401299 sub esp,8 0040129c mov eax,esp 0040129e mov dword ptr [esp+60h],esp 004012a2 sub esp,8 004012a5 fstp qword ptr [esp] 004012a8 mov dword ptr [eax],edi 004012aa mov dword ptr [eax+4],ebp 004012ad push 6765706ah 004012b2 lea eax,[esp+0a8h] 004012b9 push eax 004012ba lea ecx,[esp+5ch] 004012be call cv::videowriter::videowriter (401454h) ... vw << img; 00401353 mov edx,dword ptr [esp+40h] 00401357 mov eax,dword ptr [edx+0ch] 0040135a lea ecx,[esp+20h] 0040135e push ecx 0040135f lea ecx,[esp+44h] 00401363 call eax 00401365 lea ecx,[esp+14h]
when block commented out, assembly this:
cv::videowriter vw( str, fourcc, fps, cv::size(width, height)); 00401253 fld qword ptr [esp+44h] 00401257 push 1 00401259 sub esp,8 0040125c mov ecx,esp 0040125e mov dword ptr [esp+58h],esp 00401262 sub esp,8 00401265 fstp qword ptr [esp] 00401268 mov dword ptr [ecx+4],eax 0040126b push 6765706ah 00401270 lea eax,[esp+0a0h] 00401277 mov dword ptr [ecx],edi 00401279 push eax 0040127a lea ecx,[esp+54h] 0040127e call cv::videowriter::videowriter (401454h) ... vw << img; 00401313 mov edx,dword ptr [esp+38h] 00401317 mov eax,dword ptr [edx+0ch] 0040131a lea ecx,[esp+18h] 0040131e push ecx 0040131f lea ecx,[esp+3ch] 00401323 call eax 00401325 lea ecx,[esp+0ch]
the main difference being in call cv::videowriter vw()
:
// working (with block) crashes (without block) 00401290 fld qword ptr [esp+50h] 00401253 fld qword ptr [esp+44h] *** 00401294 add esp,4 00401297 push 1 00401257 push 1 ... 004012a5 fstp qword ptr [esp] 00401265 fstp qword ptr [esp] *** 004012a8 mov dword ptr [eax],edi 00401268 mov dword ptr [ecx+4],eax *** 004012aa mov dword ptr [eax+4],ebp 0040126b push 6765706ah *** 004012ad push 6765706ah 00401270 lea eax,[esp+0a0h] 004012b2 lea eax,[esp+0a8h] 00401277 mov dword ptr [ecx],edi 004012b9 push eax 00401279 push eax
how change alignment of stack variables? why compiler generate different code same call in these 2 scenarios?
again, i'm running on windows xp using opencv 2.1 , visual studio 2008.
end edit
original
why simple little program crash written, work if uncomment block (and comment out save(…) statement)?
the problem occurs when try write vw - gets constructed fine, creates specified file in file system (it wouldn't if file name wasn't being passed in correctly), , crashes when try write first time vw << img
.
if in main function, however, output file opened, written to, , closed, should be.
#include <opencv/highgui.h> void save(const std::string & str, cv::videocapture & cap) { int fourcc = int(cap.get(cv_cap_prop_fourcc)); double fps = cap.get(cv_cap_prop_fps); int width = int(cap.get(cv_cap_prop_frame_width)); int height = int(cap.get(cv_cap_prop_frame_height)); cv::videowriter vw( str, fourcc, fps, cv::size(width, height)); int fnum = 0; cv::mat img; while(cap.grab() && cap.retrieve(img) && fnum < 30) { cv::imshow("img", img); cv::waitkey(1); vw << img; ++fnum; } } int main(int argc, char* argv[]) { if (argc < 3) { return -1; } cv::videocapture cap(argv[1]); std::string str = argv[2]; save(str, cap); /* int fourcc = int(cap.get(cv_cap_prop_fourcc)); double fps = cap.get(cv_cap_prop_fps); int width = int(cap.get(cv_cap_prop_frame_width)); int height = int(cap.get(cv_cap_prop_frame_height)); cv::videowriter vw( str, fourcc, fps, cv::size(width, height)); int fnum = 0; cv::mat img; while(cap.grab() && cap.retrieve(img) && fnum < 30) { cv::imshow("img", img); cv::waitkey(1); vw << img; ++fnum; } */ return 0; }
i'm running on windows xp using opencv 2.1 , visual studio 2008.
end original
Comments
Post a Comment