[vlc-commits] [Git][videolan/vlc][master] 3 commits: demux: ps: split LPCM/MLP AOB detection
Steve Lhomme (@robUx4)
gitlab at videolan.org
Wed Aug 20 15:32:24 UTC 2025
Steve Lhomme pushed to branch master at VideoLAN / VLC
Commits:
3d0669c3 by Steve Lhomme at 2025-08-20T14:16:08+00:00
demux: ps: split LPCM/MLP AOB detection
In AOB files LPCM is always 0xa0 and MLP always 0xa1.
- - - - -
7b0b957e by Steve Lhomme at 2025-08-20T14:16:08+00:00
demux: ps: relax the test for LPCM AOB detection
The 0xc0 check was added for MLP in 7e3972c490bf6de6db0050dc05a3a6974dd12d88
Verified on a VOB with LPCM, p_pkt[i_start + 6] is always 0x80.
libavformat has the same test to detect PCM [^1].
[^1]: https://code.ffmpeg.org/FFmpeg/FFmpeg/src/6dd83fab44ca309b02b4ca1baea3ca9ed8b6180f/libavformat/mpeg.c#L517
- - - - -
1ae5b0b8 by Steve Lhomme at 2025-08-20T14:16:08+00:00
demux: ps: define what flavor of PS streams can be expected
Between VOB and AOB files the 0xa0->0xaf substreams may be used
with different codec or different encapsulation.
There is nothing in the data to really distinguish them. But when reading
either of those files we know if the file we opened is a dvd, dvda, .VOB,
.AOB or something else.
This will break detection of MLP in AOB files that are not named *.AOB.
But it was already broken in a different way by checking a certain value.
In any case DVD sources will be considered as DVD unless it's marked as
coming from DVD-Audio.
The DVD-Audio support in dvdread is commented out and will have to be
uncommented when DVD-Audio support is added.
- - - - -
5 changed files:
- modules/access/dvdnav.c
- modules/access/dvdread.c
- modules/demux/mpeg/ps.c
- modules/demux/mpeg/ps.h
- modules/demux/vobsub.c
Changes:
=====================================
modules/access/dvdnav.c
=====================================
@@ -1526,7 +1526,7 @@ static int DemuxBlock( demux_t *p_demux, const uint8_t *p, int32_t len )
}
default:
{
- int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
+ int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer, PS_SOURCE_VOB );
if( i_id >= 0xc0 )
{
ps_track_t *tk = &p_sys->tk[ps_id_to_tk(i_id)];
=====================================
modules/access/dvdread.c
=====================================
@@ -648,7 +648,7 @@ static int DemuxBlock( demux_t *p_demux, const uint8_t *p, int len )
}
default:
{
- int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
+ int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer, /*p_sys->type == DVD_A ? PS_SOURCE_AOB :*/ PS_SOURCE_VOB );
if( i_id >= 0xc0 )
{
ps_track_t *tk = &p_sys->tk[ps_id_to_tk(i_id)];
=====================================
modules/demux/mpeg/ps.c
=====================================
@@ -109,6 +109,7 @@ typedef struct
PSMF_PS,
IMKH_PS,
} format;
+ enum ps_source source;
int current_title;
int current_seekpoint;
@@ -253,6 +254,19 @@ static int OpenCommon( vlc_object_t *p_this, bool b_force )
p_sys->current_seekpoint = 0;
p_sys->updates = 0;
+ p_sys->source = PS_SOURCE_UNKNOWN;
+ if ( likely(p_demux->s->psz_url != NULL) )
+ {
+ size_t url_len = strlen( p_demux->s->psz_url );
+ if ( url_len >= 4 )
+ {
+ if ( !strncasecmp( &p_demux->s->psz_url[url_len-4], ".AOB", 4 ))
+ p_sys->source = PS_SOURCE_AOB;
+ if ( !strncasecmp( &p_demux->s->psz_url[url_len-4], ".VOB", 4 ))
+ p_sys->source = PS_SOURCE_VOB;
+ }
+ }
+
vlc_stream_Control( p_demux->s, STREAM_CAN_SEEK, &p_sys->b_seekable );
ps_psm_init( &p_sys->psm );
@@ -325,7 +339,7 @@ static int Probe( demux_t *p_demux, bool b_end )
return VLC_DEMUXER_EOF;
}
- i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
+ i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer, p_sys->source );
if( i_id >= 0xc0 )
{
ps_track_t *tk = &p_sys->tk[ps_id_to_tk(i_id)];
@@ -528,7 +542,7 @@ static int Demux( demux_t *p_demux )
case STREAM_ID_PRIVATE_STREAM_1:
case STREAM_ID_EXTENDED_STREAM_ID:
{
- int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer );
+ int i_id = ps_pkt_id( p_pkt->p_buffer, p_pkt->i_buffer, p_sys->source );
/* Small heuristic to improve MLP detection from AOB */
if( i_id == 0xa001 &&
p_sys->i_aob_mlp_count < 500 )
=====================================
modules/demux/mpeg/ps.h
=====================================
@@ -28,6 +28,12 @@
#define PS_STREAM_ID_PACK_HEADER 0xBA
#define PS_STREAM_ID_SYSTEM_HEADER 0xBB
+enum ps_source {
+ PS_SOURCE_UNKNOWN, // any PS/PES source
+ PS_SOURCE_VOB, // when reading a DVD-Video
+ PS_SOURCE_AOB, // when reading a DVD-Audio
+};
+
/* 256-0xC0 for normal stream, 256 for 0xbd stream, 256 for 0xfd stream, 8 for 0xa0 AOB stream */
#define PS_TK_COUNT (256+256+256+8 - 0xc0)
static inline unsigned ps_id_to_tk( unsigned i_id )
@@ -323,7 +329,7 @@ static inline int ps_track_fill( ps_track_t *tk, ps_psm_t *p_psm,
}
/* return the id of a PES (should be valid) */
-static inline int ps_pkt_id( const uint8_t *p_pkt, size_t i_pkt )
+static inline int ps_pkt_id( const uint8_t *p_pkt, size_t i_pkt, enum ps_source source )
{
if(unlikely(i_pkt < 4))
return 0;
@@ -336,14 +342,18 @@ static inline int ps_pkt_id( const uint8_t *p_pkt, size_t i_pkt )
const unsigned i_start = 9 + p_pkt[8];
i_sub_id = p_pkt[i_start];
- if( (i_sub_id & 0xfe) == 0xa0 &&
+ if( i_sub_id == 0xa0 &&
i_pkt >= i_start + 7 &&
- ( p_pkt[i_start + 5] >= 0xc0 ||
- p_pkt[i_start + 6] != 0x80 ) )
+ p_pkt[i_start + 6] != 0x80 )
+ {
+ /* AOB LPCM extension */
+ return 0xa000 | (i_sub_id & 0x01);
+ }
+
+ if( i_sub_id == 0xa1 &&
+ source == PS_SOURCE_AOB )
{
- /* AOB LPCM/MLP extension
- * XXX for MLP I think that the !=0x80 test is not good and
- * will fail for some valid files */
+ /* AOB MLP extension */
return 0xa000 | (i_sub_id & 0x01);
}
}
@@ -520,8 +530,8 @@ static inline int ps_pkt_parse_pes( vlc_object_t *p_object, block_t *p_pes, int
if( i_skip_extra >= 0 )
i_skip += i_skip_extra;
else if( p_pes->i_buffer > i_skip + 3 &&
- ( ps_pkt_id( p_pes->p_buffer, p_pes->i_buffer ) == 0xa001 ||
- ps_pkt_id( p_pes->p_buffer, p_pes->i_buffer ) == 0xbda1 ) )
+ ( ps_pkt_id( p_pes->p_buffer, p_pes->i_buffer, PS_SOURCE_AOB ) == 0xa001 ||
+ ps_pkt_id( p_pes->p_buffer, p_pes->i_buffer, PS_SOURCE_VOB ) == 0xbda1 ) )
i_skip += 4 + p_pes->p_buffer[i_skip+3];
if( p_pes->i_buffer <= i_skip )
=====================================
modules/demux/vobsub.c
=====================================
@@ -652,7 +652,7 @@ static int DemuxVobSub( demux_t *p_demux, block_t *p_bk )
break;
}
- i_id = ps_pkt_id( p, i_size );
+ i_id = ps_pkt_id( p, i_size, PS_SOURCE_VOB );
if( (i_id&0xffe0) != 0xbd20 )
{
/* msg_Dbg( p_demux, "we don't need these ps packets (id=0x1%2.2x)", p[3] ); */
@@ -697,4 +697,3 @@ static int DemuxVobSub( demux_t *p_demux, block_t *p_bk )
return VLC_SUCCESS;
}
-
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c6d6c0c5966023080a4b98a2091fab01f4713f5c...1ae5b0b8d4c67a74d9f98d84aad78b4f38a4cb8c
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/c6d6c0c5966023080a4b98a2091fab01f4713f5c...1ae5b0b8d4c67a74d9f98d84aad78b4f38a4cb8c
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list