* modules/demux/dts.c: implemented DEMUX_GET_TIME and DEMUX_GET_LENGTH.
* modules/access/cdda.c: got rid of the cdda demux and add a wav header at the beginning of the data.
This allows to correctly support DTS audio cd (demux will detect what kind of CD it is).
* modules/demux/wav.c: code cleanup and fixed seeking.
dnl Autoconf settings for vlc
-dnl $Id: configure.ac,v 1.169 2004/02/03 12:49:53 sigmunau Exp $
+dnl $Id: configure.ac,v 1.170 2004/02/05 22:56:12 gbazin Exp $
AC_INIT(vlc,0.7.1-cvs)
if test "${SYS}" != "mingw32"; then
AC_TYPE_SIGNAL
AC_CHECK_LIB(m,cos,[
- AX_ADD_LDFLAGS([adjust distort a52tofloat32],[-lm])
+ AX_ADD_LDFLAGS([adjust distort a52tofloat32 dtstofloat32],[-lm])
])
AC_CHECK_LIB(m,pow,[
AX_ADD_LDFLAGS([ffmpeg stream_out_transcode stream_out_transrate i420_rgb faad vlc],[-lm])
dnl
-dnl a52 AC3 decoder plugin
+dnl A52/AC3 decoder plugin
dnl
AC_ARG_ENABLE(a52,
[ --enable-a52 A/52 support with liba52 (default enabled)])
fi
fi
+dnl
+dnl DTS Coherent Acoustics decoder plugin
+dnl
+AC_ARG_ENABLE(dts,
+ [ --enable-dts DTS Coherent Acoustics support with libdts (default enabled)])
+if test "${enable_dts}" != "no"; then
+ AC_ARG_WITH(dts-tree,
+ [ --with-dts-tree=PATH dtsdec tree for static linking ],[],[])
+ if test "${with_dts_tree}" != "no" -a -n "${with_dts_tree}"
+ then
+ real_dts_tree="`cd ${with_dts_tree} 2>/dev/null && pwd`"
+ if test -z "${real_dts_tree}"
+ then
+ dnl The given directory can't be found
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([${with_dts_tree} directory doesn't exist])
+ fi
+ dnl Use a custom dtsdec
+ AC_MSG_CHECKING(for dts.h in ${real_dts_tree}/include)
+ if test -f ${real_dts_tree}/include/dts.h
+ then
+ AC_MSG_RESULT(yes)
+ AX_ADD_CPPFLAGS([dtstofloat32],[-I${real_dts_tree}])
+ AX_ADD_LDFLAGS([dtstofloat32],[-L${real_dts_tree}/libdts/.libs])
+ LDFLAGS="${LDFLAGS_save} ${LDFLAGS_dtstofloat32}"
+ AC_CHECK_LIB(dts, dts_free, [
+ AX_ADD_BUILTINS([dtstofloat32])
+ AX_ADD_CPPFLAGS([dtstofloat32],[-DUSE_DTSDEC_TREE])
+ AX_ADD_LDFLAGS([dtstofloat32],[-ldts])
+ ],[
+ if test -f ${real_dts_tree}/libdts/.libs/libdts.a
+ then
+ AC_MSG_ERROR([make sure you have at least dtsdec-0.1.0])
+ else
+ AC_MSG_ERROR([the specified tree hasn't been compiled])
+ fi
+ ])
+ LDFLAGS="${LDFLAGS_save}"
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR([the specified tree doesn't have dts.h])
+ fi
+ else
+ AC_CHECK_HEADERS(dtsdec/dts.h, [
+ AC_CHECK_LIB(dts, dts_free, [
+ AX_ADD_PLUGINS([dtstofloat32])
+ AX_ADD_LDFLAGS([dtstofloat32],[-ldts])
+ ],[
+ if test "${enable_dts}" = "yes"; then
+ AC_MSG_ERROR([Could not find libdts on your system: you may get it from http://www.videolan.org/dtsdec.])
+ fi
+ ])
+ ])
+ fi
+fi
+
dnl dnl
dnl dnl DV plugin
dnl dnl
* cdda.c : CD digital audio input module for vlc
*****************************************************************************
* Copyright (C) 2000, 2003 VideoLAN
- * $Id: cdda.c,v 1.12 2004/01/25 17:31:22 gbazin Exp $
+ * $Id: cdda.c,v 1.13 2004/02/05 22:56:12 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com>
#include "vcd/cdrom.h"
+typedef struct WAVEHEADER
+{
+ uint32_t MainChunkID; // it will be 'RIFF'
+ uint32_t Length;
+ uint32_t ChunkTypeID; // it will be 'WAVE'
+ uint32_t SubChunkID; // it will be 'fmt '
+ uint32_t SubChunkLength;
+ uint16_t Format;
+ uint16_t Modus;
+ uint32_t SampleFreq;
+ uint32_t BytesPerSec;
+ uint16_t BytesPerSample;
+ uint16_t BitsPerSample;
+ uint32_t DataChunkID; // it will be 'data'
+ uint32_t DataLength;
+} WAVEHEADER;
+
/*****************************************************************************
* Module descriptior
*****************************************************************************/
static int AccessOpen ( vlc_object_t * );
static void AccessClose( vlc_object_t * );
-static int DemuxOpen ( vlc_object_t * );
-static void DemuxClose ( vlc_object_t * );
-
#define CACHING_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \
"Allows you to modify the default caching value for cdda streams. This " \
set_capability( "access", 70 );
set_callbacks( AccessOpen, AccessClose );
add_shortcut( "cdda" );
-
- add_submodule();
- set_description( _("Audio CD demux") );
- set_capability( "demux", 0 );
- set_callbacks( DemuxOpen, DemuxClose );
- add_shortcut( "cdda" );
vlc_module_end();
int * p_sectors; /* Track sectors */
vlc_bool_t b_end_of_track; /* If the end of track was reached */
+ WAVEHEADER waveheader; /* Wave header for the output data */
+ int i_header_pos;
};
static int Read ( input_thread_t *, byte_t *, size_t );
msg_Err( p_input, "no audio tracks found" );
}
- if( p_sys->i_nb_tracks <= 1)
+ if( p_sys->i_nb_tracks <= 0 )
{
ioctl_Close( p_this, p_sys->vcddev );
free( p_sys );
vlc_mutex_unlock( &p_input->stream.stream_lock );
- if( !p_input->psz_demux || !*p_input->psz_demux )
- {
- p_input->psz_demux = "cdda";
- }
-
p_input->pf_read = Read;
p_input->pf_seek = Seek;
p_input->pf_set_area = SetArea;
/* Update default_pts to a suitable value for cdda access */
p_input->i_pts_delay = config_GetInt( p_input, "cdda-caching" ) * 1000;
+ /* Build a WAV header for the output data */
+ memset( &p_sys->waveheader, 0, sizeof(WAVEHEADER) );
+ p_sys->waveheader.Format = 1 /*WAVE_FORMAT_PCM*/;
+ p_sys->waveheader.BitsPerSample = 16;
+ p_sys->waveheader.MainChunkID = VLC_FOURCC('R', 'I', 'F', 'F');
+ p_sys->waveheader.Length = 0; /* we just don't know */
+ p_sys->waveheader.ChunkTypeID = VLC_FOURCC('W', 'A', 'V', 'E');
+ p_sys->waveheader.SubChunkID = VLC_FOURCC('f', 'm', 't', ' ');
+ p_sys->waveheader.SubChunkLength = 16;
+ p_sys->waveheader.Modus = 2;
+ p_sys->waveheader.SampleFreq = 44100;
+ p_sys->waveheader.BytesPerSample =
+ p_sys->waveheader.Modus * p_sys->waveheader.BitsPerSample / 8;
+ p_sys->waveheader.BytesPerSec =
+ p_sys->waveheader.BytesPerSample * p_sys->waveheader.SampleFreq;
+ p_sys->waveheader.DataChunkID = VLC_FOURCC('d', 'a', 't', 'a');
+ p_sys->waveheader.DataLength = 0; /* we just don't know */
+ p_sys->i_header_pos = 0;
+
return VLC_SUCCESS;
}
* Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* bytes.
*****************************************************************************/
-static int Read( input_thread_t * p_input, byte_t * p_buffer,
- size_t i_len )
+static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
{
access_sys_t *p_sys = p_input->p_access_data;
int i_blocks = i_len / CDDA_DATA_SIZE;
int i_read = 0;
int i_index;
+ if( !p_sys->i_header_pos )
+ {
+ p_sys->i_header_pos = sizeof(WAVEHEADER);
+ i_blocks = (i_len - sizeof(WAVEHEADER)) / CDDA_DATA_SIZE;
+ memcpy( p_buffer, &p_sys->waveheader, sizeof(WAVEHEADER) );
+ p_buffer += sizeof(WAVEHEADER);
+ }
if( ioctl_ReadSectors( VLC_OBJECT(p_input), p_sys->vcddev, p_sys->i_sector,
p_buffer, i_blocks, CDDA_TYPE ) < 0 )
return i_read;
}
-
/*****************************************************************************
* SetProgram: Does nothing since a CDDA is mono_program
*****************************************************************************/
return VLC_EGENERIC;
}
-
/*****************************************************************************
* SetArea: initialize input data for title x.
* It should be called for each user navigation request.
return 0;
}
-
/****************************************************************************
* Seek
****************************************************************************/
- p_input->stream.p_selected_area->i_start;
vlc_mutex_unlock( &p_input->stream.stream_lock );
}
-
-
-
-
-/*****************************************************************************
- * Demux: local prototypes
- *****************************************************************************/
-struct demux_sys_t
-{
- es_out_id_t *p_es;
- mtime_t i_pts;
-};
-
-static int Demux ( input_thread_t * p_input );
-
-/****************************************************************************
- * DemuxOpen:
- ****************************************************************************/
-static int DemuxOpen ( vlc_object_t * p_this)
-{
- input_thread_t *p_input = (input_thread_t *)p_this;
- demux_sys_t *p_sys;
-
- es_format_t fmt;
-
- if( p_input->stream.i_method != INPUT_METHOD_CDDA )
- {
- return VLC_EGENERIC;
- }
-
- p_input->pf_demux = Demux;
- p_input->pf_rewind = NULL;
- p_input->pf_demux_control = demux_vaControlDefault;
- p_input->p_demux_data = p_sys = malloc( sizeof( es_descriptor_t ) );
- p_sys->i_pts = 0;
-
- vlc_mutex_lock( &p_input->stream.stream_lock );
- if( input_InitStream( p_input, 0 ) == -1)
- {
- vlc_mutex_unlock( &p_input->stream.stream_lock );
- msg_Err( p_input, "cannot init stream" );
- free( p_sys );
- return VLC_EGENERIC;
- }
- p_input->stream.i_mux_rate = 4 * 44100 / 50;
- vlc_mutex_unlock( &p_input->stream.stream_lock );
-
- es_format_Init( &fmt, AUDIO_ES, VLC_FOURCC( 'a', 'r', 'a', 'w' ) );
- fmt.audio.i_channels = 2;
- fmt.audio.i_rate = 44100;
- fmt.audio.i_bitspersample = 16;
- fmt.audio.i_blockalign = 4;
- fmt.i_bitrate = 4 * 44100 * 8;
-
- p_sys->p_es = es_out_Add( p_input->p_es_out, &fmt );
-
- return VLC_SUCCESS;
-}
-
-/****************************************************************************
- * DemuxClose:
- ****************************************************************************/
-static void DemuxClose( vlc_object_t * p_this)
-{
- input_thread_t *p_input = (input_thread_t*)p_this;
- demux_sys_t *p_sys = (demux_sys_t*)p_input->p_demux_data;
-
- free( p_sys );
- return;
-}
-
-/****************************************************************************
- * Demux:
- ****************************************************************************/
-static int Demux( input_thread_t * p_input )
-{
- demux_sys_t *p_sys = (demux_sys_t*)p_input->p_demux_data;
- block_t *p_block;
-
-
- input_ClockManageRef( p_input,
- p_input->stream.p_selected_program,
- p_sys->i_pts );
-
- if( ( p_block = stream_Block( p_input->s, CDDA_DATA_SIZE ) ) == NULL )
- {
- /* eof */
- return 0;
- }
- p_block->i_dts =
- p_block->i_pts = input_ClockGetTS( p_input,
- p_input->stream.p_selected_program,
- p_sys->i_pts );
- p_block->i_length = (mtime_t)90000 * (mtime_t)p_block->i_buffer/44100/4;
-
- p_sys->i_pts += p_block->i_length;
-
- es_out_Send( p_input->p_es_out, p_sys->p_es, p_block );
-
- return 1;
-}
--- /dev/null
+/*****************************************************************************
+ * dtstofloat32.c: DTS Coherent Acoustics decoder plugin for VLC.
+ * This plugin makes use of libdts to do the actual decoding
+ * (http://www.videolan.org/dtsdec/).
+ *****************************************************************************
+ * Copyright (C) 2001, 2002 VideoLAN
+ * $Id: dtstofloat32.c,v 1.1 2004/02/05 22:56:12 gbazin Exp $
+ *
+ * Author: Gildas Bazin <gbazin@netcourrier.com>
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <vlc/vlc.h>
+
+#include <stdlib.h> /* malloc(), free() */
+#include <string.h> /* strdup() */
+
+#ifdef USE_DTSDEC_TREE /* libdts header file */
+# include "include/dts.h"
+#else
+# include "dtsdec/dts.h"
+#endif
+
+#include "audio_output.h"
+#include "aout_internal.h"
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+static int Create ( vlc_object_t * );
+static void Destroy ( vlc_object_t * );
+static void DoWork ( aout_instance_t *, aout_filter_t *, aout_buffer_t *,
+ aout_buffer_t * );
+
+/*****************************************************************************
+ * Local structures
+ *****************************************************************************/
+struct aout_filter_sys_t
+{
+ dts_state_t * p_libdts; /* libdts internal structure */
+ vlc_bool_t b_dynrng; /* see below */
+ int i_flags; /* libdts flags, see dtsdec/doc/libdts.txt */
+ vlc_bool_t b_dontwarn;
+ int i_nb_channels; /* number of float32 per sample */
+};
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+#define DYNRNG_TEXT N_("DTS dynamic range compression")
+#define DYNRNG_LONGTEXT N_( \
+ "Dynamic range compression makes the loud sounds softer, and the soft " \
+ "sounds louder, so you can more easily listen to the stream in a noisy " \
+ "environment without disturbing anyone. If you disable the dynamic range "\
+ "compression the playback will be more adapted to a movie theater or a " \
+ "listening room.")
+
+vlc_module_begin();
+ set_description( _("DTS Coherent Acoustics audio decoder") );
+ add_bool( "dts-dynrng", 1, NULL, DYNRNG_TEXT, DYNRNG_LONGTEXT, VLC_FALSE );
+ set_capability( "audio filter", 100 );
+ set_callbacks( Create, Destroy );
+vlc_module_end();
+
+/*****************************************************************************
+ * Create:
+ *****************************************************************************/
+static int Create( vlc_object_t * _p_filter )
+{
+ aout_filter_t * p_filter = (aout_filter_t *)_p_filter;
+ struct aout_filter_sys_t * p_sys;
+
+ if ( p_filter->input.i_format != VLC_FOURCC('d','t','s',' ')
+ || p_filter->output.i_format != VLC_FOURCC('f','l','3','2') )
+ {
+ return -1;
+ }
+
+ if ( p_filter->input.i_rate != p_filter->output.i_rate )
+ {
+ return -1;
+ }
+
+ /* Allocate the memory needed to store the module's structure */
+ p_sys = p_filter->p_sys = malloc( sizeof(struct aout_filter_sys_t) );
+ if( p_sys == NULL )
+ {
+ msg_Err( p_filter, "out of memory" );
+ return -1;
+ }
+
+ p_sys->b_dynrng = config_GetInt( p_filter, "dts-dynrng" );
+ p_sys->b_dontwarn = 0;
+
+ /* We'll do our own downmixing, thanks. */
+ p_sys->i_nb_channels = aout_FormatNbChannels( &p_filter->output );
+ switch ( (p_filter->output.i_physical_channels & AOUT_CHAN_PHYSMASK)
+ & ~AOUT_CHAN_LFE )
+ {
+ case AOUT_CHAN_CENTER:
+ if ( (p_filter->output.i_original_channels & AOUT_CHAN_CENTER)
+ || (p_filter->output.i_original_channels
+ & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
+ {
+ p_sys->i_flags = DTS_MONO;
+ }
+ break;
+
+ case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT:
+ if ( p_filter->output.i_original_channels & AOUT_CHAN_DOLBYSTEREO )
+ {
+ p_sys->i_flags = DTS_DOLBY;
+ }
+ else if ( p_filter->input.i_original_channels == AOUT_CHAN_CENTER )
+ {
+ p_sys->i_flags = DTS_MONO;
+ }
+ else if ( p_filter->input.i_original_channels & AOUT_CHAN_DUALMONO )
+ {
+ p_sys->i_flags = DTS_CHANNEL;
+ }
+ else
+ {
+ p_sys->i_flags = DTS_STEREO;
+ }
+ break;
+
+ case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER:
+ p_sys->i_flags = DTS_3F;
+ break;
+
+ case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARCENTER:
+ p_sys->i_flags = DTS_2F1R;
+ break;
+
+ case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+ | AOUT_CHAN_REARCENTER:
+ p_sys->i_flags = DTS_3F1R;
+ break;
+
+ case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT
+ | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT:
+ p_sys->i_flags = DTS_2F2R;
+ break;
+
+ case AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
+ | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT:
+ p_sys->i_flags = DTS_3F2R;
+ break;
+
+ default:
+ msg_Warn( p_filter, "unknown sample format!" );
+ free( p_sys );
+ return -1;
+ }
+ if ( p_filter->output.i_physical_channels & AOUT_CHAN_LFE )
+ {
+ p_sys->i_flags |= DTS_LFE;
+ }
+ //p_sys->i_flags |= DTS_ADJUST_LEVEL;
+
+ /* Initialize libdts */
+ p_sys->p_libdts = dts_init( 0 );
+ if( p_sys->p_libdts == NULL )
+ {
+ msg_Err( p_filter, "unable to initialize libdts" );
+ return -1;
+ }
+
+ p_filter->pf_do_work = DoWork;
+ p_filter->b_in_place = 0;
+
+ return 0;
+}
+
+/*****************************************************************************
+ * Interleave: helper function to interleave channels
+ *****************************************************************************/
+static void Interleave( float * p_out, const float * p_in, int i_nb_channels )
+{
+ /* We do not only have to interleave, but also reorder the channels
+ * Channel reordering according to number of output channels of libdts
+ * The reordering needs to be different for different channel configurations
+ * (3F2R, 1F2R etc), so this is only temporary.
+ * The WG-4 order is appropriate for stereo, quadrophonia, and 5.1 surround.
+ *
+ * 6 channel mode
+ * channel libdts order WG-4 order
+ * 0 C // L
+ * 1 L // R
+ * 2 R // LS
+ * 3 LS // RS
+ * 4 RS // C
+ * 5 LFE // LFE
+ *
+ * The libdts moves channels to the front if there are unused spaces, so
+ * there is no gap between channels. The translation table says which
+ * channel of the new stream is taken from which original channel [use
+ * the new channel as the array index, use the number you get from the
+ * array to address the original channel].
+ */
+
+ static const int translation[7][6] =
+ {{ 0, 0, 0, 0, 0, 0 }, /* 0 channels (rarely used) */
+ { 0, 0, 0, 0, 0, 0 }, /* 1 ch */
+ { 0, 1, 0, 0, 0, 0 }, /* 2 */
+ { 1, 2, 0, 0, 0, 0 }, /* 3 */
+ { 0, 1, 2, 3, 0, 0 }, /* 4 */
+ { 1, 2, 3, 4, 0, 0 }, /* 5 */
+ { 1, 2, 3, 4, 0, 5 }}; /* 6 */
+
+ int i, j;
+ for ( j = 0; j < i_nb_channels; j++ )
+ {
+ for ( i = 0; i < 256; i++ )
+ {
+ p_out[i * i_nb_channels + j] = p_in[translation[i_nb_channels][j]
+ * 256 + i];
+ }
+ }
+}
+
+/*****************************************************************************
+ * Duplicate: helper function to duplicate a unique channel
+ *****************************************************************************/
+static void Duplicate( float * p_out, const float * p_in )
+{
+ int i;
+
+ for ( i = 256; i--; )
+ {
+ *p_out++ = *p_in;
+ *p_out++ = *p_in;
+ p_in++;
+ }
+}
+
+/*****************************************************************************
+ * Exchange: helper function to exchange left & right channels
+ *****************************************************************************/
+static void Exchange( float * p_out, const float * p_in )
+{
+ int i;
+ const float * p_first = p_in + 256;
+ const float * p_second = p_in;
+
+ for ( i = 0; i < 256; i++ )
+ {
+ *p_out++ = *p_first++;
+ *p_out++ = *p_second++;
+ }
+}
+
+/*****************************************************************************
+ * DoWork: decode a DTS frame.
+ *****************************************************************************/
+static void DoWork( aout_instance_t * p_aout, aout_filter_t * p_filter,
+ aout_buffer_t * p_in_buf, aout_buffer_t * p_out_buf )
+{
+ struct aout_filter_sys_t * p_sys = p_filter->p_sys;
+ sample_t i_sample_level = 1;
+ int i_flags = p_sys->i_flags;
+ int i_bytes_per_block = 256 * p_sys->i_nb_channels
+ * sizeof(float);
+ int i;
+
+ /*
+ * Do the actual decoding now.
+ */
+
+ /* Needs to be called so the decoder knows which type of bitstream it is
+ * dealing with. */
+ int i_sample_rate, i_bit_rate, i_frame_length;
+ if( !dts_syncinfo( p_sys->p_libdts, p_in_buf->p_buffer, &i_flags,
+ &i_sample_rate, &i_bit_rate, &i_frame_length ) )
+ {
+ msg_Warn( p_filter, "libdts couldn't sync on frame" );
+ p_out_buf->i_nb_samples = p_out_buf->i_nb_bytes = 0;
+ return;
+ }
+
+ i_flags = p_sys->i_flags;
+ dts_frame( p_sys->p_libdts, p_in_buf->p_buffer,
+ &i_flags, &i_sample_level, 0 );
+
+ if ( (i_flags & DTS_CHANNEL_MASK) != (p_sys->i_flags & DTS_CHANNEL_MASK)
+ && !p_sys->b_dontwarn )
+ {
+ msg_Warn( p_filter,
+ "libdts couldn't do the requested downmix 0x%x->0x%x",
+ p_sys->i_flags & DTS_CHANNEL_MASK,
+ i_flags & DTS_CHANNEL_MASK );
+
+ p_sys->b_dontwarn = 1;
+ }
+
+ if( 0)//!p_sys->b_dynrng )
+ {
+ dts_dynrng( p_filter->p_sys->p_libdts, NULL, NULL );
+ }
+
+ for ( i = 0; i < dts_blocks_num(p_filter->p_sys->p_libdts); i++ )
+ {
+ sample_t * p_samples;
+
+ if( dts_block( p_sys->p_libdts ) )
+ {
+ msg_Warn( p_filter, "dts_block failed for block %d", i );
+ break;
+ }
+
+ p_samples = dts_samples( p_sys->p_libdts );
+
+ if ( (p_sys->i_flags & DTS_CHANNEL_MASK) == DTS_MONO
+ && (p_filter->output.i_physical_channels
+ & (AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT)) )
+ {
+ Duplicate( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
+ p_samples );
+ }
+ else if ( p_filter->output.i_original_channels
+ & AOUT_CHAN_REVERSESTEREO )
+ {
+ Exchange( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
+ p_samples );
+ }
+ else
+ {
+ /* Interleave the *$£%ù samples. */
+ Interleave( (float *)(p_out_buf->p_buffer + i * i_bytes_per_block),
+ p_samples, p_sys->i_nb_channels );
+ }
+ }
+
+ p_out_buf->i_nb_samples = p_in_buf->i_nb_samples;
+ p_out_buf->i_nb_bytes = i_bytes_per_block * i;
+}
+
+/*****************************************************************************
+ * Destroy : deallocate data structures
+ *****************************************************************************/
+static void Destroy( vlc_object_t * _p_filter )
+{
+ aout_filter_t * p_filter = (aout_filter_t *)_p_filter;
+ struct aout_filter_sys_t * p_sys = p_filter->p_sys;
+
+ dts_free( p_sys->p_libdts );
+ free( p_sys );
+}
* dts.c : raw DTS stream input module for vlc
*****************************************************************************
* Copyright (C) 2001 VideoLAN
- * $Id: dts.c,v 1.4 2004/02/04 08:11:49 gbazin Exp $
+ * $Id: dts.c,v 1.5 2004/02/05 22:56:11 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
static void Close ( vlc_object_t * );
static int Demux ( input_thread_t * );
+static int Control( input_thread_t *, int, va_list );
+
struct demux_sys_t
{
vlc_bool_t b_start;
/* Packetizer */
decoder_t *p_packetizer;
+
+ int i_mux_rate;
};
/*****************************************************************************
int i_peek = 0;
p_input->pf_demux = Demux;
- p_input->pf_demux_control = demux_vaControlDefault;
+ p_input->pf_demux_control = Control;
p_input->pf_rewind = NULL;
/* Check if we are dealing with a WAV file */
p_input->p_demux_data = p_sys = malloc( sizeof( demux_sys_t ) );
p_sys->b_start = VLC_TRUE;
+ p_sys->i_mux_rate = 0;
/*
* Load the DTS packetizer
{
block_t *p_next = p_block_out->p_next;
+ /* We assume a constant bitrate */
+ if( p_block_out->i_length )
+ p_sys->i_mux_rate =
+ p_block_out->i_buffer * I64C(1000000) / p_block_out->i_length;
+ p_input->stream.i_mux_rate = p_sys->i_mux_rate / 50;
+
input_ClockManageRef( p_input,
p_input->stream.p_selected_program,
p_block_out->i_pts * 9 / 100 );
return 1;
}
+
+/*****************************************************************************
+ * Control:
+ *****************************************************************************/
+static int Control( input_thread_t *p_input, int i_query, va_list args )
+{
+ demux_sys_t *p_sys = (demux_sys_t *)p_input->p_demux_data;
+ int64_t *pi64;
+
+ switch( i_query )
+ {
+ case DEMUX_GET_TIME:
+ pi64 = (int64_t*)va_arg( args, int64_t * );
+ if( p_sys->i_mux_rate > 0 )
+ {
+ *pi64 = I64C(1000000) * stream_Tell( p_input->s ) /
+ p_sys->i_mux_rate;
+ return VLC_SUCCESS;
+ }
+ *pi64 = 0;
+ return VLC_EGENERIC;
+
+ case DEMUX_GET_LENGTH:
+ pi64 = (int64_t*)va_arg( args, int64_t * );
+ if( p_sys->i_mux_rate > 0 )
+ {
+ *pi64 = I64C(1000000) * stream_Size( p_input->s ) /
+ p_sys->i_mux_rate;
+ return VLC_SUCCESS;
+ }
+ *pi64 = 0;
+ return VLC_EGENERIC;
+
+ default:
+ return demux_vaControlDefault( p_input, i_query, args );
+ }
+}
* wav.c : wav file input module for vlc
*****************************************************************************
* Copyright (C) 2001-2003 VideoLAN
- * $Id: wav.c,v 1.11 2003/11/21 00:38:01 gbazin Exp $
+ * $Id: wav.c,v 1.12 2004/02/05 22:56:11 gbazin Exp $
*
* Authors: Laurent Aimar <fenrir@via.ecp.fr>
*
/*****************************************************************************
* Module descriptor
*****************************************************************************/
-
-static int Open ( vlc_object_t * );
-static void Close ( vlc_object_t * );
+static int Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
vlc_module_begin();
set_description( _("WAV demuxer") );
/*****************************************************************************
* Local prototypes
*****************************************************************************/
-
-static int Demux ( input_thread_t * );
+static int Demux( input_thread_t * );
struct demux_sys_t
{
mtime_t i_frame_length;
};
-
/*****************************************************************************
* Declaration of local function
*****************************************************************************/
}
es_format_Init( &p_sys->fmt, AUDIO_ES, 0 );
- wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_sys->fmt.i_codec, &psz_name );
+ wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_sys->fmt.i_codec,
+ &psz_name );
p_sys->fmt.audio.i_channels = GetWLE ( &p_wf->nChannels );
p_sys->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
p_sys->fmt.audio.i_blockalign = GetWLE ( &p_wf->nBlockAlign );
memcpy( p_sys->fmt.p_extra, &p_wf[1], p_sys->fmt.i_extra );
}
- msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s blockalign:%d bits/samples:%d extra size:%d",
- GetWLE( &p_wf->wFormatTag ),
- p_sys->fmt.audio.i_channels,
- p_sys->fmt.audio.i_rate,
- p_sys->fmt.i_bitrate / 8 / 1024,
- p_sys->fmt.audio.i_blockalign,
- p_sys->fmt.audio.i_bitspersample,
- p_sys->fmt.i_extra );
+ msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s "
+ "blockalign:%d bits/samples:%d extra size:%d",
+ GetWLE( &p_wf->wFormatTag ), p_sys->fmt.audio.i_channels,
+ p_sys->fmt.audio.i_rate, p_sys->fmt.i_bitrate / 8 / 1024,
+ p_sys->fmt.audio.i_blockalign, p_sys->fmt.audio.i_bitspersample,
+ p_sys->fmt.i_extra );
+
free( p_wf );
switch( p_sys->fmt.i_codec )
{
- case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
- case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
- case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
- FrameInfo_PCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
- break;
- case VLC_FOURCC( 'm', 's', 0x00, 0x02 ):
- FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
- break;
- case VLC_FOURCC( 'm', 's', 0x00, 0x11 ):
- FrameInfo_IMA_ADPCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
- break;
- case VLC_FOURCC( 'm', 's', 0x00, 0x61 ):
- case VLC_FOURCC( 'm', 's', 0x00, 0x62 ):
- /* FIXME not sure at all FIXME */
- FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
- break;
- case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
- case VLC_FOURCC( 'a', '5', '2', ' ' ):
- /* FIXME set end of area FIXME */
- goto relay;
- default:
- msg_Err( p_input, "unsupported codec (%4.4s)", (char*)&p_sys->fmt.i_codec );
- goto error;
+ case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
+ case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
+ case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
+ FrameInfo_PCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
+ break;
+ case VLC_FOURCC( 'm', 's', 0x00, 0x02 ):
+ FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size,
+ &p_sys->i_frame_length );
+ break;
+ case VLC_FOURCC( 'm', 's', 0x00, 0x11 ):
+ FrameInfo_IMA_ADPCM( p_input, &p_sys->i_frame_size,
+ &p_sys->i_frame_length );
+ break;
+ case VLC_FOURCC( 'm', 's', 0x00, 0x61 ):
+ case VLC_FOURCC( 'm', 's', 0x00, 0x62 ):
+ /* FIXME not sure at all FIXME */
+ FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size,
+ &p_sys->i_frame_length );
+ break;
+ case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
+ case VLC_FOURCC( 'a', '5', '2', ' ' ):
+ /* FIXME set end of area FIXME */
+ goto relay;
+ default:
+ msg_Err( p_input, "unsupported codec (%4.4s)",
+ (char*)&p_sys->fmt.i_codec );
+ goto error;
}
msg_Dbg( p_input, "found %s audio format", psz_name );
stream_Read( p_input->s, NULL, 8 ); /* cannot fail */
- /* create one program */
+ /* Create one program */
vlc_mutex_lock( &p_input->stream.stream_lock );
if( input_InitStream( p_input, 0 ) == -1)
{
msg_Err( p_input, "cannot init stream" );
goto error;
}
+
p_input->stream.i_mux_rate = 0;
- if( p_sys->i_data_size > 0 )
+ if( p_sys->fmt.i_bitrate )
+ {
+ p_input->stream.i_mux_rate = p_sys->fmt.i_bitrate / 50 / 8;
+ }
+ else if( p_sys->i_data_size > 0 )
{
p_input->stream.i_mux_rate = (mtime_t)p_sys->i_frame_size *
- (mtime_t)1000000 / 50 / p_sys->i_frame_length;
+ (mtime_t)1000000 / 50 / p_sys->i_frame_length;
}
vlc_mutex_unlock( &p_input->stream.stream_lock );
*****************************************************************************/
static int Demux( input_thread_t *p_input )
{
- demux_sys_t *p_sys = p_input->p_demux_data;
- int64_t i_pos;
- block_t *p_block;
+ demux_sys_t *p_sys = p_input->p_demux_data;
+ int64_t i_pos;
+ block_t *p_block;
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{
i_pos = stream_Tell( p_input->s );
- if( p_sys->fmt.audio.i_blockalign != 0 )
+ if( p_sys->fmt.audio.i_blockalign != 0 &&
+ i_pos % p_sys->fmt.audio.i_blockalign )
{
- i_pos += p_sys->fmt.audio.i_blockalign - i_pos % p_sys->fmt.audio.i_blockalign;
- if( stream_Seek( p_input->s, i_pos ) )
+ i_pos = p_sys->fmt.audio.i_blockalign -
+ i_pos % p_sys->fmt.audio.i_blockalign;
+
+ /* Skip some data to realign the stream */
+ if( stream_Read( p_input->s, NULL, i_pos ) != i_pos )
{
msg_Err( p_input, "stream_Sekk failed (cannot resync)" );
}
}
}
- input_ClockManageRef( p_input,
- p_input->stream.p_selected_program,
+ input_ClockManageRef( p_input, p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 );
i_pos = stream_Tell( p_input->s );
}
p_block->i_dts =
p_block->i_pts = input_ClockGetTS( p_input,
- p_input->stream.p_selected_program,
- p_sys->i_time * 9 / 100 );
+ p_input->stream.p_selected_program,
+ p_sys->i_time * 9 / 100 );
es_out_Send( p_input->p_es_out, p_sys->p_es, p_block );
p_sys->i_time += p_sys->i_frame_length;
- return( 1 );
+ return 1;
}
/*****************************************************************************
free( p_sys );
}
-
/*****************************************************************************
* Local functions
*****************************************************************************/
static int ChunkFind( input_thread_t *p_input,
char *fcc, unsigned int *pi_size )
{
- uint8_t *p_peek;
+ uint8_t *p_peek;
for( ;; )
{
(mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate;
- i_bytes = i_samples * p_sys->fmt.audio.i_channels * ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
+ i_bytes = i_samples * p_sys->fmt.audio.i_channels *
+ ( (p_sys->fmt.audio.i_bitspersample + 7) / 8 );
if( p_sys->fmt.audio.i_blockalign > 0 )
{
i_bytes += p_sys->fmt.audio.i_blockalign - i_modulo;
}
}
+
*pi_size = i_bytes;
}
static void FrameInfo_MS_ADPCM( input_thread_t *p_input,
- unsigned int *pi_size,
- mtime_t *pi_length )
+ unsigned int *pi_size,
+ mtime_t *pi_length )
{
- demux_sys_t *p_sys = p_input->p_demux_data;
+ demux_sys_t *p_sys = p_input->p_demux_data;
int i_samples;
i_samples = 2 + 2 * ( p_sys->fmt.audio.i_blockalign -
- 7 * p_sys->fmt.audio.i_channels ) / p_sys->fmt.audio.i_channels;
+ 7 * p_sys->fmt.audio.i_channels ) / p_sys->fmt.audio.i_channels;
- *pi_length = (mtime_t)1000000 *
- (mtime_t)i_samples /
+ *pi_length = (mtime_t)1000000 * (mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate;
*pi_size = p_sys->fmt.audio.i_blockalign;
}
static void FrameInfo_IMA_ADPCM( input_thread_t *p_input,
- unsigned int *pi_size,
- mtime_t *pi_length )
+ unsigned int *pi_size,
+ mtime_t *pi_length )
{
- demux_sys_t *p_sys = p_input->p_demux_data;
+ demux_sys_t *p_sys = p_input->p_demux_data;
int i_samples;
i_samples = 2 * ( p_sys->fmt.audio.i_blockalign -
- 4 * p_sys->fmt.audio.i_channels ) / p_sys->fmt.audio.i_channels;
+ 4 * p_sys->fmt.audio.i_channels ) / p_sys->fmt.audio.i_channels;
- *pi_length = (mtime_t)1000000 *
- (mtime_t)i_samples /
+ *pi_length = (mtime_t)1000000 * (mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate;
*pi_size = p_sys->fmt.audio.i_blockalign;
}
-
* vout.c: Windows DirectX video output display method
*****************************************************************************
* Copyright (C) 2001-2004 VideoLAN
- * $Id: directx.c,v 1.34 2004/01/26 16:45:02 zorglub Exp $
+ * $Id: directx.c,v 1.35 2004/02/05 22:56:11 gbazin Exp $
*
* Authors: Gildas Bazin <gbazin@netcourrier.com>
*
add_string( "directx-device", "", NULL, DEVICE_TEXT, DEVICE_LONGTEXT,
VLC_TRUE );
change_string_list( ppsz_dev, ppsz_dev_text, FindDevicesCallback );
+ change_action_add( FindDevicesCallback, N_("Refresh list") );
set_description( _("DirectX video output") );
set_capability( "video output", 100 );