[FFmpeg-devel] [RFC/PATCH] Pass PRIVATE_STREAM_2 MPEG-PS packets to caller
peper03 at yahoo.com
Mon Feb 25 17:23:18 CET 2013
On 25/02/13 04:36, Michael Niedermayer wrote:
> On Mon, Feb 25, 2013 at 12:47:47AM +0100, Richard wrote:
>> Specifically, I started with the problem of playing audio DVDs (in
>> the sense of a normal video DVD with primarily only audio). These
>> have a single video frame followed by an arbitrary number of audio
>> frames. At the moment, the demultiplexing code in Myth ends up
>> reading and buffering too much audio data because it is normally
>> slowed down by the availability of video buffers. Now it could be
>> argued that it should be making more use of the timecodes in the
>> audio and video packets but that is also difficult when
>> discontinuities are to be expected and there's no way to ensure the
>> demultiplexer/decoder is informed about the discontinuity ahead of
>> time (ideally 'now' but certainly not afterwards).
>> For my in-depth ideas with respect to single images with audio, I
>> can point you here:
> IRC> peper03: Playing with VobEdit and looking at the PCI and DSI
> IRC> structures here http://dvdnav.mplayerhq.hu/dvdinfo/ shows that we
> IRC> *can* work out how long to show a still frame for.
> so AVPacket.duration could be set according to this information?
> also i remember something about sequence end codes and still pictures
> they could be used too if they are there
The duration would be the duration of the video frame, not of the data
packet. The contents of the data packet would allow you to calculate
the duration of the video frame and even then, you couldn't calculate
the total duration. Only the duration until the next data packet.
The sequence end code allows you to determine *which* frame is the last
frame. That can also be done using the 'vobu_se_e_ptm' field in the PCI
packet - whichever works best in any given architecture.
Does it make sense to give a pure data packet a duration? I suppose you
could use the start and end fields of the PCI packet to indicate the
time frame the data applies to. In that case, it would be necessary to
'merge' the two packets together as the DSI packet has no time
information at all (apart from SCR).
>>> for example random buffering + no timestamps just feels wrong also
>>> this feels a bit like a hack, to output a private stream raw like
>>> that. we dont do that for audio or video either, there you get clean
>>> packets one for each frame with timestamps, a codec id and various
>>> other things
>> The problem is that the contents of packets with startcode '0x1bf'
>> is not uniquely defined. In the context of DVDs, it is, but given
>> any MPEG program stream, it isn't. That makes it difficult to
>> implement a parser. The PCI structure indicates the start and end
>> PTS values for the following VOBU, so the start PTS could be used,
>> but the DSI structure only references the system clock reference.
>> It might be possible to write a parser to decode the contents based
>> on 'if this byte is X and that byte is Y and those bytes are all
>> zero, then we've almost certainly got a PCI structure' but I'm not
>> convinced that is that much cleaner. The contents are simply
>> undefined so there'll always be a chance of false-positives and
> all the probing code that detects formats & codecs checks if a byte
> is X and another is Y and so on. Whats your point here?
Sorry, my point was that there's no 'magic number' to definitely
identify the contents. All you could do is say 'if the length of the
packet is 980 and the first byte is zero then it's *probably* a PCI
packet'. There are probably other 'sanity checks' that could be
performed to increase the reliability but it's not as clean as having
some sort of defined identifier. If that's good enough for you, I don't
have a problem with it.
> we also return ac3 frames instead of private stream data ...
Yes, that thought came to me as well after I'd written my last reply.
The contents of private stream 1 packets are also undefined. The only
difference is that private stream 1 packets will also contain the usual
header information. So presumably they are determined to be AC3 packets
on the basis of sanity checks, or is there some form of magic number?
So, working on the assumption that the contents can be determined to a
sufficiently reliably degree do you prefer the following:
1) Define codec ID 'AV_CODEC_DVD_NAV' instead of 'AV_CODEC_PRIVATE_STREAM_2'
2) Implement a parser to combine the two packets (PCI and DSI) found on DVDs
3) Set 'pts' to the 'vobu_s_ptm' field in the PCI packet
4) Set 'dts' to AV_NOPTS_VALUE
5) Potentially set 'duration' to (vobu_e_ptm - vobu_s_ptm)
As I said, I don't know whether it makes sense to set the duration field
for a pure data packet but I don't have a problem to do it if that's
what you'd prefer.
> all things for which proper fields exist like pts/dts/duration/codec_id
> and so on should be set correctly before some raw packets of any
> stream are exported just to get to their correct values.
That's fine by me. From my point of view, it's just a question of what
to do with packets that are defined as 'user-defined'. If you want to
handle them 100% correctly, you can't make any assumptions about their
contents as anyone could use them for any purpose. Almost any attempt
to determine their contents without context *could* fail. All you can
do is pass them on unprocessed to allow the calling application (which
has the context required) can decode them.
On the other hand, you can take the approach that 99% of these packets
ever encountered will contain data in a certain format (in this case for
DVDs). By performing a few sanity checks, you can increase your
confidence even more so that the likelihood of misinterpreting the data
is almost zero.
The first option is purer, as you are following the specifications. The
second is potentially more useful albeit with the proviso that you can't
give a 100% guarantee that no packets will be misinterpreted.
A third option is to allow the calling application to provide the
context required. I don't know whether this is already possible and I'm
not putting it forward as a suggested change, but it would be an
Personally, if you prefer the second option, I don't have a problem to
implement it that way. I assume that there aren't many MPEG streams out
there that use these private streams so that a couple of checks should
give sufficient confidence to interpret the contents successfully.
If you are ok with my suggestions above, I'll create a new patch to
parse and merge the packets, setting the fields as required.
More information about the ffmpeg-devel