gdcl.co.uk-mpeg4
gdcl.co.uk-mpeg4 copied to clipboard
How to access GetMediaSampleTimes
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.
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();
}
}
Many thanks for the instant and very useful reply.
What is the __C() macro? I'm guessing it is something related to extern "C"{...} but I am not familiar with this usage.
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)
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.
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?
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.