[vlc-devel] [PATCH 9/9] converter: spdif: add EAC3 support
Thomas Guillem
thomas at gllm.fr
Thu Sep 1 10:54:16 CEST 2016
---
modules/audio_filter/converter/tospdif.c | 58 +++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/modules/audio_filter/converter/tospdif.c b/modules/audio_filter/converter/tospdif.c
index da34a81..d147c9d 100644
--- a/modules/audio_filter/converter/tospdif.c
+++ b/modules/audio_filter/converter/tospdif.c
@@ -37,6 +37,8 @@
#include <vlc_aout.h>
#include <vlc_filter.h>
+#include "../packetizer/a52.h"
+
static int Open( vlc_object_t * );
static void Close( vlc_object_t * );
@@ -53,9 +55,18 @@ struct filter_sys_t
block_t *p_first;
block_t **pp_last;
unsigned i_total_samples;
+
+ union
+ {
+ struct
+ {
+ unsigned int i_nb_blocks_substream0;
+ } eac3;
+ } spec;
};
#define IEC61937_AC3 0x01
+#define IEC61937_EAC3 0x15
#define IEC61937_DTS1 0x0B
#define IEC61937_DTS2 0x0C
#define IEC61937_DTS3 0x0D
@@ -84,6 +95,45 @@ static int parse_header_ac3( filter_t *p_filter, block_t *p_in,
return SPDIF_SUCCESS;
}
+static int parse_header_eac3( filter_t *p_filter, block_t *p_in,
+ struct hdr_res *p_res )
+{
+ filter_sys_t *p_sys = p_filter->p_sys;
+
+ vlc_a52_header_t a52 = { };
+ if( vlc_a52_header_Parse( &a52, p_in->p_buffer, p_in->i_buffer )
+ != VLC_SUCCESS )
+ return SPDIF_ERROR;
+
+ p_in->i_buffer = a52.i_size;
+ p_in->i_nb_samples = a52.i_samples;
+
+ if( a52.b_eac3 )
+ {
+ if( ( a52.eac3.strmtyp == EAC3_STRMTYP_INDEPENDENT
+ || a52.eac3.strmtyp == EAC3_STRMTYP_AC3_CONVERT )
+ && a52.i_blocks_per_sync_frame != 6 )
+ {
+ /* cf. Annex E 2.3.1.2 of AC3 spec */
+ if( a52.eac3.i_substreamid == 0 )
+ p_sys->spec.eac3.i_nb_blocks_substream0
+ += a52.i_blocks_per_sync_frame;
+
+ if( p_sys->spec.eac3.i_nb_blocks_substream0 != 6 )
+ return SPDIF_MORE_DATA;
+ else
+ p_sys->spec.eac3.i_nb_blocks_substream0 = 0;
+ }
+ p_res->i_out_size_padded = AOUT_SPDIF_SIZE * 4;
+ p_res->i_data_type = IEC61937_EAC3;
+ p_res->i_length_mul = 1; /* in bytes */
+ return SPDIF_SUCCESS;
+ }
+ else
+ return SPDIF_MORE_DATA;
+
+}
+
static int parse_header_dts( filter_t *p_filter, block_t *p_in,
struct hdr_res *p_res )
{
@@ -116,6 +166,8 @@ static int parse_header( filter_t *p_filter, block_t *p_in,
{
case VLC_CODEC_A52:
return parse_header_ac3( p_filter, p_in, p_res );
+ case VLC_CODEC_EAC3:
+ return parse_header_eac3( p_filter, p_in, p_res );
case VLC_CODEC_DTS:
return parse_header_dts( p_filter, p_in, p_res );
default:
@@ -128,6 +180,7 @@ static bool is_big_endian( filter_t *p_filter, block_t *p_in )
switch( p_filter->fmt_in.audio.i_format )
{
case VLC_CODEC_A52:
+ case VLC_CODEC_EAC3:
return true;
case VLC_CODEC_DTS:
return p_in->p_buffer[0] == 0x1F || p_in->p_buffer[0] == 0x7F;
@@ -147,6 +200,7 @@ static void Flush( filter_t *p_filter )
p_sys->pp_last = &p_sys->p_first;
p_sys->i_total_samples = 0;
}
+ memset( &p_sys->spec, 0, sizeof( p_sys->spec ) );
}
static block_t *DoWork( filter_t *p_filter, block_t *p_in_buf )
@@ -251,7 +305,8 @@ static int Open( vlc_object_t *p_this )
filter_sys_t *p_sys;
if( ( p_filter->fmt_in.audio.i_format != VLC_CODEC_DTS &&
- p_filter->fmt_in.audio.i_format != VLC_CODEC_A52 ) ||
+ p_filter->fmt_in.audio.i_format != VLC_CODEC_A52 &&
+ p_filter->fmt_in.audio.i_format != VLC_CODEC_EAC3 ) ||
( p_filter->fmt_out.audio.i_format != VLC_CODEC_SPDIFL &&
p_filter->fmt_out.audio.i_format != VLC_CODEC_SPDIFB ) )
return VLC_EGENERIC;
@@ -262,6 +317,7 @@ static int Open( vlc_object_t *p_this )
p_sys->p_first = NULL;
p_sys->pp_last = &p_sys->p_first;
p_sys->i_total_samples = 0;
+ memset( &p_sys->spec, 0, sizeof( p_sys->spec ) );
p_filter->pf_audio_filter = DoWork;
p_filter->pf_flush = Flush;
--
2.9.3
More information about the vlc-devel
mailing list