extern "C" {
#include "../vobsub.h"
#include "../xiph.h"
+#include "../windows_audio_commons.h"
}
#include <vlc_codecs.h>
else
{
WAVEFORMATEX *p_wf = (WAVEFORMATEX*)p_tk->p_extra_data;
- if( p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
- p_tk->i_extra_data >= sizeof(WAVEFORMATEXTENSIBLE) )
- {
- WAVEFORMATEXTENSIBLE * p_wext = (WAVEFORMATEXTENSIBLE*) p_wf;
- sf_tag_to_fourcc( &p_wext->SubFormat, &p_tk->fmt.i_codec, NULL);
- /* FIXME should we use Samples and dwChannelMask?*/
- }
- else
- wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_tk->fmt.i_codec, NULL );
- if( p_tk->fmt.i_codec == VLC_FOURCC( 'u', 'n', 'd', 'f' ) )
- msg_Err( &sys.demuxer, "Unrecognized wf tag: 0x%x", GetWLE( &p_wf->wFormatTag ) );
p_tk->fmt.audio.i_channels = GetWLE( &p_wf->nChannels );
p_tk->fmt.audio.i_rate = GetDWLE( &p_wf->nSamplesPerSec );
p_tk->fmt.i_bitrate = GetDWLE( &p_wf->nAvgBytesPerSec ) * 8;
if( p_tk->fmt.i_extra > 0 )
{
p_tk->fmt.p_extra = xmalloc( p_tk->fmt.i_extra );
- memcpy( p_tk->fmt.p_extra, &p_wf[1], p_tk->fmt.i_extra );
+ if( p_tk->fmt.p_extra )
+ memcpy( p_tk->fmt.p_extra, &p_wf[1], p_tk->fmt.i_extra );
+ else
+ p_tk->fmt.i_extra = 0;
}
+
+ if( p_wf->wFormatTag == WAVE_FORMAT_EXTENSIBLE &&
+ p_tk->i_extra_data >= sizeof(WAVEFORMATEXTENSIBLE) )
+ {
+ WAVEFORMATEXTENSIBLE * p_wext = (WAVEFORMATEXTENSIBLE*) p_wf;
+ sf_tag_to_fourcc( &p_wext->SubFormat, &p_tk->fmt.i_codec, NULL);
+ /* FIXME should we use Samples */
+
+ if( p_tk->fmt.audio.i_channels > 2 &&
+ ( p_tk->fmt.i_codec != VLC_FOURCC( 'u', 'n', 'd', 'f' ) ) )
+ {
+ uint32_t wfextcm = GetDWLE( &p_wext->dwChannelMask );
+ int match;
+ unsigned i_channel_mask = getChannelMask( &wfextcm,
+ p_tk->fmt.audio.i_channels,
+ &match );
+ p_tk->fmt.i_codec = vlc_fourcc_GetCodecAudio( p_tk->fmt.i_codec,
+ p_tk->fmt.audio.i_bitspersample );
+ if( i_channel_mask )
+ {
+ p_tk->i_chans_to_reorder = aout_CheckChannelReorder(
+ pi_channels_aout, NULL,
+ i_channel_mask,
+ p_tk->pi_chan_table );
+
+ p_tk->fmt.audio.i_physical_channels =
+ p_tk->fmt.audio.i_original_channels = i_channel_mask;
+ }
+ }
+ }
+ else
+ wf_tag_to_fourcc( GetWLE( &p_wf->wFormatTag ), &p_tk->fmt.i_codec, NULL );
+
+ if( p_tk->fmt.i_codec == VLC_FOURCC( 'u', 'n', 'd', 'f' ) )
+ msg_Err( &sys.demuxer, "Unrecognized wf tag: 0x%x", GetWLE( &p_wf->wFormatTag ) );
}
}
else if( !strcmp( p_tk->psz_codec, "A_MPEG/L3" ) ||
p_block->i_length = -1 * i_duration * tk->fmt.audio.i_rate
/ CLOCK_FREQ;
}
+ break;
}
- if ( tk->fmt.i_cat == NAV_ES )
- {
- // TODO handle the start/stop times of this packet
- p_sys->p_ev->SetPci( (const pci_t *)&p_block->p_buffer[1]);
- block_Release( p_block );
- return;
- }
- // correct timestamping when B frames are used
+
if( tk->fmt.i_cat != VIDEO_ES )
{
+ if ( tk->fmt.i_cat == NAV_ES )
+ {
+ // TODO handle the start/stop times of this packet
+ p_sys->p_ev->SetPci( (const pci_t *)&p_block->p_buffer[1]);
+ block_Release( p_block );
+ return;
+ }
+ else if( tk->fmt.i_cat == AUDIO_ES )
+ {
+ if( tk->i_chans_to_reorder )
+ aout_ChannelReorder( p_block->p_buffer, p_block->i_buffer,
+ tk->fmt.audio.i_channels,
+ tk->pi_chan_table, tk->fmt.i_codec );
+
+ }
p_block->i_dts = p_block->i_pts = i_pts;
}
else
{
+ // correct timestamping when B frames are used
if( tk->b_dts_only )
{
p_block->i_pts = VLC_TS_INVALID;
#include <vlc_charset.h>
#include <vlc_input.h>
#include <vlc_demux.h>
+#include <vlc_aout.h> /* For reordering */
#include <iostream>
#include <cassert>
/* audio */
unsigned int i_original_rate;
+ uint8_t i_chans_to_reorder; /* do we need channel reordering */
+ uint8_t pi_chan_table[AOUT_CHAN_MAX];
+
/* Private track paramters */
PrivateTrackData *p_sys;
#include <vlc_aout.h>
#include <vlc_codecs.h>
+#include "windows_audio_commons.h"
+
/*****************************************************************************
* Module descriptor
*****************************************************************************/
static int FrameInfo_PCM ( unsigned int *, int *, const es_format_t * );
static int FrameInfo_MSGSM ( unsigned int *, int *, const es_format_t * );
-static const uint32_t pi_channels_src[] =
- { WAVE_SPEAKER_FRONT_LEFT, WAVE_SPEAKER_FRONT_RIGHT,
- WAVE_SPEAKER_FRONT_CENTER, WAVE_SPEAKER_LOW_FREQUENCY,
- WAVE_SPEAKER_BACK_LEFT, WAVE_SPEAKER_BACK_RIGHT, WAVE_SPEAKER_BACK_CENTER,
- WAVE_SPEAKER_SIDE_LEFT, WAVE_SPEAKER_SIDE_RIGHT, 0 };
-static const uint32_t pi_channels_in[] =
- { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
- AOUT_CHAN_CENTER, AOUT_CHAN_LFE,
- AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_REARCENTER,
- AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, 0 };
-
/*****************************************************************************
* Open: check file and initializes structures
*****************************************************************************/
if( i_channel_mask )
{
int i_match = 0;
- for( unsigned i = 0; i < sizeof(pi_channels_src)/sizeof(*pi_channels_src); i++ )
- {
- if( i_channel_mask & pi_channels_src[i] )
- {
- if( !( p_sys->i_channel_mask & pi_channels_in[i] ) )
- i_match++;
-
- i_channel_mask &= ~pi_channels_src[i];
- p_sys->i_channel_mask |= pi_channels_in[i];
-
- if( i_match >= p_sys->fmt.audio.i_channels )
- break;
- }
- }
+ p_sys->i_channel_mask = getChannelMask( &i_channel_mask, p_sys->fmt.audio.i_channels, &i_match );
if( i_channel_mask )
msg_Warn( p_demux, "Some channels are unrecognized or uselessly specified (0x%x)", i_channel_mask );
if( i_match < p_sys->fmt.audio.i_channels )
}
}
/* Well fill up with what we can */
- for( unsigned i = 0; i < sizeof(pi_channels_in)/sizeof(*pi_channels_in) && i_missing > 0; i++ )
+ for( unsigned i = 0; i < sizeof(pi_channels_aout)/sizeof(*pi_channels_aout) && i_missing > 0; i++ )
{
- if( !( p_sys->i_channel_mask & pi_channels_in[i] ) )
+ if( !( p_sys->i_channel_mask & pi_channels_aout[i] ) )
{
- p_sys->i_channel_mask |= pi_channels_in[i];
+ p_sys->i_channel_mask |= pi_channels_aout[i];
i_missing--;
if( i_missing <= 0 )
p_sys->fmt.audio.i_channels > 2 && p_sys->fmt.audio.i_channels <= 9 )
{
for( int i = 0; i < p_sys->fmt.audio.i_channels; i++ )
- p_sys->i_channel_mask |= pi_channels_in[i];
+ p_sys->i_channel_mask |= pi_channels_aout[i];
}
if( p_sys->i_channel_mask )
if( p_sys->fmt.i_codec == VLC_FOURCC('a','r','a','w') ||
p_sys->fmt.i_codec == VLC_FOURCC('a','f','l','t') )
p_sys->i_chans_to_reorder =
- aout_CheckChannelReorder( pi_channels_in, NULL,
+ aout_CheckChannelReorder( pi_channels_aout, NULL,
p_sys->i_channel_mask,
p_sys->pi_chan_table );
--- /dev/null
+/*****************************************************************************
+ * windows_audio_common.h: Windows Audio common code
+ *****************************************************************************
+ * Copyright (C) 2001-2013 VideoLAN
+ * $Id$
+ *
+ * Authors: Denis Charmet <typx@videolan.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+#ifndef DMX_WINDOWS_AUDIO_COMMONS_H
+#define DMX_WINDOWS_AUDIO_COMMONS_H
+
+#include <vlc_aout.h>
+#include <vlc_codecs.h>
+
+static const uint32_t pi_channels_src[] = { WAVE_SPEAKER_FRONT_LEFT,
+ WAVE_SPEAKER_FRONT_RIGHT, WAVE_SPEAKER_FRONT_CENTER,
+ WAVE_SPEAKER_LOW_FREQUENCY, WAVE_SPEAKER_BACK_LEFT, WAVE_SPEAKER_BACK_RIGHT,
+ WAVE_SPEAKER_BACK_CENTER, WAVE_SPEAKER_SIDE_LEFT, WAVE_SPEAKER_SIDE_RIGHT, 0 };
+
+static const uint32_t pi_channels_aout[] = { AOUT_CHAN_LEFT, AOUT_CHAN_RIGHT,
+ AOUT_CHAN_CENTER, AOUT_CHAN_LFE, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
+ AOUT_CHAN_REARCENTER, AOUT_CHAN_MIDDLELEFT, AOUT_CHAN_MIDDLERIGHT, 0 };
+
+static inline unsigned getChannelMask( uint32_t * wvfextChannelMask, int i_channels, int * i_match )
+{
+ unsigned i_channel_mask = 0;
+ *i_match = 0;
+ for( unsigned i = 0;
+ i < sizeof(pi_channels_src)/sizeof(*pi_channels_src) &&
+ *i_match < i_channels; i++ )
+ {
+ if( *wvfextChannelMask & pi_channels_src[i] )
+ {
+ if( !( i_channel_mask & pi_channels_aout[i] ) )
+ *i_match += 1;
+
+ *wvfextChannelMask &= ~pi_channels_src[i];
+ i_channel_mask |= pi_channels_aout[i];
+ }
+ }
+ return i_channel_mask;
+}
+
+#endif /*DMX_WINDOWS_AUDIO_COMMONS_H*/