164 lines
5.6 KiB
Plaintext
164 lines
5.6 KiB
Plaintext
$OpenBSD: patch-modules_codec_avcodec_audio_c,v 1.1 2013/03/09 09:32:03 brad Exp $
|
|
--- modules/codec/avcodec/audio.c.orig Fri Mar 8 16:28:52 2013
|
|
+++ modules/codec/avcodec/audio.c Fri Mar 8 16:29:02 2013
|
|
@@ -29,6 +29,8 @@
|
|
# include "config.h"
|
|
#endif
|
|
|
|
+#include <assert.h>
|
|
+
|
|
#include <vlc_common.h>
|
|
#include <vlc_aout.h>
|
|
#include <vlc_codec.h>
|
|
@@ -81,6 +83,42 @@ struct decoder_sys_t
|
|
int64_t i_previous_layout;
|
|
};
|
|
|
|
+/**
|
|
+ * Interleaves audio samples within a block of samples.
|
|
+ * \param dst destination buffer for interleaved samples
|
|
+ * \param src source buffer with consecutive planes of samples
|
|
+ * \param samples number of samples (per channel/per plane)
|
|
+ * \param chans channels/planes count
|
|
+ * \param fourcc sample format (must be a linear sample format)
|
|
+ * \note The samples must be naturally aligned in memory.
|
|
+ * \warning Destination and source buffers MUST NOT overlap.
|
|
+ */
|
|
+static void Interleave( void *restrict dst, const void *restrict src,
|
|
+ unsigned samples, unsigned chans, vlc_fourcc_t fourcc )
|
|
+{
|
|
+#define INTERLEAVE_TYPE(type) \
|
|
+do { \
|
|
+ type *d = dst; \
|
|
+ const type *s = src; \
|
|
+ for( size_t i = 0; i < chans; i++ ) { \
|
|
+ for( size_t j = 0, k = 0; j < samples; j++, k += chans ) \
|
|
+ d[k] = *(s++); \
|
|
+ d++; \
|
|
+ } \
|
|
+} while(0)
|
|
+
|
|
+ switch( fourcc )
|
|
+ {
|
|
+ case VLC_CODEC_U8: INTERLEAVE_TYPE(uint8_t); break;
|
|
+ case VLC_CODEC_S16N: INTERLEAVE_TYPE(uint16_t); break;
|
|
+ case VLC_CODEC_FL32: INTERLEAVE_TYPE(float); break;
|
|
+ case VLC_CODEC_S32N: INTERLEAVE_TYPE(int32_t); break;
|
|
+ case VLC_CODEC_FL64: INTERLEAVE_TYPE(double); break;
|
|
+ default: assert(0);
|
|
+ }
|
|
+#undef INTERLEAVE_TYPE
|
|
+}
|
|
+
|
|
#define BLOCK_FLAG_PRIVATE_REALLOCATED (1 << BLOCK_FLAG_PRIVATE_SHIFT)
|
|
|
|
static void SetupOutputFormat( decoder_t *p_dec, bool b_trust );
|
|
@@ -230,6 +268,7 @@ static aout_buffer_t *SplitBuffer( decoder_t *p_dec )
|
|
{
|
|
decoder_sys_t *p_sys = p_dec->p_sys;
|
|
int i_samples = __MIN( p_sys->i_samples, 4096 );
|
|
+ int sample_planar=0;
|
|
aout_buffer_t *p_buffer;
|
|
|
|
if( i_samples == 0 ) return NULL;
|
|
@@ -241,16 +280,26 @@ static aout_buffer_t *SplitBuffer( decoder_t *p_dec )
|
|
p_buffer->i_length = date_Increment( &p_sys->end_date, i_samples )
|
|
- p_buffer->i_pts;
|
|
|
|
+ sample_planar = av_sample_fmt_is_planar( p_sys->p_context->sample_fmt );
|
|
+ if( sample_planar )
|
|
+ Interleave( p_buffer->p_buffer, p_sys->p_samples, i_samples, p_sys->p_context->channels, p_dec->fmt_out.audio.i_format );
|
|
+
|
|
if( p_sys->b_extract )
|
|
+ {
|
|
+ if( sample_planar )
|
|
+ memcpy( p_sys->p_samples, p_buffer->p_buffer, p_buffer->i_buffer );
|
|
+
|
|
aout_ChannelExtract( p_buffer->p_buffer, p_dec->fmt_out.audio.i_channels,
|
|
p_sys->p_samples, p_sys->p_context->channels, i_samples,
|
|
p_sys->pi_extraction, p_dec->fmt_out.audio.i_bitspersample );
|
|
- else
|
|
+ }
|
|
+ else if (!sample_planar)
|
|
memcpy( p_buffer->p_buffer, p_sys->p_samples, p_buffer->i_buffer );
|
|
|
|
p_sys->p_samples += i_samples * p_sys->p_context->channels * ( p_dec->fmt_out.audio.i_bitspersample / 8 );
|
|
p_sys->i_samples -= i_samples;
|
|
|
|
+
|
|
return p_buffer;
|
|
}
|
|
|
|
@@ -416,33 +465,25 @@ void EndAudioDec( decoder_t *p_dec )
|
|
*
|
|
*****************************************************************************/
|
|
|
|
-void GetVlcAudioFormat( vlc_fourcc_t *pi_codec, unsigned *pi_bits, int i_sample_fmt )
|
|
+vlc_fourcc_t GetVlcAudioFormat( int fmt )
|
|
{
|
|
- switch( i_sample_fmt )
|
|
- {
|
|
- case AV_SAMPLE_FMT_U8:
|
|
- *pi_codec = VLC_CODEC_U8;
|
|
- *pi_bits = 8;
|
|
- break;
|
|
- case AV_SAMPLE_FMT_S32:
|
|
- *pi_codec = VLC_CODEC_S32N;
|
|
- *pi_bits = 32;
|
|
- break;
|
|
- case AV_SAMPLE_FMT_FLT:
|
|
- *pi_codec = VLC_CODEC_FL32;
|
|
- *pi_bits = 32;
|
|
- break;
|
|
- case AV_SAMPLE_FMT_DBL:
|
|
- *pi_codec = VLC_CODEC_FL64;
|
|
- *pi_bits = 64;
|
|
- break;
|
|
-
|
|
- case AV_SAMPLE_FMT_S16:
|
|
- default:
|
|
- *pi_codec = VLC_CODEC_S16N;
|
|
- *pi_bits = 16;
|
|
- break;
|
|
- }
|
|
+ static const vlc_fourcc_t fcc[] = {
|
|
+ [AV_SAMPLE_FMT_U8] = VLC_CODEC_U8,
|
|
+ [AV_SAMPLE_FMT_S16] = VLC_CODEC_S16N,
|
|
+ [AV_SAMPLE_FMT_S32] = VLC_CODEC_S32N,
|
|
+ [AV_SAMPLE_FMT_FLT] = VLC_CODEC_FL32,
|
|
+ [AV_SAMPLE_FMT_DBL] = VLC_CODEC_FL64,
|
|
+#ifdef HAVE_AVUTIL_PLANAR
|
|
+ [AV_SAMPLE_FMT_U8P] = VLC_CODEC_U8,
|
|
+ [AV_SAMPLE_FMT_S16P] = VLC_CODEC_S16N,
|
|
+ [AV_SAMPLE_FMT_S32P] = VLC_CODEC_S32N,
|
|
+ [AV_SAMPLE_FMT_FLTP] = VLC_CODEC_FL32,
|
|
+ [AV_SAMPLE_FMT_DBLP] = VLC_CODEC_FL64,
|
|
+#endif
|
|
+ };
|
|
+ if( (sizeof(fcc) / sizeof(fcc[0])) > (unsigned)fmt )
|
|
+ return fcc[fmt];
|
|
+ return VLC_CODEC_S16N;
|
|
}
|
|
|
|
static const uint64_t pi_channels_map[][2] =
|
|
@@ -473,9 +514,8 @@ static void SetupOutputFormat( decoder_t *p_dec, bool
|
|
{
|
|
decoder_sys_t *p_sys = p_dec->p_sys;
|
|
|
|
- GetVlcAudioFormat( &p_dec->fmt_out.i_codec,
|
|
- &p_dec->fmt_out.audio.i_bitspersample,
|
|
- p_sys->p_context->sample_fmt );
|
|
+ p_dec->fmt_out.i_codec = GetVlcAudioFormat( p_sys->p_context->sample_fmt );
|
|
+ p_dec->fmt_out.audio.i_format = p_dec->fmt_out.i_codec;
|
|
p_dec->fmt_out.audio.i_rate = p_sys->p_context->sample_rate;
|
|
|
|
/* */
|
|
@@ -527,6 +567,6 @@ static void SetupOutputFormat( decoder_t *p_dec, bool
|
|
|
|
p_dec->fmt_out.audio.i_physical_channels =
|
|
p_dec->fmt_out.audio.i_original_channels = i_layout_dst;
|
|
- p_dec->fmt_out.audio.i_channels = i_channels_dst;
|
|
+ aout_FormatPrepare( &p_dec->fmt_out.audio );
|
|
}
|
|
|