Author Topic: Movie file playing code in FS2!  (Read 6875 times)

0 Members and 1 Guest are viewing this topic.

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
Quote
Originally posted by Inquisitor
we'll probably have to put some conditionals in there to preserve the (currently stalled) linux build.


Well yes, thats easy enough

Quote
Originally posted by Inquisitor
then lets go ahead and get it into CVS.


I thought I might try and get it fully working first.
Also its not coded into fs2_open as such its in my own source code project . So I'd need to transfer it across.

But first I need to defrag my harddisc. Its 20% fragmented and its slowing everything down. Does anyone know of a good defragger for XP? I tryed to install Norton but all the scarey messages put me off.

 
Movie file playing code in FS2!
Maybe post a copy of your code to this thread?

EDIT:
On binding to another window:
The trick to it is to set the new window you create to be a child window of the FS2 window.

Assume pVW is a pointer to the video window and hWnd is the window handle of the main FS2 window in the below example:
Code: [Select]

// Set video windows owner (i.e. who is the parent window?)
pVW->put_Owner((OAHWND)hWnd);

// Get the size of the Parent window
RECT vwrect;
GetClientRect(hWnd, &vwrect);

// Set the child to this exact position
// This appears to be done relative to the parent
pVW->SetWindowPosition(0,0, vwrect.right, vwrect.bottom);



This code should work well since the FS2_window doesn't need to dynamically resize itself and such.

EDIT 2:
And a final note, I made a very simple app a while ago with directshow and it plays avi's encoded with DivX perfectly provided you have the codec installed. Just add in some error checking in building the filter graph and such to avoid bad crashes.
« Last Edit: August 16, 2002, 08:39:51 am by 383 »

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
Cool, that looks quite promising. I'll give it a shot and then post the code.

How 'bad' is a 'bad crash'?

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
Quote
Originally posted by ##UnknownPlayer##
Assume pVW is a pointer to the video window and hWnd is the window handle of the main FS2 window in the below example:
Code: [Select]

// Set video windows owner (i.e. who is the parent window?)
pVW->put_Owner((OAHWND)hWnd);

[/B]


That was already there   

Quote
Originally posted by ##UnknownPlayer##

Code: [Select]

// Get the size of the Parent window
RECT vwrect;
GetClientRect(hWnd, &vwrect);

// Set the child to this exact position
// This appears to be done relative to the parent
pVW->SetWindowPosition(0,0, vwrect.right, vwrect.bottom);

[/B]


That didnt seem to have any effect

OK, here comes the code (sorry about the mess)

Code: [Select]

#include
#include

#include "osapi.h"

#include "dx8show.h"

//
// Constants
//
#define KEYBOARD_SAMPLE_FREQ  1000  // Sample user input on an interval

//
// Globals
//
static IGraphBuilder  *pGB = NULL;
static IMediaControl  *pMC = NULL;
static IVideoWindow   *pVW = NULL;
static IMediaEvent    *pME = NULL;

static BOOL g_bContinue = TRUE;
static BOOL g_bUserInterruptedPlayback = FALSE;

//
// Function prototypes
//
static HRESULT PlayMedia(LPTSTR movie_filename);
static HRESULT GetInterfaces(void);
static HRESULT SetFullscreen(void);
static void CleanupInterfaces(void);
static void Msg(TCHAR *szFormat, ...);

//
// Helper Macros (Jump-If-Failed, Log-If-Failed)
//
#define RELEASE(i) {if (i) i->Release(); i = NULL;}

#define JIF(x) if (FAILED(hr=(x))) \
    {Msg(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); goto CLEANUP;}

#define LIF(x) if (FAILED(hr=(x))) \
    {Msg(TEXT("FAILED(hr=0x%x) in ") TEXT(#x) TEXT("\n"), hr); return hr;}

bool dx8show_stop_cutscene()
{
pMC->Stop();
return true;
}

bool dx8show_play_cutscene(char *szMovie)
{
    HRESULT hr;

    // Initialize COM
    if (FAILED(hr = CoInitialize(NULL)))
{
        return false;
}

    // Get DirectShow interfaces
    if (FAILED(hr = GetInterfaces()))
    {
        CoUninitialize();
        return false;
    }

pVW->put_Owner((OAHWND) os_get_window());

    // Play the movie / cutscene
    hr = PlayMedia(szMovie);
   
// If the user interrupted playback and there was no other error,
bool result = true;

    if ((hr == S_OK) && g_bUserInterruptedPlayback)
{
        result = false;
}

pVW->put_Owner(NULL);

    // Release DirectShow interfaces
    CleanupInterfaces();
    CoUninitialize();

    return result;
}

HRESULT GetInterfaces(void)
{
    HRESULT hr = S_OK;

    // Instantiate filter graph interface
    JIF(CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,
                         IID_IGraphBuilder, (void **)&pGB));

    // Get interfaces to control playback & screensize
    JIF(pGB->QueryInterface(IID_IMediaControl,  (void **)&pMC));
    JIF(pGB->QueryInterface(IID_IVideoWindow,   (void **)&pVW));

    // Get interface to allow the app to wait for completion of playback
    JIF(pGB->QueryInterface(IID_IMediaEventEx,  (void **)&pME));

    return S_OK;

    // In case of failure, the helper macro jumps here
CLEANUP:
    CleanupInterfaces();
    return(hr);
}


void CleanupInterfaces(void)
{
    // Release the DirectShow interfaces
    RELEASE(pGB);
    RELEASE(pMC);
    RELEASE(pVW);
    RELEASE(pME);
}

HRESULT PlayMedia(LPTSTR movie_filename)
{
    HRESULT hr = S_OK;
    WCHAR wFileName[MAX_PATH];
    BOOL bSleep=TRUE;

#ifndef UNICODE
    MultiByteToWideChar(CP_ACP, 0, movie_filename, -1, wFileName, MAX_PATH);
#else
    lstrcpy(wFile, szFile);
#endif

    // Allow DirectShow to create the FilterGraph for this media file
    hr = pGB->RenderFile(wFileName, NULL);

    if (FAILED(hr)) {
        Msg(TEXT("Failed(0x%08lx) in RenderFile(%s)!\r\n"), hr, movie_filename);
        return hr;
    }

    // Set the message drain of the video window to point to our hidden
    // application window.  This allows keyboard input to be transferred
    // to our main window for processing.
    //
    // If this is an audio-only or MIDI file, then put_MessageDrain will fail.
    //
    hr = pVW->put_MessageDrain((OAHWND) os_get_window());

    if (FAILED(hr))
    {
        Msg(TEXT("Failed(0x%08lx) to set message drain for %s.\r\n\r\n"
                 "This sample is designed to play videos, but the file selected "
                 "has no video component."), hr, movie_filename);
        return hr;
    }


    // Set fullscreen
    hr = SetFullscreen();

MSG msg;

/*
while(PeekMessage(&msg, (HWND) os_get_window(), 0, 0, PM_REMOVE))
{
  TranslateMessage(&msg);
DispatchMessage(&msg);
}
*/

    if (FAILED(hr)) {
        Msg(TEXT("Failed(%08lx) to set fullscreen!\r\n"), hr);
        return hr;
    }

    // Display first frame of the movie
    hr = pMC->Pause();

    if (FAILED(hr)) {
        Msg(TEXT("Failed(%08lx) in Pause()!\r\n"), hr);
        return hr;
    }

    // Start playback
    hr = pMC->Run();

    if (FAILED(hr)) {
        Msg(TEXT("Failed(%08lx) in Run()!\r\n"), hr);
        return hr;
    }

    // Update state variables
    g_bContinue = TRUE;

    // Enter a loop of checking for events and sampling keyboard input
    while (g_bContinue)
    {
        LONGLONG pos=0;
        long lEventCode, lParam1, lParam2;

        // Reset sleep flag
        bSleep = TRUE;

        // Has there been a media event?  Look for end of stream condition.
        if(E_ABORT != pME->GetEvent(&lEventCode, &lParam1, &lParam2, 0))
        {
            // Free the media event resources.
            hr = pME->FreeEventParams(lEventCode, lParam1, lParam2);
            if (FAILED(hr))
            {
                Msg(TEXT("Failed(%08lx) to free event params (%s)!\r\n"),
                    hr, movie_filename);
            }

            // Is this the end of the movie?
            if (lEventCode == EC_COMPLETE)
            {
                g_bContinue = FALSE;
                bSleep = FALSE;
            }
        }

        // Give system threads time to run (and don't sample user input madly)
        if (bSleep)
{
            Sleep(KEYBOARD_SAMPLE_FREQ);
}

// Quits movie if escape, space or return is pressed
while(PeekMessage(&msg, (HWND) os_get_window(), 0, 0, PM_REMOVE))
{
  TranslateMessage(&msg);

if(msg.message != WM_KEYDOWN)
{
continue;
}

switch(msg.wParam )
{
case VK_ESCAPE:
   case VK_SPACE:
   case VK_RETURN:
{
g_bUserInterruptedPlayback = TRUE;
       dx8show_stop_cutscene();
       return S_OK;
   }
}
  }
    }

    return hr;
}


HRESULT SetFullscreen(void)
{
    HRESULT hr=S_OK;
    LONG lMode;
    static HWND hDrain=0;

    if (!pVW)
        return S_FALSE;

    // Read current state
    LIF(pVW->get_FullScreenMode(&lMode));

    if (lMode == OAFALSE)
    {
        // Save current message drain
        LIF(pVW->get_MessageDrain((OAHWND *) &hDrain));

        // Set message drain to application main window
        LIF(pVW->put_MessageDrain((OAHWND) os_get_window()));
 
        // Switch to full-screen mode
        lMode = OATRUE;
        LIF(pVW->put_FullScreenMode(lMode));
    }

    return hr;
}


void Msg(TCHAR *szFormat, ...)
{
    TCHAR szBuffer[512];  // Large buffer for very long filenames (like with HTTP)

    va_list pArgs;
    va_start(pArgs, szFormat);
    vsprintf(szBuffer, szFormat, pArgs);
    va_end(pArgs);

    // This sample uses a simple message box to convey warning and error
    // messages.   You may want to display a debug string or suppress messages
    // altogether, depending on your application.
  //  MessageBox(NULL, szBuffer, "PlayCutscene Error", MB_OK);
}


 
Movie file playing code in FS2!
You should perhaps use GetClientRect in place of the Fullscreen functions to make fullscreen work (because it'll also then size down to a window). This stuff will only have an effect if you can grab the window handle of the Freespace window (which Im not entirely sure if it's totally global or not since FS2 = multithreaded)

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
Uknown: If I remove the fullscreen code it simply doesnt go fullscreen at all.

I just tryed plugging the above code into a D3D8 sample.
When the movie was started from the app windowed the movie fills the screen. When the movie was started from the app in fullscreen the movie did not fill the screen but it didnt do any crazy switching either though.

Any thoughts?

 
Movie file playing code in FS2!
Do you think you could put this into the CVS with a specialized build option so I could have a play around with it?

As far as I know it should work with that method since I've got a demo app which does exactly that.

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
OK, I think thats an idea since I've run out of ideas to fix my problems. Its got something to do with the type of window.

I will probably need someone to sort out the make file for me.

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
I've just had a big breakthough, its not perfect now but acceptable. Still a bit of a switching problem but everything else works. Turns out I had to deactivate direct3D to allow it to play properly.

What I need now is:

1. fs2_open admin to get me write access to cvs again.
Apparently I dont have it any more!

2. Could my testers please check their e-mail.

3. Someone from the modding community or any developers to talk to me about how we are going to make the new video code work for the modders.

 

Offline Inquisitor

Movie file playing code in FS2!
Ahh, lemme check, somehow the writers file is getting over wrote :)
No signature.

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
Thanks Inquisitor but I was just being stupid thats all.

OK, I have committed my changes. To activate my changes use the new tag '-dshowvid'. This will allow FS2 to pick up videos of the (exact including mve extension) same name as on the CD but in your root freespace 2 dir. It will play MPG, AVI and DIVX and in theory anything else that you have a codec for (ie anything that can play through media player).

It cannot play mve files.

The catch? It has to switch out to video window and back in which is a bit messy. So if you are a coder take a look, perhaps you can fix it!

I dont understand make files so thats probably broken, sorry.

Anyone have any problems feel free to contact me.

 

Offline Kazan

  • PCS2 Wizard
  • 212
  • Soul lives in the Mountains
    • http://alliance.sourceforge.net
Movie file playing code in FS2!
nice code

too bad it's completely useless for unix
PCS2 2.0.3 | POF CS2 wiki page | Important PCS2 Threads | PCS2 Mantis

"The Mountains are calling, and I must go" - John Muir

 

Offline Inquisitor

Movie file playing code in FS2!
That's what the defines are for, till we get someone to pony up for the divx player on Unix.

Unix has other problems first though ;)
No signature.

 

Offline Kazan

  • PCS2 Wizard
  • 212
  • Soul lives in the Mountains
    • http://alliance.sourceforge.net
Movie file playing code in FS2!
like fs2_open linux working :P
PCS2 2.0.3 | POF CS2 wiki page | Important PCS2 Threads | PCS2 Mantis

"The Mountains are calling, and I must go" - John Muir

 

Offline Inquisitor

Movie file playing code in FS2!
Yup :)
No signature.

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
I could really do with some testers, people. See MOD forum for full details.

 

Offline tomcat

  • Dark Lord of Truespace
  • 28
Movie file playing code in FS2!
what divx  player for linux? I just saw a  B5 ACTA -Divx in linux
mplayer is name of the game :D
Truespace is the path of the Dark Side
-----------------------------------------------
Dark Truespace Master Tomcat

 

Offline Kazan

  • PCS2 Wizard
  • 212
  • Soul lives in the Mountains
    • http://alliance.sourceforge.net
Movie file playing code in FS2!
xine is better than mplayer
PCS2 2.0.3 | POF CS2 wiki page | Important PCS2 Threads | PCS2 Mantis

"The Mountains are calling, and I must go" - John Muir

 

Offline Zarax

  • 210
Movie file playing code in FS2!
Goody Good!!!!
Put it in FS2 OPEN!!!!!
It's the best way, you wouldn't have to be tied to a damned codec!!!!
And, if linux release has problems, then it will use another version or no video at all!!!!
For Windows there can be no other way...
Finally i will bring some DVD quality movies on FS2...
Sorry for the half flaming, but if Windows Media can be used, we will have superior quality with smaller size...
Could be a good way even for in-game audio...
Real CD quality a 192kbs...
The Best is Yet to Come

 

Offline RandomTiger

  • Senior Member
  • 211
Movie file playing code in FS2!
WM_ACTIVATEAPP, WM_ACTIVATEAPP, WM_ACTIVATEAPP, messing with my code!