[FFmpeg-devel] dvd/vob "decoder" part 1: the system itself

Erik Van Grunderbeeck erik
Sun Jul 12 02:00:33 CEST 2009


Included are the files, and patches needed for the dvd decoder.

I threw away my original system on trying to insert packets into the main
stream (as the "attachment/data" type stream). The reason for that is that
the dvd data stream, that contains commands for the client can change/insert
packets "in the past". Example; a user seeks back. The DVD ifo system will
insert packets containing "change the subtitle color" so it works ok for the
displayed cell/chapter. LibAV doesn't expect new packets inserted
"backwards" in the stream, and the buffer system gets all messed up because
packet sizes are off. Changing to a new system means my "hack" on decoding
the packet header isn't needed any more, and except for stream flagging the
mpegps  demuxer should be unchanged. My attachment decoder is not needed
anymore (for those who looked at it, only dvd_protocol.c/h are still

The new system uses a callback, that the user registers. This is, after much
experimenting, the best way I could come up with. The callback though is
registered per protocol, and thus changes are needed in "gasp" URLContext.
Reason for keeping it per context? Well, a user can be reading from several
dvd devices at the same time if he/she uses the avlibs. Or some end devices
(like the ps3) send several request to open a file at the same time. If one
callback is registered for the whole library, this messes up the system.

Whats send in the callback? Basically AVDVDParseContext packets. They
contain a type (the enum effdvd_Type ) that tells the end-user app what
should be done, and a pts timestamp in dvd time (90000/tick). The packets
should be handled at that time.

There are some packets which are obvious (like: new subtitle palette) and
some that are not. The most important one is effdvd_Reset_IFO.

effdvd_Reset_IFO asks the end-user app: clear your streams, flag all streams
you are using as invalid (more later on that), and be prepared to re-init
all your codec decoders. 

Why does one need to do that? Because a vob file 1 might contain audio data
in ac3 with 2 channels, while a vob 2 might have it in 6 channels. Or the
resolution of the video stream might change (from dvd pal to dvd ntsc
widescreen for example).

First; DVD's may contain up to 64 streams. One of the patches changes the
MAX_STREAMS constant to match that.

Second; Stream re-init. I implemented this by adding a flag to AVStream (at
the end, discard_flags). Set this to one in end-user app, and this will tell
the demuxer that this stream has been discarded by user (user closed all
codecs, etc). 

It works by telling the demuxer that once it dedects a certain packet type,
and normally does a av_new_stream; don't re-add the stream to the end of the
new list (pushing more and more streams on the list). Example; suppose the
discard_flag is set to 1 for the video stream (and we only have one). When a
new packet is received by the demuxer, its loop will not find a valid video
stream anymore. It thus will create a new one, but will fill the slot for
the "old" video stream with the new video stream. Don't know if this text
makes sense, bit a quick look at the code should be helpful.

Why not do this in the protocol reader? Basically 1) because the protocol
doesn't and shouldn't know about the streams and 2) because the end-user
needs to close and free his/her decoders. Once that's done, the demuxer
doesn't even know.

Next; chapter seeking. I added a new flag for that: 

#define AVSEEK_FLAG_DIRECT	 8 ///< seek directly, skipping any stamps
and translation
#define AVSEEK_FLAG_CHAPTER	 16 ///< seek to chapter, if supported

Using that will basically use av_seek_frame() to override a search like it
does for AVSEEK_FLAG_BYTE. The arguments timestamp will thus position
chapters, instead of timestamps.

Summary; whats the total change;

1) The whole setup adds a protocol handler called ffdvd. User inits his open
file with av_open_input_file ("dvdread:e:/") or
2) User registers a callback by using url_fset_protocol_callback(), a new
function in avio.c. I tried to make it generic.
3) User polls streams as before for audio/video
4) User can get callback events from the protocol, with timestamps.
5) Events get examined for the timestamps on the protocol packet, and
handled upon.
6) When needed, these events are executed, and for some functions a notify
is send back (example, when user selects a button
dvd_protocol_select_button() is called).
7) That's it.

How well does this all work? I build a example app separate from ffmpeg, on
which rather big changes are going to be needed. Note that these changes
have almost nothing to do with the dvd protocol handler. They are mostly
implementing the "we should look at this/this is wrong/etc" comments
(example; discarding new streams). I have ffplay ok, but will need to work
with someone on ffmpeg. Source is. Offcourse available.

I am attaching the main files here, and the most important patches. Since I
am not sure on how the continue on this, please tell me how this needs to be
handled (ege do patches first, what order,. Etc. ) If the system is
accepted, at least one patch needs a major version bump. I should probably
split up some patches too.

Note 2; I need to talk to the people for libdvdread, since I fixed a few
problems in their code (and added one function to read attributes that its
not available now dvdnav_get_video_attributes()). To have this working, we
would offcourse also need to depend on libdvdread (if the user enabled it by
./configure, changes for makesfiles and that needed).

Note 3: we will probably need some commandline extensions to specify seeking
to a chapter, etc. for ffmpeg

I have worked on and of on this for the better part of 2 months figuring out
the best and least intrusive way. If this all gets rejected, I am fine with
that. If it doesn't, also. Just let me know. 

-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: dvd_protocol.c
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment.asc>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: dvd_protocol.h
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment.txt>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: stream_select.patch
Type: application/octet-stream
Size: 1143 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: avio_h_protocol.patch
Type: application/octet-stream
Size: 786 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: avio_buf.patch
Type: application/octet-stream
Size: 449 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: utils_seek.patch
Type: application/octet-stream
Size: 5379 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment-0003.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: avio_c_protocol.patch
Type: application/octet-stream
Size: 1877 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment-0004.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: av_format_streams_change.patch
Type: application/octet-stream
Size: 2315 bytes
Desc: not available
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20090712/7ddceb1e/attachment-0005.obj>

More information about the ffmpeg-devel mailing list