Commit 1ffe943e authored by Stéphane Borel's avatar Stéphane Borel

-Changes and bugfixes to make network work in VLAN Broadcast mode.

-Bugfix in the interface to access the network specific features.

-Some base of synchro in ac3 spdif
parent 6854d3f1
......@@ -2,7 +2,7 @@
* audio_output.h : audio output thread interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: audio_output.h,v 1.35 2001/05/06 18:32:30 stef Exp $
* $Id: audio_output.h,v 1.36 2001/05/30 05:19:03 stef Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
*
......@@ -194,6 +194,9 @@ typedef struct aout_thread_s
#define AOUT_FMT_S16_NE AOUT_FMT_S16_LE
#endif
/* Number of samples in an AC3 frame */
#define AC3_FRAME_SIZE 1536
/* Size of a frame for spdif output */
#define SPDIF_FRAME_SIZE 6144
......
......@@ -181,20 +181,24 @@
/* Default remote server */
#define INPUT_SERVER_VAR "vlc_server"
#define INPUT_SERVER_DEFAULT "138.195.143.220"
#define INPUT_SERVER_DEFAULT "138.195.143.224"
/* Default input port */
#define INPUT_PORT_VAR "vlc_server_port"
#define INPUT_PORT_DEFAULT 1234
/* Default broadcast address */
#define INPUT_BCAST_ADRR_VAR "vlc_broadcast_addr"
#define INPUT_BCAST_ADDR_VAR "vlc_broadcast_addr"
#define INPUT_BCAST_ADDR_DEFAULT "138.195.143.255"
/* Broadcast mode */
#define INPUT_BROADCAST_VAR "vlc_broadcast"
#define INPUT_BROADCAST_DEFAULT 0
/* Channels mode */
#define INPUT_NETWORK_CHANNEL_VAR "vlc_channel"
#define INPUT_NETWORK_CHANNEL_DEFAULT 0
/*
* Channel method
*/
......@@ -205,7 +209,7 @@
/* Default server and port */
#define INPUT_CHANNEL_SERVER_VAR "vlc_channel_server"
#define INPUT_CHANNEL_SERVER_DEFAULT "138.195.139.95"
#define INPUT_CHANNEL_SERVER_DEFAULT "138.195.143.220"
#define INPUT_CHANNEL_PORT_VAR "vlc_channel_port"
#define INPUT_CHANNEL_PORT_DEFAULT 6010
......
......@@ -259,3 +259,5 @@ GnomePopupJumpActivate (GtkMenuItem *menuitem,
{
GtkJumpShow( GTK_WIDGET( menuitem ), NULL, "intf_popup" );
}
......@@ -125,3 +125,11 @@ GnomePlaylistNetworkOpenActivate (GtkMenuItem *menuitem,
void
GnomePopupJumpActivate (GtkMenuItem *menuitem,
gpointer user_data);
void
GtkNetworkJoin (GtkEditable *editable,
gpointer user_data);
void
GtkChannelGo (GtkButton *button,
gpointer user_data);
......@@ -178,8 +178,9 @@ create_intf_window (void)
GtkWidget *network_address_label;
GtkWidget *network_channel_box;
GtkWidget *label_network;
GtkObject *network_spinbutton_adj;
GtkWidget *network_spinbutton;
GtkObject *network_channel_spinbutton_adj;
GtkWidget *network_channel_spinbutton;
GtkWidget *network_channel_go_button;
GtkWidget *appbar;
GtkTooltips *tooltips;
......@@ -634,6 +635,7 @@ create_intf_window (void)
gtk_widget_ref (network_channel_box);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "network_channel_box", network_channel_box,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (network_channel_box);
gtk_box_pack_start (GTK_BOX (network_box), network_channel_box, FALSE, FALSE, 0);
label_network = gtk_label_new (_("Network Channel:"));
......@@ -643,14 +645,21 @@ create_intf_window (void)
gtk_widget_show (label_network);
gtk_box_pack_start (GTK_BOX (network_channel_box), label_network, TRUE, FALSE, 5);
network_spinbutton_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
network_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (network_spinbutton_adj), 1, 0);
gtk_widget_ref (network_spinbutton);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "network_spinbutton", network_spinbutton,
network_channel_spinbutton_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
network_channel_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (network_channel_spinbutton_adj), 1, 0);
gtk_widget_ref (network_channel_spinbutton);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "network_channel_spinbutton", network_channel_spinbutton,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (network_spinbutton);
gtk_box_pack_start (GTK_BOX (network_channel_box), network_spinbutton, FALSE, TRUE, 5);
gtk_widget_set_sensitive (network_spinbutton, FALSE);
gtk_widget_show (network_channel_spinbutton);
gtk_box_pack_start (GTK_BOX (network_channel_box), network_channel_spinbutton, FALSE, TRUE, 5);
network_channel_go_button = gtk_button_new_with_label (_("Go!"));
gtk_widget_ref (network_channel_go_button);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "network_channel_go_button", network_channel_go_button,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (network_channel_go_button);
gtk_box_pack_start (GTK_BOX (network_channel_box), network_channel_go_button, FALSE, FALSE, 0);
gtk_button_set_relief (GTK_BUTTON (network_channel_go_button), GTK_RELIEF_NONE);
appbar = gnome_appbar_new (FALSE, TRUE, GNOME_PREFERENCES_NEVER);
gtk_widget_ref (appbar);
......@@ -721,6 +730,12 @@ create_intf_window (void)
gtk_signal_connect (GTK_OBJECT (button_chapter_next), "clicked",
GTK_SIGNAL_FUNC (GtkChapterNext),
"intf_window");
gtk_signal_connect (GTK_OBJECT (network_channel_spinbutton), "activate",
GTK_SIGNAL_FUNC (GtkNetworkJoin),
"intf_window");
gtk_signal_connect (GTK_OBJECT (network_channel_go_button), "clicked",
GTK_SIGNAL_FUNC (GtkChannelGo),
"intf_window");
gtk_object_set_data (GTK_OBJECT (intf_window), "tooltips", tooltips);
......@@ -1497,6 +1512,7 @@ create_intf_network (void)
gtk_table_attach (GTK_TABLE (table2), broadcast_check, 0, 1, 2, 3,
(GtkAttachOptions) (GTK_FILL),
(GtkAttachOptions) (0), 0, 0);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (broadcast_check), TRUE);
network_broadcast_combo = gnome_entry_new (NULL);
gtk_widget_ref (network_broadcast_combo);
......@@ -1513,6 +1529,7 @@ create_intf_network (void)
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (network_broadcast);
gtk_widget_set_sensitive (network_broadcast, FALSE);
gtk_entry_set_text (GTK_ENTRY (network_broadcast), _("138.195.143.255"));
network_server_combo = gnome_entry_new (NULL);
gtk_widget_ref (network_server_combo);
......@@ -1528,7 +1545,7 @@ create_intf_network (void)
gtk_object_set_data_full (GTK_OBJECT (intf_network), "network_server", network_server,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (network_server);
gtk_entry_set_text (GTK_ENTRY (network_server), _("vls"));
gtk_entry_set_text (GTK_ENTRY (network_server), _("vlsppc-02"));
hbuttonbox1 = GNOME_DIALOG (intf_network)->action_area;
gtk_object_set_data (GTK_OBJECT (intf_network), "hbuttonbox1", hbuttonbox1);
......
......@@ -2,7 +2,7 @@
* gtk_callbacks.c : Callbacks for the Gtk+ plugin.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_callbacks.c,v 1.20 2001/05/23 23:08:20 stef Exp $
* $Id: gtk_callbacks.c,v 1.21 2001/05/30 05:19:03 stef Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr>
......@@ -54,6 +54,7 @@
#include "intf_gtk.h"
#include "main.h"
#include "netutils.h"
/*****************************************************************************
* Callbacks
......@@ -271,6 +272,36 @@ void GtkChapterNext( GtkButton * button, gpointer user_data )
}
}
/****************************************************************************
* Network specific items
****************************************************************************/
void GtkNetworkJoin( GtkEditable * editable, gpointer user_data )
{
int i_channel;
i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( editable ) );
intf_WarnMsg( 3, "intf info: joining channel %d", i_channel );
// network_ChannelJoin( i_channel );
}
void GtkChannelGo( GtkButton * button, gpointer user_data )
{
GtkWidget * window;
GtkWidget * spin;
int i_channel;
window = gtk_widget_get_toplevel( GTK_WIDGET (button) );
spin = GTK_WIDGET( gtk_object_get_data( GTK_OBJECT( window ),
"network_channel_spinbutton" ) );
i_channel = gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON( spin ) );
intf_WarnMsg( 3, "intf info: joining channel %d", i_channel );
network_ChannelJoin( i_channel );
}
/****************************************************************************
* About box
****************************************************************************/
......@@ -401,3 +432,4 @@ void GtkJumpActivate( GtkMenuItem * menuitem, gpointer user_data )
{
GtkJumpShow( GTK_WIDGET( menuitem ), NULL, user_data );
}
......@@ -2,7 +2,7 @@
* gtk_callbacks.h : Callbacks for the gtk plugin.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_callbacks.h,v 1.13 2001/05/23 23:08:20 stef Exp $
* $Id: gtk_callbacks.h,v 1.14 2001/05/30 05:19:03 stef Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr>
......@@ -65,3 +65,6 @@ void GtkWindowToggleActivate( GtkMenuItem *, gpointer );
void GtkFullscreenActivate ( GtkMenuItem *, gpointer );
void GtkAboutActivate ( GtkMenuItem *, gpointer );
void GtkJumpActivate ( GtkMenuItem *, gpointer );
void GtkNetworkJoin ( GtkEditable *, gpointer );
void GtkChannelGo ( GtkButton *, gpointer );
......@@ -2,7 +2,7 @@
* gtk_display.c: Gtk+ tools for main interface
*****************************************************************************
* Copyright (C) 1999, 2000 VideoLAN
* $Id: gtk_display.c,v 1.1 2001/05/23 23:08:20 stef Exp $
* $Id: gtk_display.c,v 1.2 2001/05/30 05:19:03 stef Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr>
......@@ -130,6 +130,7 @@ gint GtkModeManage( intf_thread_t * p_intf )
switch( p_intf->p_input->stream.i_method & 0xf0 )
{
case INPUT_METHOD_FILE:
//intf_WarnMsg( 2, "intf info: file method" );
gtk_widget_show( GTK_WIDGET( p_file_box ) );
p_label = gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ),
......@@ -138,9 +139,11 @@ gint GtkModeManage( intf_thread_t * p_intf )
p_intf->p_input->p_source );
break;
case INPUT_METHOD_DISC:
//intf_WarnMsg( 2, "intf info: disc method" );
gtk_widget_show( GTK_WIDGET( p_dvd_box ) );
break;
case INPUT_METHOD_NETWORK:
//intf_WarnMsg( 2, "intf info: network method" );
gtk_widget_show( GTK_WIDGET( p_network_box ) );
p_label = gtk_object_get_data( GTK_OBJECT(
p_intf->p_sys->p_window ),
......@@ -176,6 +179,7 @@ gint GtkModeManage( intf_thread_t * p_intf )
}
else
{
//intf_WarnMsg( 2, "intf info: default to file method" );
/* default mode */
p_label = gtk_object_get_data( GTK_OBJECT( p_intf->p_sys->p_window ),
"label_status" );
......
......@@ -92,8 +92,9 @@ create_intf_window (void)
GtkWidget *network_address;
GtkWidget *network_channel_box;
GtkWidget *channel_label;
GtkObject *channel_spinbutton_adj;
GtkWidget *channel_spinbutton;
GtkObject *network_channel_spinbutton_adj;
GtkWidget *network_channel_spinbutton;
GtkWidget *network_channel_go_button;
GtkWidget *intf_statusbar;
GtkAccelGroup *accel_group;
GtkTooltips *tooltips;
......@@ -741,13 +742,21 @@ create_intf_window (void)
gtk_widget_show (channel_label);
gtk_box_pack_start (GTK_BOX (network_channel_box), channel_label, FALSE, FALSE, 5);
channel_spinbutton_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
channel_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (channel_spinbutton_adj), 1, 0);
gtk_widget_ref (channel_spinbutton);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "channel_spinbutton", channel_spinbutton,
network_channel_spinbutton_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
network_channel_spinbutton = gtk_spin_button_new (GTK_ADJUSTMENT (network_channel_spinbutton_adj), 1, 0);
gtk_widget_ref (network_channel_spinbutton);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "network_channel_spinbutton", network_channel_spinbutton,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (channel_spinbutton);
gtk_box_pack_start (GTK_BOX (network_channel_box), channel_spinbutton, FALSE, TRUE, 0);
gtk_widget_show (network_channel_spinbutton);
gtk_box_pack_start (GTK_BOX (network_channel_box), network_channel_spinbutton, FALSE, TRUE, 0);
network_channel_go_button = gtk_button_new_with_label (_("Go!"));
gtk_widget_ref (network_channel_go_button);
gtk_object_set_data_full (GTK_OBJECT (intf_window), "network_channel_go_button", network_channel_go_button,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (network_channel_go_button);
gtk_box_pack_start (GTK_BOX (network_channel_box), network_channel_go_button, FALSE, FALSE, 0);
gtk_button_set_relief (GTK_BUTTON (network_channel_go_button), GTK_RELIEF_NONE);
intf_statusbar = gtk_statusbar_new ();
gtk_widget_ref (intf_statusbar);
......@@ -847,6 +856,12 @@ create_intf_window (void)
gtk_signal_connect (GTK_OBJECT (chapter_next_button), "clicked",
GTK_SIGNAL_FUNC (GtkChapterNext),
"intf_window");
gtk_signal_connect (GTK_OBJECT (network_channel_spinbutton), "activate",
GTK_SIGNAL_FUNC (GtkNetworkJoin),
"intf_window");
gtk_signal_connect (GTK_OBJECT (network_channel_go_button), "clicked",
GTK_SIGNAL_FUNC (GtkChannelGo),
"intf_window");
gtk_object_set_data (GTK_OBJECT (intf_window), "tooltips", tooltips);
......
......@@ -2,7 +2,7 @@
* gtk_control.c : functions to handle stream control buttons.
*****************************************************************************
* Copyright (C) 2000, 2001 VideoLAN
* $Id: gtk_preferences.c,v 1.3 2001/05/23 23:08:20 stef Exp $
* $Id: gtk_preferences.c,v 1.4 2001/05/30 05:19:03 stef Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
* Stphane Borel <stef@via.ecp.fr>
......@@ -108,7 +108,7 @@ gboolean GtkPreferencesShow( GtkWidget *widget,
"preferences_network_port_spinbutton" );
/* Broadcast address */
ASSIGN_PSZ_ENTRY( INPUT_BCAST_ADRR_VAR, INPUT_BCAST_ADDR_DEFAULT,
ASSIGN_PSZ_ENTRY( INPUT_BCAST_ADDR_VAR, INPUT_BCAST_ADDR_DEFAULT,
"preferences_network_broadcast_entry" );
/* Broadcast stream by default ? */
......@@ -233,7 +233,7 @@ void GtkPreferencesApply( GtkButton * button, gpointer user_data )
ASSIGN_INT_VALUE( INPUT_PORT_VAR, "preferences_network_port_spinbutton" );
/* Broadcast address */
ASSIGN_PSZ_ENTRY( INPUT_BCAST_ADRR_VAR,
ASSIGN_PSZ_ENTRY( INPUT_BCAST_ADDR_VAR,
"preferences_network_broadcast_entry" );
/* Broadcast stream by default ? */
......
......@@ -869,7 +869,6 @@
<widget>
<class>GtkHBox</class>
<name>network_channel_box</name>
<visible>False</visible>
<homogeneous>False</homogeneous>
<spacing>0</spacing>
<child>
......@@ -897,9 +896,14 @@
<widget>
<class>GtkSpinButton</class>
<name>network_spinbutton</name>
<sensitive>False</sensitive>
<name>network_channel_spinbutton</name>
<can_focus>True</can_focus>
<signal>
<name>activate</name>
<handler>GtkNetworkJoin</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Wed, 30 May 2001 02:28:48 GMT</last_modification_time>
</signal>
<climb_rate>1</climb_rate>
<digits>0</digits>
<numeric>False</numeric>
......@@ -918,6 +922,25 @@
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkButton</class>
<name>network_channel_go_button</name>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>GtkChannelGo</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Wed, 30 May 2001 02:38:25 GMT</last_modification_time>
</signal>
<label>Go!</label>
<relief>GTK_RELIEF_NONE</relief>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
</widget>
......@@ -2026,7 +2049,7 @@ Henri Fallon &lt;henri@via.ecp.fr&gt;
<last_modification_time>Sat, 19 May 2001 02:57:46 GMT</last_modification_time>
</signal>
<label>Broadcast</label>
<active>False</active>
<active>True</active>
<draw_indicator>True</draw_indicator>
<child>
<left_attach>0</left_attach>
......@@ -2072,7 +2095,7 @@ Henri Fallon &lt;henri@via.ecp.fr&gt;
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text></text>
<text>138.195.143.255</text>
</widget>
</widget>
......@@ -2103,7 +2126,7 @@ Henri Fallon &lt;henri@via.ecp.fr&gt;
<editable>True</editable>
<text_visible>True</text_visible>
<text_max_length>0</text_max_length>
<text>vls</text>
<text>vlsppc-02</text>
</widget>
</widget>
</widget>
......
......@@ -894,8 +894,14 @@
<widget>
<class>GtkSpinButton</class>
<name>channel_spinbutton</name>
<name>network_channel_spinbutton</name>
<can_focus>True</can_focus>
<signal>
<name>activate</name>
<handler>GtkNetworkJoin</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Wed, 30 May 2001 02:48:10 GMT</last_modification_time>
</signal>
<climb_rate>1</climb_rate>
<digits>0</digits>
<numeric>False</numeric>
......@@ -914,6 +920,25 @@
<fill>True</fill>
</child>
</widget>
<widget>
<class>GtkButton</class>
<name>network_channel_go_button</name>
<can_focus>True</can_focus>
<signal>
<name>clicked</name>
<handler>GtkChannelGo</handler>
<data>&quot;intf_window&quot;</data>
<last_modification_time>Wed, 30 May 2001 02:49:18 GMT</last_modification_time>
</signal>
<label>Go!</label>
<relief>GTK_RELIEF_NONE</relief>
<child>
<padding>0</padding>
<expand>False</expand>
<fill>False</fill>
</child>
</widget>
</widget>
</widget>
......
......@@ -2,7 +2,7 @@
* ac3_spdif.c: ac3 pass-through to external decoder with enabled soundcard
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: ac3_spdif.c,v 1.5 2001/05/07 03:14:09 stef Exp $
* $Id: ac3_spdif.c,v 1.6 2001/05/30 05:19:03 stef Exp $
*
* Authors: Stphane Borel <stef@via.ecp.fr>
* Juha Yrjola <jyrjola@cc.hut.fi>
......@@ -80,7 +80,7 @@ vlc_thread_t spdif_CreateThread( adec_config_t * p_config )
}
/* Temporary buffer to store ac3 frames to be transformed */
p_spdif->p_ac3 = malloc( /*ac3_info.i_frame_size*/SPDIF_FRAME_SIZE );
p_spdif->p_ac3 = malloc( SPDIF_FRAME_SIZE );
if( p_spdif->p_ac3 == NULL )
{
......@@ -126,7 +126,7 @@ static int InitThread( ac3_spdif_thread_t * p_spdif )
BitstreamCallback, (void*)p_spdif );
/* Creating the audio output fifo */
p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_SPDIF_FIFO, 1, 0, 0,
p_spdif->p_aout_fifo = aout_CreateFifo( AOUT_ADEC_SPDIF_FIFO, 1, 48000, 0,
SPDIF_FRAME_SIZE, NULL );
if( p_spdif->p_aout_fifo == NULL )
......@@ -146,7 +146,10 @@ static int InitThread( ac3_spdif_thread_t * p_spdif )
return -1;
}
/* Check that we can handle the rate */
/* Check that we can handle the rate
* FIXME: we should check that we have the same rate for all fifos
* but all rates should be supported by the decoder (32, 44.1, 48) */
if( p_spdif->ac3_info.i_sample_rate != 48000 )
{
intf_ErrMsg( "spdif error: Only 48000 Hz streams supported");
......@@ -154,6 +157,7 @@ static int InitThread( ac3_spdif_thread_t * p_spdif )
aout_DestroyFifo( p_spdif->p_aout_fifo );
return -1;
}
p_spdif->p_aout_fifo->l_rate = p_spdif->ac3_info.i_sample_rate;
GetChunk( &p_spdif->bit_stream, p_spdif->p_ac3 + sizeof(sync_frame_t),
p_spdif->ac3_info.i_frame_size - sizeof(sync_frame_t) );
......@@ -167,27 +171,38 @@ static int InitThread( ac3_spdif_thread_t * p_spdif )
****************************************************************************/
static void RunThread( ac3_spdif_thread_t * p_spdif )
{
mtime_t m_last_pts = 0;
mtime_t m_frame_time;
/* Initializing the spdif decoder thread */
if( InitThread( p_spdif ) )
{
p_spdif->p_fifo->b_error = 1;
}
/* Compute the theorical duration of an ac3 frame */
m_frame_time = 1000000 * AC3_FRAME_SIZE /
p_spdif->ac3_info.i_sample_rate;
while( !p_spdif->p_fifo->b_die && !p_spdif->p_fifo->b_error )
{
/* Handle the dates */
if(DECODER_FIFO_START(*p_spdif->p_fifo)->i_pts)
{
p_spdif->p_aout_fifo->date[p_spdif->p_aout_fifo->l_end_frame] =
DECODER_FIFO_START(*p_spdif->p_fifo)->i_pts;
m_last_pts = DECODER_FIFO_START(*p_spdif->p_fifo)->i_pts;
DECODER_FIFO_START(*p_spdif->p_fifo)->i_pts = 0;
}
else
{
p_spdif->p_aout_fifo->date[p_spdif->p_aout_fifo->l_end_frame] =
LAST_MDATE;
m_last_pts += m_frame_time;
}
/* if we're late here the output won't have to play the frame */
if( m_last_pts > mdate() )
{
p_spdif->p_aout_fifo->date[p_spdif->p_aout_fifo->l_end_frame] =
m_last_pts;
/* Write in the first free packet of aout fifo */
p_spdif->p_iec = (p_spdif->p_aout_fifo->buffer) +
(p_spdif->p_aout_fifo->l_end_frame * SPDIF_FRAME_SIZE );
......@@ -199,6 +214,7 @@ static void RunThread( ac3_spdif_thread_t * p_spdif )
p_spdif->p_aout_fifo->l_end_frame =
(p_spdif->p_aout_fifo->l_end_frame + 1 ) & AOUT_FIFO_SIZE;
vlc_mutex_unlock (&p_spdif->p_aout_fifo->data_lock);
}
/* Find syncword again in case of stream discontinuity */
while( ShowBits( &p_spdif->bit_stream, 16 ) != 0xb77 )
......
......@@ -2,7 +2,7 @@
* aout_spdif: ac3 passthrough output
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: aout_spdif.c,v 1.6 2001/05/19 00:39:30 stef Exp $
* $Id: aout_spdif.c,v 1.7 2001/05/30 05:19:03 stef Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
* Stphane Borel <stef@via.ecp.fr>
......@@ -41,7 +41,7 @@
#include "audio_output.h"
#include "aout_common.h"
#define BLANK_FRAME_MAX 1000
#define BLANK_FRAME_MAX 100
/*****************************************************************************
* aout_SpdifThread: audio output thread that sends raw spdif data
......@@ -60,6 +60,10 @@ void aout_SpdifThread( aout_thread_t * p_aout )
int i_fifo;
int i_frame;
int i_blank;
mtime_t mplay;
mtime_t mdelta;
mtime_t mlast = 0;
mtime_t m_frame_time;
/* get a blank frame ready */
memset( pi_blank, 0, sizeof(pi_blank) );
......@@ -71,17 +75,16 @@ void aout_SpdifThread( aout_thread_t * p_aout )
* last significant frame */
i_blank = 0;
/* Compute the theorical duration of an ac3 frame */
m_frame_time = 1000000 * AC3_FRAME_SIZE / p_aout->fifo[0].l_rate;
while( !p_aout->b_die )
{
/* we leave some time for aout fifo to fill and not to stress
* the external decoder too much */
msleep( 10000 );
/* variable to check that we send data to the decoder
* once per loop at least */
i_frame = 0;
/* FIXME: find a way to hnadle the locks here */
/* FIXME: find a way to handle the locks here */
for( i_fifo = 0 ; i_fifo < AOUT_MAX_FIFOS ; i_fifo++ )
{
/* the loop read each fifo so that we can change the stream
......@@ -98,9 +101,18 @@ void aout_SpdifThread( aout_thread_t * p_aout )
}
else if( !AOUT_FIFO_ISEMPTY( p_aout->fifo[i_fifo] ) )
{
// vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
//fprintf(stderr, "delay %lld\n",p_aout->fifo[i_fifo].date[p_aout->fifo[i_fifo].l_start_frame] -mdate() );
mplay = p_aout->fifo[i_fifo].date[p_aout->fifo[i_fifo].
l_start_frame];
mdelta = mplay - mdate();
if( mdelta < ( 2 * m_frame_time ) )
{
intf_WarnMsg( 12, "spdif out (%d):"
"playing frame %lld (%lld)",
i_fifo,
mdelta,
mplay-mlast );
mlast = mplay;
/* play spdif frame to the external decoder */
p_aout->pf_play( p_aout,
p_aout->fifo[i_fifo].buffer +
......@@ -108,26 +120,34 @@ void aout_SpdifThread( aout_thread_t * p_aout )
SPDIF_FRAME_SIZE,
p_aout->fifo[i_fifo].l_frame_size );
// vlc_mutex_lock( &p_aout->fifo[i_fifo].data_lock );
p_aout->fifo[i_fifo].l_start_frame =
(p_aout->fifo[i_fifo].l_start_frame + 1 )
& AOUT_FIFO_SIZE;
vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
i_frame++;
i_blank = 0;
}
vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
}
else
{
vlc_mutex_unlock( &p_aout->fifo[i_fifo].data_lock );
}
}
}
if( !i_frame )
if( i_frame )
{
/* we leave some time for aout fifo to fill and not to stress
* the external decoder too much */
msleep( m_frame_time / 2 );
}
else
{
/* insert blank frame for stream continuity to
* the external decoder */
p_aout->pf_play( p_aout, pi_blank, SPDIF_FRAME_SIZE );
intf_WarnMsg( 6, "spdif warning: blank frame" );
p_aout->pf_play( p_aout, pi_blank, SPDIF_FRAME_SIZE/4 );
/* we kill the output if we don't have any stream */
if( ++i_blank > BLANK_FRAME_MAX )
......@@ -138,6 +158,14 @@ void aout_SpdifThread( aout_thread_t * p_aout )
}
intf_WarnMsg( 3, "aout info: exiting spdif loop" );
vlc_mutex_lock( &p_aout->fifos_lock );
for ( i_fifo = 0; i_fifo < AOUT_MAX_FIFOS; i_fifo++ )
{
aout_FreeFifo( &p_aout->fifo[i_fifo] );
}
vlc_mutex_unlock( &p_aout->fifos_lock );
return;
}
......
......@@ -2,7 +2,7 @@
* audio_output.c : audio output thread
*****************************************************************************
* Copyright (C) 1999, 2000, 2001 VideoLAN
* $Id: audio_output.c,v 1.61 2001/05/25 04:23:37 sam Exp $
* $Id: audio_output.c,v 1.62 2001/05/30 05:19:03 stef Exp $
*
* Authors: Michel Kaempf <maxx@via.ecp.fr>
*
......@@ -150,7 +150,6 @@ aout_thread_t *aout_CreateThread( int *pi_status )
if( main_GetIntVariable( AOUT_SPDIF_VAR, 0 ) )
{
p_aout->i_format = AOUT_FMT_AC3;
p_aout->i_channels = 1;
p_aout->l_rate = 48000;
}
......@@ -246,12 +245,6 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
pf_aout_thread = aout_S16MonoThread;
break;
case AOUT_FMT_AC3:
intf_WarnMsg( 2, "aout info: ac3 pass-through thread" );
l_bytes = 0;
pf_aout_thread = aout_SpdifThread;
break;
default:
intf_ErrMsg( "aout error: unknown audio output format (%i)",
p_aout->i_format );
......@@ -288,6 +281,13 @@ static int aout_SpawnThread( aout_thread_t * p_aout )
l_bytes = 2 * sizeof(s16) * p_aout->l_units;
pf_aout_thread = aout_S16StereoThread;
break;
case AOUT_FMT_AC3:
intf_WarnMsg( 2, "aout info: ac3 pass-through thread" );
l_bytes = SPDIF_FRAME_SIZE;
pf_aout_thread = aout_SpdifThread;
break;
default:
intf_ErrMsg( "aout error: unknown audio output format %i",
p_aout->i_format );
......
......@@ -4,7 +4,7 @@
* decoders.
*****************************************************************************
* Copyright (C) 1998, 1999, 2000 VideoLAN