From a4b486148b57b3bc15c165e1cebea1ee0e444284 Mon Sep 17 00:00:00 2001 From: Gildas Bazin Date: Thu, 5 Feb 2004 22:56:12 +0000 Subject: [PATCH] * modules/video_output/directx/directx.c: fixed the "refresh" button for the --directx-device option. * 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. --- configure.ac | 62 ++- modules/access/cdda.c | 170 +++----- modules/audio_filter/converter/dtstofloat32.c | 365 ++++++++++++++++++ modules/demux/dts.c | 52 ++- modules/demux/wav.c | 145 +++---- modules/video_output/directx/directx.c | 3 +- 6 files changed, 600 insertions(+), 197 deletions(-) create mode 100644 modules/audio_filter/converter/dtstofloat32.c diff --git a/configure.ac b/configure.ac index 5d28b138f2..2cf0d89cdf 100644 --- a/configure.ac +++ b/configure.ac @@ -1,5 +1,5 @@ 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) @@ -377,7 +377,7 @@ AM_CONDITIONAL(BUILD_GETOPT, ${need_getopt}) 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]) @@ -1993,7 +1993,7 @@ AC_CHECK_HEADERS(libtar.h, [ 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)]) @@ -2062,6 +2062,62 @@ then 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 diff --git a/modules/access/cdda.c b/modules/access/cdda.c index 36f05fda73..a7c2d6307c 100644 --- a/modules/access/cdda.c +++ b/modules/access/cdda.c @@ -2,7 +2,7 @@ * 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 * Gildas Bazin @@ -32,15 +32,29 @@ #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 " \ @@ -55,12 +69,6 @@ vlc_module_begin(); 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(); @@ -80,6 +88,8 @@ struct access_sys_t 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 ); @@ -171,7 +181,7 @@ static int AccessOpen( vlc_object_t *p_this ) 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 ); @@ -216,11 +226,6 @@ static int AccessOpen( vlc_object_t *p_this ) 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; @@ -229,6 +234,25 @@ static int AccessOpen( vlc_object_t *p_this ) /* 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; } @@ -250,14 +274,20 @@ static void AccessClose( vlc_object_t *p_this ) * 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 ) @@ -299,7 +329,6 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, return i_read; } - /***************************************************************************** * SetProgram: Does nothing since a CDDA is mono_program *****************************************************************************/ @@ -309,7 +338,6 @@ static int SetProgram( input_thread_t * p_input, return VLC_EGENERIC; } - /***************************************************************************** * SetArea: initialize input data for title x. * It should be called for each user navigation request. @@ -349,7 +377,6 @@ static int SetArea( input_thread_t * p_input, input_area_t * p_area ) return 0; } - /**************************************************************************** * Seek ****************************************************************************/ @@ -366,104 +393,3 @@ static void Seek( input_thread_t * p_input, off_t i_off ) - 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; -} diff --git a/modules/audio_filter/converter/dtstofloat32.c b/modules/audio_filter/converter/dtstofloat32.c new file mode 100644 index 0000000000..d42d60c9a9 --- /dev/null +++ b/modules/audio_filter/converter/dtstofloat32.c @@ -0,0 +1,365 @@ +/***************************************************************************** + * 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 + * + * 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 + +#include /* malloc(), free() */ +#include /* 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 ); +} diff --git a/modules/demux/dts.c b/modules/demux/dts.c index 9e58c44190..30b1a33e44 100644 --- a/modules/demux/dts.c +++ b/modules/demux/dts.c @@ -2,7 +2,7 @@ * 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 * @@ -38,6 +38,8 @@ static int Open ( vlc_object_t * ); 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; @@ -45,6 +47,8 @@ struct demux_sys_t /* Packetizer */ decoder_t *p_packetizer; + + int i_mux_rate; }; /***************************************************************************** @@ -103,7 +107,7 @@ static int Open( vlc_object_t * p_this ) 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 */ @@ -163,6 +167,7 @@ static int Open( vlc_object_t * p_this ) 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 @@ -251,6 +256,12 @@ static int Demux( input_thread_t * p_input ) { 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 ); @@ -268,3 +279,40 @@ static int Demux( input_thread_t * p_input ) 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 ); + } +} diff --git a/modules/demux/wav.c b/modules/demux/wav.c index 18d6865e06..af5c28b4c1 100644 --- a/modules/demux/wav.c +++ b/modules/demux/wav.c @@ -2,7 +2,7 @@ * 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 * @@ -34,9 +34,8 @@ /***************************************************************************** * 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") ); @@ -47,8 +46,7 @@ vlc_module_end(); /***************************************************************************** * Local prototypes *****************************************************************************/ - -static int Demux ( input_thread_t * ); +static int Demux( input_thread_t * ); struct demux_sys_t { @@ -63,7 +61,6 @@ struct demux_sys_t mtime_t i_frame_length; }; - /***************************************************************************** * Declaration of local function *****************************************************************************/ @@ -133,7 +130,8 @@ static int Open( vlc_object_t * p_this ) } 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 ); @@ -147,41 +145,44 @@ static int Open( vlc_object_t * p_this ) 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 ); @@ -196,7 +197,7 @@ static int Open( vlc_object_t * p_this ) 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) { @@ -204,11 +205,16 @@ static int Open( vlc_object_t * p_this ) 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 ); @@ -228,25 +234,28 @@ relay: *****************************************************************************/ 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 ); @@ -265,14 +274,14 @@ static int Demux( input_thread_t *p_input ) } 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; } /***************************************************************************** @@ -286,14 +295,13 @@ static void Close ( vlc_object_t * p_this ) 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( ;; ) { @@ -345,7 +353,8 @@ static void FrameInfo_PCM( input_thread_t *p_input, (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 ) { @@ -354,42 +363,40 @@ static void FrameInfo_PCM( input_thread_t *p_input, 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; } - diff --git a/modules/video_output/directx/directx.c b/modules/video_output/directx/directx.c index ed40ff05af..85ebd7a2e6 100644 --- a/modules/video_output/directx/directx.c +++ b/modules/video_output/directx/directx.c @@ -2,7 +2,7 @@ * 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 * @@ -138,6 +138,7 @@ vlc_module_begin(); 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 ); -- 2.39.2