Commit 574ccfac authored by Rocky Bernstein's avatar Rocky Bernstein

Ignore timestamp in PACK header in a private stream. This is to get

around a WinSubMux bug in multiplexing CVD and SVCD subtitles.
(Patch probably could be made more precise.)

To do this we've got to save the timestamp in the header.
parent 9d010d54
SOURCES_mpeg_system = system.c system.h SOURCES_mpeg_system = system.c system.h private.h
SOURCES_m4v = m4v.c SOURCES_m4v = m4v.c
SOURCES_ps = ps.c SOURCES_ps = ps.c
SOURCES_ts = ts.c SOURCES_ts = ts.c
......
/*****************************************************************************
* system.c: helper module for TS, PS and PES management
*****************************************************************************
* Copyright (C) 2003 VideoLAN
* $Id: private.h,v 1.1 2004/01/03 17:52:15 rocky Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
*****************************************************************************/
/*****************************************************************************
* Private structure
*****************************************************************************/
struct demux_sys_t
{
module_t * p_module;
mpeg_demux_t mpeg;
/*
rocky:
i_cur_mux_rate and cur_scr_time below are a bit of a hack.
Background: VLC uses the System Clock Reference (SCR) of a PACK
header to read the stream at the right pace (contrary to other
players like xine/mplayer which don't use this info and
synchronise everything on the audio output clock).
The popular SVCD/VCD subtitling WinSubMux does not renumber the
SCRs when merging subtitles into the PES. Perhaps other
multipliexing tools are equally faulty. Until such time as
WinSubMux is fixed or other tools become available and widely
used, we will cater to the WinSubMux kind of buggy stream. The
hack here delays using the PACK SCR until the first PES that
would need it is received. For this we need to temporarily save
this information in the variables below.
*/
uint32_t i_cur_mux_rate;
mtime_t cur_scr_time;
};
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* ps.c : Program Stream input module for vlc * ps.c : Program Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000-2001 VideoLAN
* $Id: ps.c,v 1.13 2003/12/22 14:32:56 sam Exp $ * $Id: ps.c,v 1.14 2004/01/03 17:52:15 rocky Exp $
* *
* Author: Christophe Massiot <massiot@via.ecp.fr> * Author: Christophe Massiot <massiot@via.ecp.fr>
* *
...@@ -36,14 +36,7 @@ ...@@ -36,14 +36,7 @@
*****************************************************************************/ *****************************************************************************/
#define PS_READ_ONCE 50 #define PS_READ_ONCE 50
/***************************************************************************** #include "private.h"
* Private structure
*****************************************************************************/
struct demux_sys_t
{
module_t * p_module;
mpeg_demux_t mpeg;
};
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -263,6 +256,15 @@ static int Activate( vlc_object_t * p_this ) ...@@ -263,6 +256,15 @@ static int Activate( vlc_object_t * p_this )
} }
break; break;
case VLC_FOURCC('o','g','t',' '):
printf("+++ID: %d\n", p_es->i_id & 0003 );
if( config_GetInt( p_input, "spu-channel" )
== (p_es->i_id & 0x0003) )
{
input_SelectES( p_input, p_es );
}
break;
case VLC_FOURCC('l','p','c','m'): case VLC_FOURCC('l','p','c','m'):
case VLC_FOURCC('l','p','c','b'): case VLC_FOURCC('l','p','c','b'):
if( config_GetInt( p_input, "audio-channel" ) if( config_GetInt( p_input, "audio-channel" )
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* system.c: helper module for TS, PS and PES management * system.c: helper module for TS, PS and PES management
***************************************************************************** *****************************************************************************
* Copyright (C) 1998-2002 VideoLAN * Copyright (C) 1998-2002 VideoLAN
* $Id: system.c,v 1.26 2003/12/22 14:32:56 sam Exp $ * $Id: system.c,v 1.27 2004/01/03 17:52:15 rocky Exp $
* *
* Authors: Christophe Massiot <massiot@via.ecp.fr> * Authors: Christophe Massiot <massiot@via.ecp.fr>
* Michel Lespinasse <walken@via.ecp.fr> * Michel Lespinasse <walken@via.ecp.fr>
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <vlc/input.h> #include <vlc/input.h>
#include "system.h" #include "system.h"
#include "private.h"
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
...@@ -54,7 +55,7 @@ static void DemuxTS ( input_thread_t *, data_packet_t *, ...@@ -54,7 +55,7 @@ static void DemuxTS ( input_thread_t *, data_packet_t *,
vlc_module_begin(); vlc_module_begin();
set_description( _("generic ISO 13818-1 MPEG demultiplexing") ); set_description( _("generic ISO 13818-1 MPEG demultiplexing") );
set_capability( "mpeg-system", 100 ); set_capability( "mpeg-system", 100 );
set_callbacks( Activate, NULL ); set_callbacks( Activate, NULL );
vlc_module_end(); vlc_module_end();
/***************************************************************************** /*****************************************************************************
...@@ -62,11 +63,18 @@ vlc_module_end(); ...@@ -62,11 +63,18 @@ vlc_module_end();
*****************************************************************************/ *****************************************************************************/
static int Activate ( vlc_object_t *p_this ) static int Activate ( vlc_object_t *p_this )
{ {
input_thread_t *p_input = (input_thread_t *)p_this;
demux_sys_t *p_sys = p_input->p_demux_data;
static mpeg_demux_t mpeg_demux = static mpeg_demux_t mpeg_demux =
{ NULL, ReadPS, ParsePS, DemuxPS, ReadTS, DemuxTS }; { NULL, ReadPS, ParsePS, DemuxPS, ReadTS, DemuxTS };
memcpy( p_this->p_private, &mpeg_demux, sizeof( mpeg_demux ) ); memcpy( p_this->p_private, &mpeg_demux, sizeof( mpeg_demux ) );
if (!p_sys) return VLC_EGENERIC;
p_sys->cur_scr_time = -1;
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -554,17 +562,22 @@ static void GatherPES( input_thread_t * p_input, data_packet_t * p_data, ...@@ -554,17 +562,22 @@ static void GatherPES( input_thread_t * p_input, data_packet_t * p_data,
/***************************************************************************** /*****************************************************************************
* GetID: Get the ID of a stream * GetID: Get the ID of a stream
*****************************************************************************/ *****************************************************************************/
static uint16_t GetID( data_packet_t * p_data ) static uint16_t GetID( input_thread_t *p_input, data_packet_t * p_data )
{ {
uint16_t i_id; uint16_t i_id;
i_id = p_data->p_demux_start[3]; /* stream_id */ i_id = p_data->p_demux_start[3]; /* stream_id */
if( i_id == 0xBD ) if( i_id == 0xBD )
{ {
demux_sys_t *p_sys = p_input->p_demux_data;
/* FIXME : this is not valid if the header is split in multiple /* FIXME : this is not valid if the header is split in multiple
* packets */ * packets */
/* stream_private_id */ /* stream_private_id */
i_id |= p_data->p_demux_start[ 9 + p_data->p_demux_start[8] ] << 8; i_id |= p_data->p_demux_start[ 9 + p_data->p_demux_start[8] ] << 8;
/* FIXME: See note about cur_scr_time above. */
p_sys->cur_scr_time = -1;
} }
return( i_id ); return( i_id );
} }
...@@ -849,7 +862,7 @@ static es_descriptor_t * ParsePS( input_thread_t * p_input, ...@@ -849,7 +862,7 @@ static es_descriptor_t * ParsePS( input_thread_t * p_input,
unsigned int i_dummy; unsigned int i_dummy;
/* This is a PES packet. Find out if we want it or not. */ /* This is a PES packet. Find out if we want it or not. */
i_id = GetID( p_data ); i_id = GetID( p_input, p_data );
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
if( p_input->stream.pp_programs[0]->b_is_ok ) if( p_input->stream.pp_programs[0]->b_is_ok )
...@@ -970,23 +983,15 @@ static es_descriptor_t * ParsePS( input_thread_t * p_input, ...@@ -970,23 +983,15 @@ static es_descriptor_t * ParsePS( input_thread_t * p_input,
/* SVCD OGT subtitles in stream 0x070 */ /* SVCD OGT subtitles in stream 0x070 */
i_fourcc = VLC_FOURCC('o','g','t', ' '); i_fourcc = VLC_FOURCC('o','g','t', ' ');
i_cat = SPU_ES; i_cat = SPU_ES;
#ifdef FINISHED_DEBUGGING
if( !p_input->stream.b_seekable )
if( config_GetInt( p_input, "spu-channel" )
== ((i_id & 0x0300) >> 8) )
#endif
{
b_auto_spawn = VLC_TRUE; b_auto_spawn = VLC_TRUE;
} }
}
else if( ((i_id >> 8) & 0xFF) <= 0x03 && else if( ((i_id >> 8) & 0xFF) <= 0x03 &&
(i_id & 0x00FF) == 0x00BD ) (i_id & 0x00FF) == 0x00BD )
{ {
/* CVD subtitles (0x00->0x03) */ /* CVD subtitles (0x00->0x03) */
i_fourcc = VLC_FOURCC('c','v','d', ' '); i_fourcc = VLC_FOURCC('c','v','d', ' ');
i_cat = SPU_ES; i_cat = SPU_ES;
msg_Warn( p_input, b_auto_spawn = VLC_TRUE;
"CVD subtitles not implemented yet" );
} }
else else
{ {
...@@ -1020,6 +1025,7 @@ static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -1020,6 +1025,7 @@ static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
uint32_t i_code; uint32_t i_code;
vlc_bool_t b_trash = 0; vlc_bool_t b_trash = 0;
es_descriptor_t * p_es = NULL; es_descriptor_t * p_es = NULL;
demux_sys_t *p_sys = p_input->p_demux_data;
i_code = ((uint32_t)p_data->p_demux_start[0] << 24) i_code = ((uint32_t)p_data->p_demux_start[0] << 24)
| ((uint32_t)p_data->p_demux_start[1] << 16) | ((uint32_t)p_data->p_demux_start[1] << 16)
...@@ -1090,18 +1096,8 @@ static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -1090,18 +1096,8 @@ static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
/* mux_rate */ /* mux_rate */
i_mux_rate = (U32_AT(p_header + 8) & 0x7FFFFE) >> 1; i_mux_rate = (U32_AT(p_header + 8) & 0x7FFFFE) >> 1;
} }
/* Call the pace control. */ p_sys->cur_scr_time = scr_time;
input_ClockManageRef( p_input, p_sys->i_cur_mux_rate = i_mux_rate;
p_input->stream.p_selected_program,
scr_time );
if( i_mux_rate != p_input->stream.i_mux_rate
&& p_input->stream.i_mux_rate )
{
msg_Warn( p_input,
"mux_rate changed, expect cosmetic errors" );
}
p_input->stream.i_mux_rate = i_mux_rate;
b_trash = 1; b_trash = 1;
} }
...@@ -1131,6 +1127,25 @@ static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data ) ...@@ -1131,6 +1127,25 @@ static void DemuxPS( input_thread_t * p_input, data_packet_t * p_data )
{ {
p_es = ParsePS( p_input, p_data ); p_es = ParsePS( p_input, p_data );
/* Call the pace control.
FIXME: see hack note about cur_scr_time above.
*/
if (p_sys->cur_scr_time != -1) {
input_ClockManageRef( p_input,
p_input->stream.p_selected_program,
p_sys->cur_scr_time );
if( p_sys->i_cur_mux_rate != p_input->stream.i_mux_rate
&& p_input->stream.i_mux_rate )
{
msg_Warn( p_input,
"mux_rate changed prev: %ud, cur: %ud;"
" expect cosmetic errors" ,
(unsigned int) p_input->stream.i_mux_rate,
(unsigned int) p_sys->i_cur_mux_rate );
}
p_input->stream.i_mux_rate = p_sys->i_cur_mux_rate;
}
vlc_mutex_lock( &p_input->stream.control.control_lock ); vlc_mutex_lock( &p_input->stream.control.control_lock );
if( p_es != NULL && p_es->p_dec != NULL if( p_es != NULL && p_es->p_dec != NULL
&& (p_es->i_cat != AUDIO_ES || !p_input->stream.control.b_mute) ) && (p_es->i_cat != AUDIO_ES || !p_input->stream.control.b_mute) )
......
/***************************************************************************** /*****************************************************************************
* mpeg_ts.c : Transport Stream input module for vlc * mpeg_ts.c : Transport Stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000-2001 VideoLAN * Copyright (C) 2000, 2001, 2003 VideoLAN
* $Id: ts.c,v 1.42 2003/11/07 21:30:52 massiot Exp $ * $Id: ts.c,v 1.43 2004/01/03 17:52:15 rocky Exp $
* *
* Authors: Henri Fallon <henri@via.ecp.fr> * Authors: Henri Fallon <henri@via.ecp.fr>
* Johan Bilien <jobi@via.ecp.fr> * Johan Bilien <jobi@via.ecp.fr>
...@@ -49,23 +49,13 @@ ...@@ -49,23 +49,13 @@
#include "system.h" #include "system.h"
#include "codecs.h" #include "codecs.h"
#include "private.h"
/***************************************************************************** /*****************************************************************************
* Constants * Constants
*****************************************************************************/ *****************************************************************************/
#define TS_READ_ONCE 200 #define TS_READ_ONCE 200
/*****************************************************************************
* Private structure
*****************************************************************************/
struct demux_sys_t
{
module_t * p_module;
mpeg_demux_t mpeg;
};
#define local_iso639_getlang(p1, p2) \ #define local_iso639_getlang(p1, p2) \
{ \ { \
const iso639_lang_t * p_iso; \ const iso639_lang_t * p_iso; \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment