openbsd-ports/x11/vlc/patches/patch-modules_codec_avcodec_audio_c
2013-03-09 09:32:03 +00:00

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 );
}