[vlc-commits] converter/tospdif: fix eac3 with dependent streams
Thomas Guillem
git at videolan.org
Wed Apr 11 13:19:44 CEST 2018
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Wed Apr 11 12:18:31 2018 +0200| [36a5138cc0b046be4a73157c04b2d5a70f7e54be] | committer: Thomas Guillem
converter/tospdif: fix eac3 with dependent streams
cf. comment.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=36a5138cc0b046be4a73157c04b2d5a70f7e54be
---
modules/audio_filter/converter/tospdif.c | 66 ++++++++++++++++++++------------
1 file changed, 42 insertions(+), 24 deletions(-)
diff --git a/modules/audio_filter/converter/tospdif.c b/modules/audio_filter/converter/tospdif.c
index 7c757cb606..9ca72441c5 100644
--- a/modules/audio_filter/converter/tospdif.c
+++ b/modules/audio_filter/converter/tospdif.c
@@ -60,7 +60,7 @@ struct filter_sys_t
{
struct
{
- unsigned int i_nb_blocks_substream0;
+ unsigned int i_nb_blocks;
} eac3;
struct
{
@@ -245,17 +245,46 @@ static int write_buffer_ac3( filter_t *p_filter, block_t *p_in_buf )
return SPDIF_SUCCESS;
}
+
static int write_buffer_eac3( filter_t *p_filter, block_t *p_in_buf )
{
filter_sys_t *p_sys = p_filter->p_sys;
- vlc_a52_header_t a52 = { };
+ /* The input block can contain the following:
+ * a/ One EAC3 independent stream (with 1, 2, 3 or 6 audio blocks per
+ * syncframe)
+ * b/ One AC3 stream followed by one EAC3 dependent stream (with 6 audio
+ * blocks per syncframe)
+ * c/ One EAC3 independent stream followed by one EAC3 dependent stream
+ * (with 1, 2, 3 or 6 audio blocks per syncframe)
+ *
+ * One IEC61937_EAC3 frame must contain 6 audio blocks per syncframe. This
+ * function will gather input blocks until it reaches this amount of audio
+ * blocks.
+ *
+ * Example: for the c/ case with 1 audio blocks per syncframe, a
+ * IEC61937_EAC3 frame will contain 12 a52 streams: 6 independent + 6
+ * dependent EAC3 streams.
+ */
+
+ vlc_a52_header_t a52;
if( vlc_a52_header_Parse( &a52, p_in_buf->p_buffer, p_in_buf->i_buffer )
!= VLC_SUCCESS || a52.i_size > p_in_buf->i_buffer )
return SPDIF_ERROR;
- p_in_buf->i_buffer = a52.i_size;
- p_in_buf->i_nb_samples = a52.i_samples;
+ if( p_in_buf->i_buffer > a52.i_size )
+ {
+ /* Check if the next stream is an eac3 dependent one */
+ vlc_a52_header_t a52_dep;
+ const uint8_t *dep_buf = &p_in_buf->p_buffer[a52.i_size];
+ const size_t dep_size = p_in_buf->i_buffer - a52.i_size;
+
+ if( vlc_a52_header_Parse( &a52_dep, dep_buf, dep_size ) != VLC_SUCCESS
+ || a52_dep.i_size > dep_size
+ || !a52_dep.b_eac3 || a52_dep.eac3.strmtyp != EAC3_STRMTYP_DEPENDENT
+ || p_in_buf->i_buffer > a52.i_size + a52_dep.i_size )
+ return SPDIF_ERROR;
+ }
if( !p_sys->p_out_buf
&& write_init( p_filter, p_in_buf, AOUT_SPDIF_SIZE * 4, AOUT_SPDIF_SIZE ) )
@@ -265,28 +294,17 @@ static int write_buffer_eac3( filter_t *p_filter, block_t *p_in_buf )
write_buffer( p_filter, p_in_buf );
- 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->eac3.i_nb_blocks_substream0
- += a52.i_blocks_per_sync_frame;
+ /* cf. Annex E 2.3 of AC3 spec */
+ p_sys->eac3.i_nb_blocks += a52.i_blocks_per_sync_frame;
- if( p_sys->eac3.i_nb_blocks_substream0 != 6 )
- return SPDIF_MORE_DATA;
- else
- p_sys->eac3.i_nb_blocks_substream0 = 0;
- }
- write_finalize( p_filter, IEC61937_EAC3, 1 /* in bytes */ );
- return SPDIF_SUCCESS;
- }
- else
+ if( p_sys->eac3.i_nb_blocks < 6 )
return SPDIF_MORE_DATA;
+ else if ( p_sys->eac3.i_nb_blocks > 6 )
+ return SPDIF_ERROR;
+ write_finalize( p_filter, IEC61937_EAC3, 1 /* in bytes */ );
+ p_sys->eac3.i_nb_blocks = 0;
+ return SPDIF_SUCCESS;
}
/* Adapted from libavformat/spdifenc.c:
@@ -513,7 +531,7 @@ static void Flush( filter_t *p_filter )
p_sys->truehd.i_frame_count = 0;
break;
case VLC_CODEC_EAC3:
- p_sys->eac3.i_nb_blocks_substream0 = 0;
+ p_sys->eac3.i_nb_blocks = 0;
break;
default:
break;
More information about the vlc-commits
mailing list