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

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -