Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

MPEG-2 Duration and Seeking

58 views
Skip to first unread message

Springer

unread,
Jun 13, 2004, 9:03:02 PM6/13/04
to
I have a question about random seeking and durations reported using
Elecard DirectShow filters playing an MPEG-2 file. I have an MPEG-2
file that I have run through the MPEG Stream Explorer. When I parse
out the .mlmix file that is generated, it shows 7050 frames. Given
this information, I expect the duration to be (7050 -1)/29.97 or
235.201869 seconds. However, when I play the file using the Elecard
PlayerApp (from the ActiveX example), it shows the file to contain
7012 frames with a duration of 234.0 seconds. Also, if I use
IMediaDet to get the duration of the MPEG program stream, I get
234.000469 seconds. What is causing this difference? I would like to
be able to depend on the .mlmix file information, since this provides
an absolute timestamp and a byte offset into the file for each frame.

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

Flynn@discussions.microsoft.com Joe Flynn

unread,
Jun 14, 2004, 12:41:11 PM6/14/04
to
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.


Joe Flynn

Springer

unread,
Jun 15, 2004, 10:24:12 AM6/15/04
to
Joe,
Thanks for your speedy response. I used the VirtualDUB tool that
you referenced and it appears to identify the duration much more
accurately (in my example, I expect 7050 frames and the VirtualDUB
tool identifies 7047 frames). I have hundreds of video files that
display the same type of result using VirtualDUB (3 less frames than
reported by the Elecard Indexer). This leads me to believe that the
Elecard Demultiplexer is doing something unexpected when getting info
from the source filter to determine the duration.
Do you know how the IMediaDet determines the duration of a video.
Is there information in a header that is used or what?
To answer your question about the IPB ratio... my samples are all
1:4:10. Each GOP is IBBPBBPBBPBBPBB.


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.

Joe Flynn

unread,
Jun 15, 2004, 1:16:01 PM6/15/04
to
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).

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

Springer

unread,
Jun 16, 2004, 5:08:49 PM6/16/04
to
Joe,
I ran the 7050 frame file through the SampleGrabCB SDK tool and it
reported 7048 samples (0 - 7047), which is the same that the
VirtualDUB application found. I have been contacted by the Elecard
technical support on the issue. Hopefully, they will provide me with
some useful input.

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).

Springer

unread,
Jun 16, 2004, 5:41:14 PM6/16/04
to
Joe,
I ran the 7050 frame file through the SampleGrabCB SDK tool and it
reported 7048 samples (0 - 7047), which is the same that the
VirtualDUB application found. I have been contacted by the Elecard
technical support on the issue. Hopefully, they will provide me with
some useful input.

Mike

Joe Flynn <joseph...@nospam.com> wrote in message news:<9F9DC00B-54A0-485B...@microsoft.com>...

Joe Flynn

unread,
Jun 19, 2004, 12:18:28 AM6/19/04
to
> I ran the 7050 frame file through the SampleGrabCB SDK tool and it
> reported 7048 samples (0 - 7047), which is the same that the
> VirtualDUB application found. I have been contacted by the Elecard
> technical support on the issue. Hopefully, they will provide me with
> some useful input.
>

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

Joe Flynn

unread,
Jun 19, 2004, 12:44:18 AM6/19/04
to
> 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


Springer

unread,
Jun 19, 2004, 4:42:53 PM6/19/04
to
Joe,

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>...

Joe Flynn

unread,
Jun 19, 2004, 8:40:31 PM6/19/04
to
> 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.
>

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

Joe Flynn

unread,
Jun 19, 2004, 8:43:50 PM6/19/04
to
I just realized that I forgot to post the Google Groups link that I
referred to - its been one of those weeks. Here it is:

http://groups.google.com/groups?q=MPEG+duration&hl=en&lr=lang_en&ie=UTF-8&selm=eg2_9.33028%24x9.10639863%40twister.socal.rr.com&rnum=2

Alessandro Angeli [MVP::DigitalMedia]

unread,
Jun 20, 2004, 7:31:45 AM6/20/04
to
Springer wrote:

> 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
*/


Springer

unread,
Jun 22, 2004, 12:25:27 PM6/22/04
to
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?


Mike

"Alessandro Angeli [MVP::DigitalMedia]" <nob...@nowhere.in.the.net> wrote in message news:<evodporV...@TK2MSFTNGP12.phx.gbl>...

Alessandro Angeli [MVP::DigitalMedia]

unread,
Jun 22, 2004, 12:36:26 PM6/22/04
to
"Springer" <Sprin...@navair.navy.mil> wrote:

> 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

Alessandro Angeli [MVP::DigitalMedia]

unread,
Jun 22, 2004, 12:46:41 PM6/22/04
to
"Springer" <Sprin...@navair.navy.mil> wrote:

> 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

0 new messages