DirectX 9 Audio/Video Playback object memory question

-Strict-

Freshman
Joined
Jan 18, 2003
Messages
32
I've got an app that imports the DirectX 9's Microsoft.DirectX.AudioVideoPlayback namespace for access to the Audio and Video objects. I have 2 private fields, AP, and VP (for audio and video playback). When i start playback of a new file I would have to create a new playback object for that flie, so I would just set the old AP/VP field = nothing and then set it to a new a/v object. I noticed that as the files played and went to the next track the memory usage of my app would forever increase with each passing track. Looking into matters i decieded to put a .Dispose on the previous reference right before setting a new one.

And this worked fine if i keep sending this class a new filename via Play(Filename) I can go all day giving it songs to play, but for some unknown reason if I let it trigger the end of song event and let it progress to the next song on its own, I get an error, but while the error shows, the next song continues to play perfectly until i end debugging.

Error:
Code:
An unhandled exception of type 'System.NullReferenceException' occurred in microsoft.directx.audiovideoplayback.dll

Additional information: Object reference not set to an instance of an object.

And it breaks on a line in which i guess is in the actual AP or VP object.

Disassembly:
Code:
 0000012a mov      eax,dword ptr [eax+20h]


Heres a snippet of how my code works...

Code:
Imports Microsoft.DirectX.AudioVideoPlayback

  ....

    Private WithEvents VP As Video
    Private WithEvents AP As Audio          
  
  ....
 
    'Play Control
    Public Sub Play() Implements IMediaDevice.Play
        Trace.WriteLine("Playing Current")
        Me.tmrPosition.Enabled = True
        Try

            Select Case mType
                Case enumMediaType.Audio
                    AP.Play()

                Case enumMediaType.Video
                    VP.Play()
            End Select

            isPlaying = True
            isPaused = False
        Catch e As Exception
            MsgBox(e.Message)

        End Try
    End Sub
    Public Sub Play(ByVal SourceFileName As String) Implements IMediaDevice.Play
        Me.Stop()
        If Not AP Is Nothing Then AP.Stop() : AP.Dispose()
        If Not VP Is Nothing Then VP.Stop() : VP.Dispose()

        Select Case FindFormat(SourceFileName)
            Case enumMediaType.Audio
                mType = enumMediaType.Audio
                AP = New Audio(SourceFileName)

            Case enumMediaType.Video
                mType = enumMediaType.Video
                VP = New Video(SourceFileName)
                VP.Owner = Me.pctVideoContainer

            Case enumMediaType.Other
                Try
                    'todo: Implement Other action for dx9 player. attempt playback, throw exception
                Catch
                End Try
        End Select
        Me.Play()
    End Sub
    Public Sub Pause() Implements IMediaDevice.Pause
        If isPaused = True Then isPaused = False Else isPaused = True
        Select Case mType
            Case enumMediaType.Audio
                If isPaused Then AP.Pause() Else AP.Play()

            Case enumMediaType.Video
                If isPaused Then VP.Pause() Else VP.Play()
        End Select
    End Sub
    Public Sub [Stop]() Implements IMediaDevice.Stop
        Select Case mType
            Case enumMediaType.Audio
                If Not AP Is Nothing Then AP.Stop()

            Case enumMediaType.Video
                If Not VP Is Nothing Then
                    VP.Stop()
                    pctVideoContainer.BackColor = Color.Black : pctVideoContainer.Refresh()
                End If
        End Select

        isPlaying = False
        isPaused = False
        Slider.Percent = 0
        Me.tmrPosition.Enabled = False
        Me.pbMovieLength.Value = 0
        System.Threading.Thread.CurrentThread.Sleep(250)
    End Sub

    Private Sub VP_Ending(ByVal sender As Object, ByVal e As System.EventArgs) Handles VP.Ending
        ' Me.Stop()

        Me.tmrPosition.Enabled = False
        pctVideoContainer.Image = Nothing
        pctVideoContainer.BackgroundImage = Nothing
        pctVideoContainer.BackColor = Color.Black : pctVideoContainer.Refresh()

        isPlaying = False
        isPaused = False

        Me.pbMovieLength.Value = 0
        RaiseEvent EndOfTrack()
    End Sub

    Private Sub AP_Ending(ByVal sender As Object, ByVal e As System.EventArgs) Handles AP.Ending
        ' AP.Stop()

        isPlaying = False
        isPaused = False

        RaiseEvent EndOfTrack()
    End Sub


I've tried just about everything I can think of... Remarked out some stuff, added a thread.sleep thinking it just needed a bit of time to fully stop playback and dispose, and if I remark out the Dispose lines, it works, but the memory usage grows and grows.


-Strict-
 
It might be in the dll itself, try rebooting your computer, if it is a problem with your code it is supposed to highlight the line in the code view not disassemble the program
 
Been looking at a few examples on the net and I tried the same thing myself in C# and I have got it to work by instead overriding the dispose method within the class... for example.

Code:
protected override void Dispose(bool disposing)
{
  if (disposing)
  {
     try
     {
        if (audio != null)
        {
           audio.Dispose();
        }
      }
      catch { }
    }
    base.Dispose(disposing);
}

and removing any lines where you have written

Visual Basic:
 : AP.Dispose()

Sorry it was too early to think how to write the dispose method in Visual Basic.
 
Sounds good for the endgame of the object, but I want to make sure the memory gets released after a track has been played.

For instance if there were a bunch of small media files that someone wanted to have played in a looping fashion since the dispose method doesn't get called until everything is closing down, and because you need to create a new playback object for a new file, the memory may not be freed until the program exits (which i would hope it was freed by then, if not theres serious proplems ^_^)

Oh, and also the reason I had the dispose call where they were is because my object inherits from UserControl, wich doesnt implement IDisposable. but, i guess i could do that if anything thinks it could make a difference.
 
.Net uses a Garbage Collector whenever you stop using a object by cutting all references the object is removed when more memory is needed or when a collection cycle takes place. Once you call .Dispose the object will be destroyed by the GC when one of the criteria occur.
 
Did you ever get a solution to this problem? In my case, I am using VS 2003 and MDX April 2005. The error occurs randomly even though I am explicitly disposing the audio object. After loading the DirectX debug symbols and setting up breaks on first chance exceptions, I get the following error:

> microsoft.directx.audiovideoplayback.dll!<Module>.AudioWndProc( hWnd = }, uint uMsg = 0x401, uint wParam = 0x0, int lParam = 0x9615fc) + 0x125 bytes
 
Back
Top