Commit a4b48614 authored by Gildas Bazin's avatar Gildas Bazin

* 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.
parent 93f3c135
dnl Autoconf settings for vlc 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) AC_INIT(vlc,0.7.1-cvs)
...@@ -377,7 +377,7 @@ AM_CONDITIONAL(BUILD_GETOPT, ${need_getopt}) ...@@ -377,7 +377,7 @@ AM_CONDITIONAL(BUILD_GETOPT, ${need_getopt})
if test "${SYS}" != "mingw32"; then if test "${SYS}" != "mingw32"; then
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_CHECK_LIB(m,cos,[ 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,[ AC_CHECK_LIB(m,pow,[
AX_ADD_LDFLAGS([ffmpeg stream_out_transcode stream_out_transrate i420_rgb faad vlc],[-lm]) AX_ADD_LDFLAGS([ffmpeg stream_out_transcode stream_out_transrate i420_rgb faad vlc],[-lm])
...@@ -1993,7 +1993,7 @@ AC_CHECK_HEADERS(libtar.h, [ ...@@ -1993,7 +1993,7 @@ AC_CHECK_HEADERS(libtar.h, [
dnl dnl
dnl a52 AC3 decoder plugin dnl A52/AC3 decoder plugin
dnl dnl
AC_ARG_ENABLE(a52, AC_ARG_ENABLE(a52,
[ --enable-a52 A/52 support with liba52 (default enabled)]) [ --enable-a52 A/52 support with liba52 (default enabled)])
...@@ -2062,6 +2062,62 @@ then ...@@ -2062,6 +2062,62 @@ then
fi fi
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
dnl dnl DV plugin dnl dnl DV plugin
dnl dnl dnl dnl
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* cdda.c : CD digital audio input module for vlc * cdda.c : CD digital audio input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2000, 2003 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@netcourrier.com> * Gildas Bazin <gbazin@netcourrier.com>
...@@ -32,15 +32,29 @@ ...@@ -32,15 +32,29 @@
#include "vcd/cdrom.h" #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 * Module descriptior
*****************************************************************************/ *****************************************************************************/
static int AccessOpen ( vlc_object_t * ); static int AccessOpen ( vlc_object_t * );
static void AccessClose( 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_TEXT N_("Caching value in ms")
#define CACHING_LONGTEXT N_( \ #define CACHING_LONGTEXT N_( \
"Allows you to modify the default caching value for cdda streams. This " \ "Allows you to modify the default caching value for cdda streams. This " \
...@@ -55,12 +69,6 @@ vlc_module_begin(); ...@@ -55,12 +69,6 @@ vlc_module_begin();
set_capability( "access", 70 ); set_capability( "access", 70 );
set_callbacks( AccessOpen, AccessClose ); set_callbacks( AccessOpen, AccessClose );
add_shortcut( "cdda" ); add_shortcut( "cdda" );
add_submodule();
set_description( _("Audio CD demux") );
set_capability( "demux", 0 );
set_callbacks( DemuxOpen, DemuxClose );
add_shortcut( "cdda" );
vlc_module_end(); vlc_module_end();
...@@ -80,6 +88,8 @@ struct access_sys_t ...@@ -80,6 +88,8 @@ struct access_sys_t
int * p_sectors; /* Track sectors */ int * p_sectors; /* Track sectors */
vlc_bool_t b_end_of_track; /* If the end of track was reached */ 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 ); static int Read ( input_thread_t *, byte_t *, size_t );
...@@ -171,7 +181,7 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -171,7 +181,7 @@ static int AccessOpen( vlc_object_t *p_this )
msg_Err( p_input, "no audio tracks found" ); 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 ); ioctl_Close( p_this, p_sys->vcddev );
free( p_sys ); free( p_sys );
...@@ -216,11 +226,6 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -216,11 +226,6 @@ static int AccessOpen( vlc_object_t *p_this )
vlc_mutex_unlock( &p_input->stream.stream_lock ); 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_read = Read;
p_input->pf_seek = Seek; p_input->pf_seek = Seek;
p_input->pf_set_area = SetArea; p_input->pf_set_area = SetArea;
...@@ -229,6 +234,25 @@ static int AccessOpen( vlc_object_t *p_this ) ...@@ -229,6 +234,25 @@ static int AccessOpen( vlc_object_t *p_this )
/* Update default_pts to a suitable value for cdda access */ /* Update default_pts to a suitable value for cdda access */
p_input->i_pts_delay = config_GetInt( p_input, "cdda-caching" ) * 1000; 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; return VLC_SUCCESS;
} }
...@@ -250,14 +274,20 @@ static void AccessClose( vlc_object_t *p_this ) ...@@ -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 * Returns -1 in case of error, 0 in case of EOF, otherwise the number of
* bytes. * bytes.
*****************************************************************************/ *****************************************************************************/
static int Read( input_thread_t * p_input, byte_t * p_buffer, static int Read( input_thread_t * p_input, byte_t * p_buffer, size_t i_len )
size_t i_len )
{ {
access_sys_t *p_sys = p_input->p_access_data; access_sys_t *p_sys = p_input->p_access_data;
int i_blocks = i_len / CDDA_DATA_SIZE; int i_blocks = i_len / CDDA_DATA_SIZE;
int i_read = 0; int i_read = 0;
int i_index; 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, if( ioctl_ReadSectors( VLC_OBJECT(p_input), p_sys->vcddev, p_sys->i_sector,
p_buffer, i_blocks, CDDA_TYPE ) < 0 ) p_buffer, i_blocks, CDDA_TYPE ) < 0 )
...@@ -299,7 +329,6 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer, ...@@ -299,7 +329,6 @@ static int Read( input_thread_t * p_input, byte_t * p_buffer,
return i_read; return i_read;
} }
/***************************************************************************** /*****************************************************************************
* SetProgram: Does nothing since a CDDA is mono_program * SetProgram: Does nothing since a CDDA is mono_program
*****************************************************************************/ *****************************************************************************/
...@@ -309,7 +338,6 @@ static int SetProgram( input_thread_t * p_input, ...@@ -309,7 +338,6 @@ static int SetProgram( input_thread_t * p_input,
return VLC_EGENERIC; return VLC_EGENERIC;
} }
/***************************************************************************** /*****************************************************************************
* SetArea: initialize input data for title x. * SetArea: initialize input data for title x.
* It should be called for each user navigation request. * 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 ) ...@@ -349,7 +377,6 @@ static int SetArea( input_thread_t * p_input, input_area_t * p_area )
return 0; return 0;
} }
/**************************************************************************** /****************************************************************************
* Seek * Seek
****************************************************************************/ ****************************************************************************/
...@@ -366,104 +393,3 @@ static void Seek( input_thread_t * p_input, off_t i_off ) ...@@ -366,104 +393,3 @@ static void Seek( input_thread_t * p_input, off_t i_off )
- p_input->stream.p_selected_area->i_start; - p_input->stream.p_selected_area->i_start;
vlc_mutex_unlock( &p_input->stream.stream_lock ); 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;
}
/*****************************************************************************
* 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 );
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* dts.c : raw DTS stream input module for vlc * dts.c : raw DTS stream input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -38,6 +38,8 @@ static int Open ( vlc_object_t * ); ...@@ -38,6 +38,8 @@ static int Open ( vlc_object_t * );
static void Close ( vlc_object_t * ); static void Close ( vlc_object_t * );
static int Demux ( input_thread_t * ); static int Demux ( input_thread_t * );
static int Control( input_thread_t *, int, va_list );
struct demux_sys_t struct demux_sys_t
{ {
vlc_bool_t b_start; vlc_bool_t b_start;
...@@ -45,6 +47,8 @@ struct demux_sys_t ...@@ -45,6 +47,8 @@ struct demux_sys_t
/* Packetizer */ /* Packetizer */
decoder_t *p_packetizer; decoder_t *p_packetizer;
int i_mux_rate;
}; };
/***************************************************************************** /*****************************************************************************
...@@ -103,7 +107,7 @@ static int Open( vlc_object_t * p_this ) ...@@ -103,7 +107,7 @@ static int Open( vlc_object_t * p_this )
int i_peek = 0; int i_peek = 0;
p_input->pf_demux = Demux; p_input->pf_demux = Demux;
p_input->pf_demux_control = demux_vaControlDefault; p_input->pf_demux_control = Control;
p_input->pf_rewind = NULL; p_input->pf_rewind = NULL;
/* Check if we are dealing with a WAV file */ /* Check if we are dealing with a WAV file */
...@@ -163,6 +167,7 @@ static int Open( vlc_object_t * p_this ) ...@@ -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_input->p_demux_data = p_sys = malloc( sizeof( demux_sys_t ) );
p_sys->b_start = VLC_TRUE; p_sys->b_start = VLC_TRUE;
p_sys->i_mux_rate = 0;
/* /*
* Load the DTS packetizer * Load the DTS packetizer
...@@ -251,6 +256,12 @@ static int Demux( input_thread_t * p_input ) ...@@ -251,6 +256,12 @@ static int Demux( input_thread_t * p_input )
{ {
block_t *p_next = p_block_out->p_next; 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, input_ClockManageRef( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_block_out->i_pts * 9 / 100 ); p_block_out->i_pts * 9 / 100 );
...@@ -268,3 +279,40 @@ static int Demux( input_thread_t * p_input ) ...@@ -268,3 +279,40 @@ static int Demux( input_thread_t * p_input )
return 1; 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 );
}
}
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* wav.c : wav file input module for vlc * wav.c : wav file input module for vlc
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2003 VideoLAN * 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> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* *
...@@ -34,9 +34,8 @@ ...@@ -34,9 +34,8 @@
/***************************************************************************** /*****************************************************************************
* Module descriptor * Module descriptor
*****************************************************************************/ *****************************************************************************/
static int Open ( vlc_object_t * );
static int Open ( vlc_object_t * ); static void Close( vlc_object_t * );
static void Close ( vlc_object_t * );
vlc_module_begin(); vlc_module_begin();
set_description( _("WAV demuxer") ); set_description( _("WAV demuxer") );
...@@ -47,8 +46,7 @@ vlc_module_end(); ...@@ -47,8 +46,7 @@ vlc_module_end();
/***************************************************************************** /*****************************************************************************
* Local prototypes * Local prototypes
*****************************************************************************/ *****************************************************************************/
static int Demux( input_thread_t * );
static int Demux ( input_thread_t * );
struct demux_sys_t struct demux_sys_t
{ {
...@@ -63,7 +61,6 @@ struct demux_sys_t ...@@ -63,7 +61,6 @@ struct demux_sys_t
mtime_t i_frame_length; mtime_t i_frame_length;
}; };
/***************************************************************************** /*****************************************************************************
* Declaration of local function * Declaration of local function
*****************************************************************************/ *****************************************************************************/
...@@ -133,7 +130,8 @@ static int Open( vlc_object_t * p_this ) ...@@ -133,7 +130,8 @@ static int Open( vlc_object_t * p_this )
} }
es_format_Init( &p_sys->fmt, AUDIO_ES, 0 ); 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_channels = GetWLE ( &p_wf->nChannels );
p_sys->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec ); p_sys->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
p_sys->fmt.audio.i_blockalign = GetWLE ( &p_wf->nBlockAlign ); p_sys->fmt.audio.i_blockalign = GetWLE ( &p_wf->nBlockAlign );
...@@ -147,41 +145,44 @@ static int Open( vlc_object_t * p_this ) ...@@ -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 ); 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", msg_Dbg( p_input, "format:0x%4.4x channels:%d %dHz %dKo/s "
GetWLE( &p_wf->wFormatTag ), "blockalign:%d bits/samples:%d extra size:%d",
p_sys->fmt.audio.i_channels, GetWLE( &p_wf->wFormatTag ), p_sys->fmt.audio.i_channels,
p_sys->fmt.audio.i_rate, p_sys->fmt.audio.i_rate, p_sys->fmt.i_bitrate / 8 / 1024,
p_sys->fmt.i_bitrate / 8 / 1024, p_sys->fmt.audio.i_blockalign, p_sys->fmt.audio.i_bitspersample,
p_sys->fmt.audio.i_blockalign, p_sys->fmt.i_extra );
p_sys->fmt.audio.i_bitspersample,
p_sys->fmt.i_extra );
free( p_wf ); free( p_wf );
switch( p_sys->fmt.i_codec ) switch( p_sys->fmt.i_codec )
{ {
case VLC_FOURCC( 'a', 'r', 'a', 'w' ): case VLC_FOURCC( 'a', 'r', 'a', 'w' ):
case VLC_FOURCC( 'u', 'l', 'a', 'w' ): case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
case VLC_FOURCC( 'a', 'l', 'a', 'w' ): case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
FrameInfo_PCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length ); FrameInfo_PCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length );
break; break;
case VLC_FOURCC( 'm', 's', 0x00, 0x02 ): case VLC_FOURCC( 'm', 's', 0x00, 0x02 ):
FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length ); FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size,
break; &p_sys->i_frame_length );
case VLC_FOURCC( 'm', 's', 0x00, 0x11 ): break;
FrameInfo_IMA_ADPCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length ); case VLC_FOURCC( 'm', 's', 0x00, 0x11 ):
break; FrameInfo_IMA_ADPCM( p_input, &p_sys->i_frame_size,
case VLC_FOURCC( 'm', 's', 0x00, 0x61 ): &p_sys->i_frame_length );
case VLC_FOURCC( 'm', 's', 0x00, 0x62 ): break;
/* FIXME not sure at all FIXME */ case VLC_FOURCC( 'm', 's', 0x00, 0x61 ):
FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size, &p_sys->i_frame_length ); case VLC_FOURCC( 'm', 's', 0x00, 0x62 ):
break; /* FIXME not sure at all FIXME */
case VLC_FOURCC( 'm', 'p', 'g', 'a' ): FrameInfo_MS_ADPCM( p_input, &p_sys->i_frame_size,
case VLC_FOURCC( 'a', '5', '2', ' ' ): &p_sys->i_frame_length );
/* FIXME set end of area FIXME */ break;
goto relay; case VLC_FOURCC( 'm', 'p', 'g', 'a' ):
default: case VLC_FOURCC( 'a', '5', '2', ' ' ):
msg_Err( p_input, "unsupported codec (%4.4s)", (char*)&p_sys->fmt.i_codec ); /* FIXME set end of area FIXME */
goto error; 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 ); msg_Dbg( p_input, "found %s audio format", psz_name );
...@@ -196,7 +197,7 @@ static int Open( vlc_object_t * p_this ) ...@@ -196,7 +197,7 @@ static int Open( vlc_object_t * p_this )
stream_Read( p_input->s, NULL, 8 ); /* cannot fail */ stream_Read( p_input->s, NULL, 8 ); /* cannot fail */
/* create one program */ /* Create one program */
vlc_mutex_lock( &p_input->stream.stream_lock ); vlc_mutex_lock( &p_input->stream.stream_lock );
if( input_InitStream( p_input, 0 ) == -1) if( input_InitStream( p_input, 0 ) == -1)
{ {
...@@ -204,11 +205,16 @@ static int Open( vlc_object_t * p_this ) ...@@ -204,11 +205,16 @@ static int Open( vlc_object_t * p_this )
msg_Err( p_input, "cannot init stream" ); msg_Err( p_input, "cannot init stream" );
goto error; goto error;
} }
p_input->stream.i_mux_rate = 0; 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 * 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 ); vlc_mutex_unlock( &p_input->stream.stream_lock );
...@@ -228,25 +234,28 @@ relay: ...@@ -228,25 +234,28 @@ relay:
*****************************************************************************/ *****************************************************************************/
static int Demux( input_thread_t *p_input ) static int Demux( input_thread_t *p_input )
{ {
demux_sys_t *p_sys = p_input->p_demux_data; demux_sys_t *p_sys = p_input->p_demux_data;
int64_t i_pos; int64_t i_pos;
block_t *p_block; block_t *p_block;
if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT ) if( p_input->stream.p_selected_program->i_synchro_state == SYNCHRO_REINIT )
{ {
i_pos = stream_Tell( p_input->s ); 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; i_pos = p_sys->fmt.audio.i_blockalign -
if( stream_Seek( p_input->s, i_pos ) ) 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)" ); msg_Err( p_input, "stream_Sekk failed (cannot resync)" );
} }
} }
} }
input_ClockManageRef( p_input, input_ClockManageRef( p_input, p_input->stream.p_selected_program,
p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 ); p_sys->i_time * 9 / 100 );
i_pos = stream_Tell( p_input->s ); i_pos = stream_Tell( p_input->s );
...@@ -265,14 +274,14 @@ static int Demux( input_thread_t *p_input ) ...@@ -265,14 +274,14 @@ static int Demux( input_thread_t *p_input )
} }
p_block->i_dts = p_block->i_dts =
p_block->i_pts = input_ClockGetTS( p_input, p_block->i_pts = input_ClockGetTS( p_input,
p_input->stream.p_selected_program, p_input->stream.p_selected_program,
p_sys->i_time * 9 / 100 ); p_sys->i_time * 9 / 100 );
es_out_Send( p_input->p_es_out, p_sys->p_es, p_block ); es_out_Send( p_input->p_es_out, p_sys->p_es, p_block );
p_sys->i_time += p_sys->i_frame_length; 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 ) ...@@ -286,14 +295,13 @@ static void Close ( vlc_object_t * p_this )
free( p_sys ); free( p_sys );
} }
/***************************************************************************** /*****************************************************************************
* Local functions * Local functions
*****************************************************************************/ *****************************************************************************/
static int ChunkFind( input_thread_t *p_input, static int ChunkFind( input_thread_t *p_input,
char *fcc, unsigned int *pi_size ) char *fcc, unsigned int *pi_size )
{ {
uint8_t *p_peek; uint8_t *p_peek;
for( ;; ) for( ;; )
{ {
...@@ -345,7 +353,8 @@ static void FrameInfo_PCM( input_thread_t *p_input, ...@@ -345,7 +353,8 @@ static void FrameInfo_PCM( input_thread_t *p_input,
(mtime_t)i_samples / (mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate; (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 ) if( p_sys->fmt.audio.i_blockalign > 0 )
{ {
...@@ -354,42 +363,40 @@ static void FrameInfo_PCM( input_thread_t *p_input, ...@@ -354,42 +363,40 @@ static void FrameInfo_PCM( input_thread_t *p_input,
i_bytes += p_sys->fmt.audio.i_blockalign - i_modulo; i_bytes += p_sys->fmt.audio.i_blockalign - i_modulo;
} }
} }
*pi_size = i_bytes; *pi_size = i_bytes;
} }
static void FrameInfo_MS_ADPCM( input_thread_t *p_input, static void FrameInfo_MS_ADPCM( input_thread_t *p_input,
unsigned int *pi_size, unsigned int *pi_size,
mtime_t *pi_length ) 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; int i_samples;
i_samples = 2 + 2 * ( p_sys->fmt.audio.i_blockalign - 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 * *pi_length = (mtime_t)1000000 * (mtime_t)i_samples /
(mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate; (mtime_t)p_sys->fmt.audio.i_rate;
*pi_size = p_sys->fmt.audio.i_blockalign; *pi_size = p_sys->fmt.audio.i_blockalign;
} }
static void FrameInfo_IMA_ADPCM( input_thread_t *p_input, static void FrameInfo_IMA_ADPCM( input_thread_t *p_input,
unsigned int *pi_size, unsigned int *pi_size,
mtime_t *pi_length ) 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; int i_samples;
i_samples = 2 * ( p_sys->fmt.audio.i_blockalign - 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 * *pi_length = (mtime_t)1000000 * (mtime_t)i_samples /
(mtime_t)i_samples /
(mtime_t)p_sys->fmt.audio.i_rate; (mtime_t)p_sys->fmt.audio.i_rate;
*pi_size = p_sys->fmt.audio.i_blockalign; *pi_size = p_sys->fmt.audio.i_blockalign;
} }
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* vout.c: Windows DirectX video output display method * vout.c: Windows DirectX video output display method
***************************************************************************** *****************************************************************************
* Copyright (C) 2001-2004 VideoLAN * 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> * Authors: Gildas Bazin <gbazin@netcourrier.com>
* *
...@@ -138,6 +138,7 @@ vlc_module_begin(); ...@@ -138,6 +138,7 @@ vlc_module_begin();
add_string( "directx-device", "", NULL, DEVICE_TEXT, DEVICE_LONGTEXT, add_string( "directx-device", "", NULL, DEVICE_TEXT, DEVICE_LONGTEXT,
VLC_TRUE ); VLC_TRUE );
change_string_list( ppsz_dev, ppsz_dev_text, FindDevicesCallback ); change_string_list( ppsz_dev, ppsz_dev_text, FindDevicesCallback );
change_action_add( FindDevicesCallback, N_("Refresh list") );
set_description( _("DirectX video output") ); set_description( _("DirectX video output") );
set_capability( "video output", 100 ); set_capability( "video output", 100 );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment