Go4Expert

Go4Expert (http://www.go4expert.com/)
-   MFC (http://www.go4expert.com/forums/mfc/)
-   -   Movie app using picture changes at 25 fps (http://www.go4expert.com/forums/movie-app-using-picture-changes-25-fps-t2596/)

Cuckoo 18Jan2007 00:05

Movie app using picture changes at 25 fps
 
i have build this engine which switches pictures on a Frame (in this case its a CDIalog) and i want it to be in a 25 fps rate.
for now all i can do is change pictures in the dialog but the timing is bad...
how can i be done?

here is my code:


Code:

BOOL MovieEngine::paintCurrFrame(BOOL onPaint)
{
        PAINTSTRUCT ps;       
        HDC hDC;
        hDC = ::BeginPaint(m_paintTarget->m_hWnd, &ps);
        HDC memDC = CreateCompatibleDC(hDC);
        m_jpegRect.bottom=m_offsetY+m_currFrame->GetHeight(); //m_currFrame is a cximage object
        m_jpegRect.right=m_offsetX+m_currFrame->GetWidth();
        m_paintTarget->GetClientRect(m_clientRect);
        HBITMAP hMemBmp = CreateCompatibleBitmap(hDC,  m_clientRect.Width(),  m_clientRect.Height());
        HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC, hMemBmp);
        FillRect(memDC,m_clientRect,(HBRUSH) (COLOR_WINDOW));
        if(m_playing)
                m_currFrame->Draw(memDC,m_jpegRect);
        BitBlt(hDC, 0, 0, m_clientRect.Width(), m_clientRect.Height(), memDC, 0, 0, SRCCOPY);
        SelectObject(memDC, hOldBmp);
        ::EndPaint(m_paintTarget->m_hWnd, &ps);
        DeleteObject(hMemBmp);
        if(!onPaint){
                m_paintTarget->InvalidateRect(m_jpegRect);
                m_paintTarget->RedrawWindow(m_jpegRect);
        }
        return TRUE;
}

this is the engine itself as a thread:

Code:

UINT MovieEngine::playThread(LPVOID engine)
{
        MovieEngine* thisEngine=(MovieEngine*)engine;
        if(thisEngine->m_buffComplete){
                while (thisEngine->m_movieBuff.size()>0)//m_movieBuff is a vector of pointers to cximages (hance the movie).
                {
                        thisEngine->m_currFrame=thisEngine->m_movieBuff.front();
                        thisEngine->m_movieBuff.pop();
                        thisEngine->paintCurrFrame(FALSE); //function above
                        delete thisEngine->m_currFrame;
                        Sleep(40);// 40 milisec is the time needed to get 25 fps rate but all the picture switching takes time, so i need 40-switch_time...
                }
        }
        return 0;
}

ofcourse there is a loading thread (to keep buffer full untill the movie ends) while playing but it is irelevant for now.
i hope the code is clear, couse i am new to mfc and visual at all.
i managed to make it play but nothing deterministic. sometimes it plays faster than 25 fps sometimes slower.... i donno what to do :(
Second year SE student.

Cuckoo 18Jan2007 00:09

Re: Movie app using picture changes at 25 fps
 
ps. i want the engine to be outside the dialog. is there a better way of doing it? perhaps should i put the painting part in the dialog OnPanint func?

ever_thus 20Feb2007 00:35

Re: Movie app using picture changes at 25 fps
 
Sorry if I haven't read all your code, so my answer might be a bit off.

It appears that the answer to your first question is that Sleep is the wrong way to go. All sleep does is wait for 40 ms. You might wait even longer while the systems multitasks to other programs. Alternatively the system might be very unbusy, run all your other code faster and make your fps higher (although 25 should still be the max).

The solution is to use check how much time has passed since the last frame was shown. Since the check is in the same place always the amount of time that the picture switching takes won't be a factor.

Here's the code:
Code:

static DWORD time = 0;
while (thisEngine->m_movieBuff.size()>0)
{
        if (GetTickCount () - time - 40){
        time = GetTickCount ();
        //all your code
}

It's a busy wait, as opposed to Sleep which allows the system to do other things, but your program isn't consuming much resources in the meantime, so that shouldn't matter. If you're concerened you can stick in Sleep (0). This tells the system: check if something else needs doing, if not come back to my program.

Hope this helps.

ever_thus 20Feb2007 00:38

Re: Movie app using picture changes at 25 fps
 
The code wasn't well formatted. Here it is again:
Code:

static DWORD time = 0;
while (thisEngine->m_movieBuff.size()>0)
{
        if (GetTickCount () - time - 40){
                time = GetTickCount ();
                //all your code
        }
}


ever_thus 21Feb2007 00:29

Re: Movie app using picture changes at 25 fps
 
OK. I've got more time now, so I read your code. My naswer is still correct, but the code I posted isn't. Here's the latest (promise!!) version.

(Moderators: If I'm breaking any rules with all this reposting just let me know and I won't do it again.)

Code:

static DWORD time = GetTickCount ();
while (thisEngine->m_movieBuff.size()>0){
while (GetTickCount () - time < 40){
Sleep (0);
}
time = GetTickCount ();
//all your code
}


Cuckoo 4Apr2007 07:11

Re: Movie app using picture changes at 25 fps
 
Quote:

Originally Posted by ever_thus
OK. I've got more time now, so I read your code. My naswer is still correct, but the code I posted isn't. Here's the latest (promise!!) version.

(Moderators: If I'm breaking any rules with all this reposting just let me know and I won't do it again.)

Code:

static DWORD time = GetTickCount ();
while (thisEngine->m_movieBuff.size()>0){
while (GetTickCount () - time < 40){
Sleep (0);
}
time = GetTickCount ();
//all your code
}


realy realy thanks, i dont know y didnt i think of busy-wait before.... i guess in my studies i somehow learned that busy-wait is bad thing... but in this case there is no other option isnt it?

ever_thus 13Apr2007 01:20

Re: Movie app using picture changes at 25 fps
 
Well, as I said, by calling Sleep (0) you can avoid the ill-effect of a busy wait, while still maintaining control of your timing by using GetTickCount ().


All times are GMT +5.5. The time now is 22:22.