vigata / vgtmpeg

a Versed Generalist Transcoder
http://godromo.com/gmt/vgtmpeg
Other
22 stars 5 forks source link

DVD subtitle stream detection sometimes doubles the number of streams #4

Open dbpete opened 9 years ago

dbpete commented 9 years ago

When accessing some DVDs, the number of subtitle streams detected is double the actual number. I've seen this behavior on multiple DVDs.

Here's an example of a DVD that contains 5 subtitle streams on title 1, but vgtmpeg detects 10 subtitle streams. I've trimmed some of the output (chapters, audio tracks) just to make it a bit briefer. If you want to see the entire output I'll be happy to include it. The vgtmpeg version I'm using is the latest available from source.

$ vgtmpeg -i dvd://dvd/VIDEO_TS?title=1
vgtmpeg version 2.0.35 Copyright (c) 2010-2015 Alberto Vigata and the FFmpeg developers
  built on Mar 13 2015 18:03:10 with gcc 4.5.1 (GCC) 20100924 (Red Hat 4.5.1-4)
  based on ffmpeg version 2.5.4
  configuration: --disable-shared --enable-static --enable-gpl --enable-version3 --enable-nonfree --disable-debug --disable-ffplay --disable-ffserver
  libavutil      54. 15.100 / 54. 15.100
  libavcodec     56. 13.100 / 56. 13.100
  libavformat    56. 15.102 / 56. 15.102
  libavdevice    56.  3.100 / 56.  3.100
  libavfilter     5.  2.103 /  5.  2.103
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  1.100 /  1.  1.100
  libpostproc    53.  3.100 / 53.  3.100
Input #0, mpeg, from 'dvd://dvd/VIDEO_TS?title=1':
  Metadata:
    source_type     : dvd
  Duration: 02:11:36.31, start: 0.000000, bitrate: 7053 kb/s
    Chapter #0:0: start 0.000000, end 260.217356
    ...
    Chapter #0:32: start 7896.133178, end 7896.309489
    Stream #0:0[0x100e0]: Video: mpeg2video (Main), yuv420p(tv, smpte170m), 720x480 [SAR 32:27 DAR 16:9], max. 9800 kb/s, 29.50 fps, 59.94 tbr, 90k tbn, 59.94 tbc
    ...
    Stream #0:5[0x100bf]: Data: dvd_nav_packet
    Stream #0:6[0x10020]: Subtitle: dvd_subtitle
    Stream #0:7[0x10021]: Subtitle: dvd_subtitle
    Stream #0:8[0x10022]: Subtitle: dvd_subtitle
    Stream #0:9[0x10023]: Subtitle: dvd_subtitle
    Stream #0:10[0x10024]: Subtitle: dvd_subtitle
    Stream #0:11[0x10025]: Subtitle: dvd_subtitle
    Stream #0:12[0x10026]: Subtitle: dvd_subtitle
    Stream #0:13[0x10027]: Subtitle: dvd_subtitle
    Stream #0:14[0x10028]: Subtitle: dvd_subtitle
    Stream #0:15[0x10029]: Subtitle: dvd_subtitle
At least one output file must be specified

You'll notice vgtmpeg sees 10 subtitle streams (0:6 - 0:15).

For comparison, here's the output from lsdvd, which shows only 5 subtitle streams:

$ lsdvd -qs -t1 dvd/VIDEO_TS
...
Title: 01, Length: 02:11:36.633 Chapters: 33, Cells: 49, Audio streams: 04, Subpictures: 05
    Subtitle: 01, Language: en - English, Content: Normal_CC, Stream id: 0x20,
    Subtitle: 02, Language: es - Espanol, Content: Normal, Stream id: 0x21,
    Subtitle: 03, Language: en - English, Content: Normal, Stream id: 0x22,
    Subtitle: 04, Language: es - Espanol, Content: Normal, Stream id: 0x23,
    Subtitle: 05, Language: fr - Francais, Content: Normal, Stream id: 0x24,

I'm fairly sure lsdvd is only looking at the subtitle information found in VIDEO_TS/VTS_XX_0.IFO, whereas vgtmpeg is scanning (I assume) the actual files to detect the subtitle streams.

After some experimentation, I've found that every other subtitle stream detected by vgtmpeg is a duplicate of the previous stream. In other words, 0:6 is a duplicate of 0:5, 0:8 is a duplicate of 0:7, etc.

As an indication of this, I ran vgtprobe (I renamed the vgtmpeg version of ffprobe to vgtprobe) to count the number of frames in each subtitle stream:

$ vgtprobe -loglevel quiet -i dvd://dvd/VIDEO_TS?title=1 -count_frames -select_streams s -show_streams -print_format flat | grep nb_read_frames
streams.stream.0.nb_read_frames="1604"
streams.stream.1.nb_read_frames="1604"
streams.stream.2.nb_read_frames="1430"
streams.stream.3.nb_read_frames="1430"
streams.stream.4.nb_read_frames="152"
streams.stream.5.nb_read_frames="152"
streams.stream.6.nb_read_frames="151"
streams.stream.7.nb_read_frames="151"
streams.stream.8.nb_read_frames="139"
streams.stream.9.nb_read_frames="139"

You'll notice the number of frames for every other stream is exactly the same as the previous stream. Stream #1 (aka 0:6) is the same as stream #0 (aka 0:5), etc. While this isn't absolute proof the streams are the same, I think it's a pretty good indication. I've also done some spot comparisons by generating sections of video containing each of the subtitle streams and the subtitles displayed are identical between the 2 pairs.

FYI. I don't believe this is an issue confined to vgtmpeg. I've seen the same type of behavior using mplayer (-dumpstream), mpv (-stream-dump) and vobcopy. Maybe it's a problem with libdvdread? Or maybe it's just something similar in the way all these tools are using libdvdread?

The only tool I've seen that doesn't exhibit this behavior is makemkvcon (command line tool for makemkv). Unfortunately, the source for makemkvcon doesn't seem to be available.

vigata commented 9 years ago

I've been looking into this and I can't find anything particularly wrong with the code on libavformat/mpeg.c which is what's parsing all this stuff.

I have the feeling that the program stream (vob files) actually contain subpicture stream duplicates. Seems they are getting a different startcode id 0x2X for every stream and the startcode comes straight from the PES header, so it's not a result you would expect from a bug in the code.

vgtmpeg adds the streams on the IFO file + whatever is found during probing. This obviously needs to be rethought. Will try to get into this once the merge with 2.6.x is complete. I'll also look into getting that metadata through for the subtitles you mentioned in the other issue.

dbpete commented 9 years ago

I've been poking around in the code and from what I can tell, vgtmpeg isn't adding the subtitle streams from the IFO file. It does this for video and audio streams, but not for subtitle streams. All the subtitle streams are added during probing. I actually discovered this when I went to see if I could figure out how to add the metadata for subtitles. I'll add a comment to that issue about what I did.

Unfortunately, just adding the subtitle streams from the IFO doesn't fix this issue, the "duplicate streams" still get added during probing.

I wonder if this is a bug in libdvdread? Or maybe it's something odd with how some dvds are produced and maybe libdvdread could deal with it in some way?

vigata commented 9 years ago

You are correct that at the moment, subtitles streams are just added during probing.

I think the problem with the duplicate streams could be that there are simply duplicated in the vob files, therefore even if you make vgtmpeg add the streams from the IFO file they will still be found during probing because they are physically in the program stream. A possible solution would be to disallow streams that are not declared on the IFO. I have to think a bit how to implement this cleanly.