]> git.sesse.net Git - vlc/commitdiff
* modules/video_output/directx/directx.c: fixed the "refresh" button for the --direct...
authorGildas Bazin <gbazin@videolan.org>
Thu, 5 Feb 2004 22:56:12 +0000 (22:56 +0000)
committerGildas Bazin <gbazin@videolan.org>
Thu, 5 Feb 2004 22:56:12 +0000 (22:56 +0000)
* 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
modules/access/cdda.c
modules/audio_filter/converter/dtstofloat32.c [new file with mode: 0644]
modules/demux/dts.c
modules/demux/wav.c
modules/video_output/directx/directx.c

index 5d28b138f24a61675e82414f1e865445818394a6..2cf0d89cdfc59961cbf59ae4788e847720aba2b2 100644 (file)
@@ -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
index 36f05fda734bb837dcd86c2a18f1a294ffffd433..a7c2d6307ca7fea9ad7827027e7d2ff79068ec94 100644 (file)
@@ -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 <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 " \
@@ -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 <= )
     {
         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 (file)
index 0000000..d42d60c
--- /dev/null
@@ -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 <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 );
+}
index 9e58c44190d9de2cba86ee817775e9e3e50d72ee..30b1a33e44c263fa7b249639ee523567fe4a5ae5 100644 (file)
@@ -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 <gbazin@netcourrier.com>
  *
@@ -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 );
+    }
+}
index 18d6865e06c8129c4413631d4fd53f0e2feefeab..af5c28b4c1c25971893b638014445be62906722d 100644 (file)
@@ -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 <fenrir@via.ecp.fr>
  *
@@ -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;
 }
-
index ed40ff05afb10a547cf8156fb50e87c5a15d4aec..85ebd7a2e61bc3254bdbba39f3cd6a26fd228e0a 100644 (file)
@@ -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 <gbazin@netcourrier.com>
  *
@@ -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 );