locked
MediaTranscoder memory leak

    Question

  • I'm developing application for video transcoding. I'm using MediaTranscoder and MediaStreamSource as a sample source.

    Inside MediaStreamSourceSampleRequested i'm calling my MediaSourceReader (based on IMFSourceReader) and passing it MediaStreamSourceSampleRequest .

    Inside ReadSample i;m reading next video sample, releasing all the stuffs and passing media sample back to MediaStreamSourceSampleRequest using SetSample.

    I've found what during transcoding my app allocates memory ~equals of video file size * 1,5. Say if i transcoding 100 MB movie it allocates 150 MB and never freed the memory even after transcoding finished and all objects disposed.

    If needed i can provide a sample code via PM.

    Monday, August 11, 2014 7:21 PM

All replies

  • I'll ask our media guru to check this out.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    NOTE: If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Tuesday, August 12, 2014 12:33 PM
    Moderator
  • Hello,

    The problem is likely due to the fact that there are one or more outstanding references on the objects associated with the sample or on the sample itself. How are you creating the samples? Are you using a buffer pool or just blindly allocating samples for each call? Are you doing any active lifecycle management of the samples at all?

    -James


    Windows SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Tuesday, August 12, 2014 9:12 PM
    Moderator
  • Hi James,

    thank you for reply!

    That is how i'm creating samples for Transcoder, basically i'm just reading samples from medis source using IMFSourceReader

    bool MediaSourceReader::ReadSample(MediaStreamSourceSampleRequest^ request)
    {
    	HRESULT hr = S_OK;
    
    	if (request == nullptr)
    	{
    		return false;
    	}
    
    	DWORD streamIndexActual;
    	DWORD flags = 0;
    
    	LONGLONG timeStamp = 0;
    
    	ComPtr<IMFMediaStreamSourceSampleRequest> spRequest = nullptr;
    	ComPtr<IMFSample> spSample = nullptr;
    
    	hr = m_spSourceReader->ReadSample(MF_SOURCE_READER_FIRST_VIDEO_STREAM, 0, &streamIndexActual, &flags, &timeStamp, spSample.GetAddressOf());
    
    	bool endOfstream = ((flags & MF_SOURCE_READERF_ENDOFSTREAM) == MF_SOURCE_READERF_ENDOFSTREAM);
    
    	if (endOfstream)
    	{
    		return false;
    	}
    
    	if (FAILED(hr))
    	{
    		return false;
    	}
    
    	hr = reinterpret_cast<IInspectable*>(request)->QueryInterface(spRequest.ReleaseAndGetAddressOf());
    
    	if (FAILED(hr))
    	{
    		return false;
    	}
    
    	if (FAILED(hr))
    	{
    		return false;
    	}
    
    	hr = spRequest->SetSample(spSample.Get());
    
    	spSample = nullptr;
    	spRequest = nullptr;
    	
    	if (FAILED(hr))
    	{
    		return false;
    	}
    
    	return true;
    }

    Next function is the calling function for this code

    void MediaStreamSourceSampleRequested(MediaStreamSource sender, MediaStreamSourceSampleRequestedEventArgs args) {
                m_MediaSourceReader.ReadSample(args.Request);
            }

    I'm expect what Transcoder itself will release a provided samples after processing it. Wrong expectations? 

    Wednesday, August 13, 2014 8:02 AM
  • In addition.

    As far as i understand MediaStreamSample holds sample info in two different manners -

    1. if it was initialized with CreateFromBuffer or CreateFromStreamAsync - Buffer member variable is valid (not null) and i can do something with buffer (re-use it, for instance)

    2. If it was initialized with spRequest->SetSample(spSample.Get()); (like in my case) Buffer is null and it keeps reference to provided media sample somwhere in IMFSample *pSample member variable what is not exposed to the class interface. In this case i have no ways to release a sample after it being processed and it still keeps memory allocated for media buffer.

    Is that correct? 

    Friday, August 15, 2014 8:51 AM
  • Just to someone who will find the same issue

    i solved memory consumption problem by calling 

    spReader->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, FALSE);

    after initialization SourceReader and 

    spReader->SetStreamSelection(streamIndex, TRUE);

    for selected streams.

    BTW our high-level media library available from here https://github.com/INDExOS/media-for-mobile 

    Tuesday, October 14, 2014 2:17 PM