Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to access GetMediaSampleTimes #29

Open
ReggThims opened this issue Jun 19, 2020 · 7 comments
Open

How to access GetMediaSampleTimes #29

ReggThims opened this issue Jun 19, 2020 · 7 comments
Labels

Comments

@ReggThims
Copy link

Sorry to ask what may be a trivial COM question, but can you point me in the right direction to access GetMediaSampleTimes()? I cannot see it as an interface to the demultiplexor when using GraphStudioNext.

@roman380
Copy link
Owner

GraphStudioNext shows well known interfaces, GetMediaSampleTimes is an extension specific to this DLL so it's there but GSN knows nothing about it.

A code snippet on how I use it in another project:

const CComPtr<IPin> pOutputPin = _FilterGraphHelper::GetFilterPin(pDemultiplexerBaseFilter, PINDIR_OUTPUT, MajorType);
const CComQIPtr<IDemuxOutputPin> pDemuxOutputPin = pOutputPin;
if(pDemuxOutputPin)
{
    _ATLTRY
    {
        ULONG nSampleCount = 0;
        CComHeapPtr<REFERENCE_TIME> pnSampleStartTimes;
        CComHeapPtr<ULONG> pnFlags;
        __C(pDemuxOutputPin->GetMediaSampleTimes(&nSampleCount, &pnSampleStartTimes, NULL, &pnFlags, NULL));
    }
    _ATLCATCHALL()
    {
        _Z_EXCEPTION();
    }
}

@ReggThims
Copy link
Author

Many thanks for the instant and very useful reply.

@ReggThims
Copy link
Author

What is the __C() macro? I'm guessing it is something related to extern "C"{...} but I am not familiar with this usage.

@roman380
Copy link
Owner

checks if HRESULT is a success code and throws otherwise. Similar to ATLENSURE_THROW IIRC. Not significant in context of your question: you need to QueryInterface for IDemuxOutputPin then you have the method accessible. The method allocates memory for arrays and caller is responsible to free it with CoTaskMemFree (what CComHeapPtr does, see https://stackoverflow.com/a/15420095/868014)

@ReggThims
Copy link
Author

Thanks again. I'd figured out the usage of memory from the mp4demux code, but good to have it confirmed. Having access to the frame times and knowledge of key frames will be very useful.

@ReggThims
Copy link
Author

Works a treat... thank you. However, I deal with files of a wide range of sizes and having the need to move the information for the entire file at a time feels excessive... For example, when stepping by frames we either have to hold the entire frame list in memory (feels a waste of space as the information could be obtained from mp4demux), or we have to read it each time we need it (which could be quite slow in a large file and risks running out of memory).

I was wondering about extending the interface by adding: SetMediaSampleTimeRange(REFERENCE_TIME rtStart, REFERENCE_TIME rtUpto, ULONG flags); or similar.

To constrain fetches of data... flags would have bits for things like: KEY frames only, first point is point before start of range, last point is point after end of range.

Do you have any feelings about this and would you be open to accepting a patch along these lines?
The MP4Demux code is not the most transparent in the way that indices work... are there any clues apart from reverse engineering the source?

@roman380
Copy link
Owner

roman380 commented Jun 21, 2020

If you want to extend it this way, I would merge the patch of course.

I myself used this method in a specialized player which deals with low delay random position scrubbing, fast and slow playback in wide range of rates, looped playback, reverse, reverse looped playback - to achieve all this I needed frame times in advance with knowledge for frame times and key frames. Hence the method. We used to deal with very large files with gigabytes of data and hours of recording, but I don't remember map of frames to be an issue, I could have kept that outside of process memory perhaps.

But either way what you wrote makes sense and if you're willing to extend it - sure it's good idea and I will gladly merge this so that this code is up to date for those who still takes advantage of it.

The MP4Demux code is not the most transparent in the way that indices work... are there any clues apart from reverse engineering the source?

mp4demux is following the original MPEG-4 Parts 12, 14 spec about MP4 file format (which is mostly intersecting MOV file format https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-33307) and one of the parts of it is stbl atom/box https://wiki.multimedia.cx/index.php/QuickTime_container#stbl where it reads data from. I'd say that source code is mostly following the spec and it's the spec to "reverse engineer" to get an idea about the format itself.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants