Which filter is responsible for determining the duration and how does
it work with the source filter to return this information for an
MPEG-2 file?
Thanks,
Mike Springer
Do you know what the ratio of I, P, and B frames is in your video clip? It would be interesting to see if the difference in frame counts being reported by the various utilities is some multiple of a full GOP sequence.
Have you tried using VirtualDub with the MPEG2 mod (http://fcchandler.home.comcast.net/) to open the file? What is the frame count reported by it?
If you don’t get any good answers here you might want to post this question on the DirectXAV LISTSERV list (http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?SUBED1=directxav&A=1). It seems like several of the Elecard guys hang out there and they may be able to directly answer your question.
Joe Flynn
Mike
Joe Flynn <Joe Fl...@discussions.microsoft.com> wrote in message news:<89F5521B-A611-4A2B...@microsoft.com>...
> I don’t have any good answers - just a couple of random thoughts:
>
> Do you know what the ratio of I, P, and B frames is in your video clip? It would be interesting to see if the difference in frame counts being reported by the various utilities is some multiple of a full GOP sequence.
>
> Have you tried using VirtualDub with the MPEG2 mod (http://fcchandler.home.comcast.net/) to open the file? What is the frame count reported by it?
>
> If you don’t get any good answers here you might want to post this question on the DirectXAV LISTSERV list (http://discuss.microsoft.com/SCRIPTS/WA-MSD.EXE?SUBED1=directxav&A=1). It seems like several of the Elecard guys hang out there and they may be able to directly answer your question.
I am not really sure what mechanism IMediaDet uses to determine the duration of an MPEG file since this info is not stored in any internal header structure. If I had to guess I would say that it is doing something like taking the size of the file and the relative bit rate and computing a duration from that. This method could be somewhat problematic with variable bit rate files however. Alessandro Angeli might be able to this question in more detail.
One other thing you could try is to run your sample clip through the SampleGrabCB.exe file that ships as part of the DirectX 9 SDK. I think it is in the ..\Samples\C++\DirectShow\Bin\ directory. How many frames does it report?
Joe Flynn
Mike
Joe Flynn <joseph...@nospam.com> wrote in message news:<9F9DC00B-54A0-485B...@microsoft.com>...
> Interesting â€" I guess the question is which utility is giving the correct frame count. At 15 frames per GOP the 7050 frame result yields an integer number of GOPs. Of course I guess some sort of scene change detection by the encoder might have possibly encoded some GOPs with less than 15 frames (not sure if this is possible but it seems reasonable).
Mike
Joe Flynn <joseph...@nospam.com> wrote in message news:<9F9DC00B-54A0-485B...@microsoft.com>...
Mike,
I don't know if you are still monitoring this thread but if so I think I
know what might be causing the difference in frame counts being reported
between the Elecard tool and VirtualDub/SampleGrabberCB.exe. I probably
should have caught this earlier but its been a long week. Basically when
you encode an MPEG stream using B-frames the first set of B-frames in
the stored bitstream for each GOP belong to the preceeding GOP. In your
file the GOP frame order as stored on disk is IBBPBBPBBPBBPBB. However
for the very first GOP at the beginning of the file the encoder has a
choice - it can either choose not to encode the first set of B-frames
(because they are meaningless) in which case the frame order of this GOP
will be IPBBPBBPBBPBB - or it can just encode junk B-frames and annote
to the decoder that these particular frames are invalid by setting the
Closed GOP bit in the GOP Header. I believe that in your file the very
first GOP may have 15 total frames encoded in it but since the Closed
GOP bit is set only 13 of those frames are valid. If the Elecard tool
isn't properly interpreting the Closed GOP bit in the first GOP then it
will end up erroneously adding the 2 junk B-frames into your total frame
count. That would explain the difference in frame counts - Elecard
reports 7050 total frames - while VirtualDub and the SampleGrabberCB.exe
report only 7048 frames.
Joe Flynn
Aargh..... In the preceeding message every place in which I referred to
the Closed GOP bit I really meant to say the Broken Link bit. Sorry for
the mistake - like I said its been a long week.
Joe Flynn
Thanks again. I sent a sample MPEG to Elecard for analysis, but since
they have an upload file size limit, I was not able to send the one
containing 7050 frames. Given the smaller sample that I sent, they
basically said what you did... that the first two B frames in the
first GOP temporally preceed the I frame and are thus disgarded. Even
with this information, I still don't understand why that when a video
containing 7050 frames ( 7048 of them temporally valid) is rendered in
a DirectShow filter graph, a call to the IMediaSeeking->GetDuration()
method returns 234.000014 seconds. If my math is correct, I would
expect (7048 - 1)/29.97 or 235.135135 seconds. Our application
'stiches' several (> 80) 100MB MPEG2 segments together and plays them
seamlessly back to back. It is easy to see how the cumulative effect
of a 1.14 second difference per video causes a serious drift over 80
segments.
If I could get a handle on how the filtergraph determines the duration
of the file (in our case, playlist), then perhaps I could solve the
problem. We have created our own File List Source Filter so perhaps I
can use this to get a look at what is going on during the filter
connection process.
Mike
Joe Flynn <joseph...@nospam.com> wrote in message news:<uTWIWgbV...@TK2MSFTNGP10.phx.gbl>...
I found the following Google Groups post that mentions an alternate
method of determining MPEG file duration that is calculated from the
mux_rate and the file size. The problem is that this method is only
going to yield an approximation which is also most likely what is
happening with IMediaDet. If you need an accurate value for the file
duration then the best way that I can think of to obtain it is by doing
just what you mention - counting the total number of frames in the file
and then dividing the result by the frame rate. However I think you
might be making a mistake in your calculation - if your file has 7048
frames (remember frame 0 is a frame) then the 7048th frame will end at a
time equivalent to 7048/frame_rate. And if accuracy is really important
remember that 29.97 isn't the exact frame rate either - the true frame
rate is equivalent to 30000/1001.
Do you need to have the total duration for all of your clips available
immediately upon creation of your playlist? If not, then a possible
solution would be to have the playlist playback running in one thread
and then in an alternate thread simply build a SampleGrabber Callback
graph with a Null renderer that scans the next file in the playlist to
determine the total frame count and then derives the clip duration from
that. If you set the graph SyncSource to null then the graph will run as
fast as possible and shouldn't take too long.
Joe Flynn
> with this information, I still don't understand why that
> when a video
> containing 7050 frames ( 7048 of them temporally valid)
> is rendered in
> a DirectShow filter graph, a call to the
> IMediaSeeking->GetDuration()
> method returns 234.000014 seconds. If my math is
> correct, I would
> expect (7048 - 1)/29.97 or 235.135135 seconds. Our
> application 'stiches' several (> 80) 100MB MPEG2 segments
> together and plays them
> seamlessly back to back. It is easy to see how the
> cumulative effect
> of a 1.14 second difference per video causes a serious
> drift over 80 segments.
>
> If I could get a handle on how the filtergraph determines
> the duration
> of the file (in our case, playlist), then perhaps I could
> solve the
> problem. We have created our own File List Source Filter
> so perhaps I
> can use this to get a look at what is going on during the
> filter connection process.
It's not the graph that determines the duration. The
documentation clearly states how IMediaSeeking works: when a
method is called on the graph's IMediaSeeking, the graph
distributes the call to all the renderers that implement
IMediaSeeking; then starting with the renderers, each filter
forwards the call to the upstream filter's output pins until
a filter returns with an error or a value. In your case, the
MPEG2 splitter returns the value and the graph has no
internal magic itself to determine the duration. Since the
MPEG2 syntax provides no way to determine the duration of a
given stream (it is meant to be used in a random-access live
environment), each splitter implements some euristic method
to calculate the duration. The most common one, since it is
the only efficent one, is to calculate the duration from the
byte size and bit rate (mux rate or bitrate of the first GOP
or whatever). This is of course far from accurate but it is
usually enough for playback. An accurate calculation
requires a full stream scan which is not acceptable because
it introduces a very long start delay.
Since you are joining MPEG files, you should also consider
that your audio/video drift may not depend on this
miscalculation but on the fact that the audio and video
elementary streams in the program stream often have slightly
different durations and there is often also a delay between
the two in the muxed stream. Tools like PVAStrumento will
tell you what the a/v delay and duration difference are.
For Joe, IMediaDet too does nothing magic: it simply builds
an internal graph and asks the filters about the duration,
which ends up asking the splitter as well.
--
/**
* Alessandro Angeli
*
* MVP :: Digital Media
*
* a dot angeli at biosys dot net
*/
Mike
"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in message news:<evodporV...@TK2MSFTNGP12.phx.gbl>...
> Thanks for the information. Is there a way to override this estimated
> duration, short of writing an MPEG2 Splitter filter? Since I have
> index files that detail the content of each MPEG2 segment, I would
> like to use this information. I would want to be able to make calls
> to IMediaSeeking SetPosition() without worrying about extending past
> what the filtergraph, incorrectly, believes is the end of the stream.
> Is this possible?
I believe someone from Elecard/Moonlight some time ago said that their
splitter can be configured to use the index generated by their own indexing
tool, so that frame-precise seeking and precise duration estimation are
possible.
--
Alessandro Angeli
MVP::DigitalMedia
> Thanks for the information. Is there a way to override this estimated
> duration, short of writing an MPEG2 Splitter filter? Since I have
> index files that detail the content of each MPEG2 segment, I would
> like to use this information. I would want to be able to make calls
> to IMediaSeeking SetPosition() without worrying about extending past
> what the filtergraph, incorrectly, believes is the end of the stream.
> Is this possible?
I don't know how you index your MPEG2 files, but using DVD2AVI also creates
a precise index (AFAIK, the DVD2AVI code is what's used by VDubMod) and
there is a source filter from the Guliverkli project on www.SourceForge.net
that can read the DVD2AVI index file as if it were the actual MPEG2.
--
Alessandro Angeli
MVP::DigitalMedia
a dot angeli at biosys dot net