1 /*****************************************************************************
2 * tospdif.c : encapsulates A/52 and DTS frames into S/PDIF packets
3 *****************************************************************************
4 * Copyright (C) 2002, 2006-2016 VLC authors and VideoLAN
7 * Authors: Christophe Massiot <massiot@via.ecp.fr>
8 * Stéphane Borel <stef@via.ecp.fr>
13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU Lesser General Public License as published by
15 * the Free Software Foundation; either version 2.1 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License for more details.
23 * You should have received a copy of the GNU Lesser General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 *****************************************************************************/
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
38 #include <vlc_filter.h>
40 #include "../packetizer/a52.h"
41 #include "../packetizer/dts_header.h"
43 static int Open( vlc_object_t
* );
44 static void Close( vlc_object_t
* );
47 set_category( CAT_AUDIO
)
48 set_subcategory( SUBCAT_AUDIO_MISC
)
49 set_description( N_("Audio filter for A/52/DTS->S/PDIF encapsulation") )
50 set_capability( "audio converter", 10 )
51 set_callbacks( Open
, Close
)
63 unsigned int i_nb_blocks
;
67 unsigned int i_frame_count
;
76 #define SPDIF_HEADER_SIZE 8
78 #define IEC61937_AC3 0x01
79 #define IEC61937_EAC3 0x15
80 #define IEC61937_TRUEHD 0x16
81 #define IEC61937_DTS1 0x0B
82 #define IEC61937_DTS2 0x0C
83 #define IEC61937_DTS3 0x0D
84 #define IEC61937_DTSHD 0x11
86 #define SPDIF_MORE_DATA 1
87 #define SPDIF_SUCCESS VLC_SUCCESS
88 #define SPDIF_ERROR VLC_EGENERIC
90 static bool is_big_endian( filter_t
*p_filter
, block_t
*p_in_buf
)
92 switch( p_filter
->fmt_in
.audio
.i_format
)
97 case VLC_CODEC_TRUEHD
:
100 return p_in_buf
->p_buffer
[0] == 0x1F
101 || p_in_buf
->p_buffer
[0] == 0x7F;
103 vlc_assert_unreachable();
107 static void set_16( filter_t
*p_filter
, void *p_buf
, uint16_t i_val
)
109 if( p_filter
->fmt_out
.audio
.i_format
== VLC_CODEC_SPDIFB
)
110 SetWBE( p_buf
, i_val
);
112 SetWLE( p_buf
, i_val
);
115 static void write_16( filter_t
*p_filter
, uint16_t i_val
)
117 filter_sys_t
*p_sys
= p_filter
->p_sys
;
118 assert( p_sys
->p_out_buf
!= NULL
);
120 assert( p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
121 >= sizeof( uint16_t ) );
122 set_16( p_filter
, &p_sys
->p_out_buf
->p_buffer
[p_sys
->i_out_offset
], i_val
);
123 p_sys
->i_out_offset
+= sizeof( uint16_t );
126 static void write_padding( filter_t
*p_filter
, size_t i_size
)
128 filter_sys_t
*p_sys
= p_filter
->p_sys
;
129 assert( p_sys
->p_out_buf
!= NULL
);
131 assert( p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
>= i_size
);
133 uint8_t *p_out
= &p_sys
->p_out_buf
->p_buffer
[p_sys
->i_out_offset
];
134 memset( p_out
, 0, i_size
);
135 p_sys
->i_out_offset
+= i_size
;
138 static void write_data( filter_t
*p_filter
, const void *p_buf
, size_t i_size
,
139 bool b_input_big_endian
)
141 filter_sys_t
*p_sys
= p_filter
->p_sys
;
142 assert( p_sys
->p_out_buf
!= NULL
);
144 bool b_output_big_endian
=
145 p_filter
->fmt_out
.audio
.i_format
== VLC_CODEC_SPDIFB
;
146 uint8_t *p_out
= &p_sys
->p_out_buf
->p_buffer
[p_sys
->i_out_offset
];
147 const uint8_t *p_in
= p_buf
;
149 assert( p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
>= i_size
);
151 if( b_input_big_endian
!= b_output_big_endian
)
152 swab( p_in
, p_out
, i_size
& ~1 );
154 memcpy( p_out
, p_in
, i_size
& ~1 );
155 p_sys
->i_out_offset
+= ( i_size
& ~1 );
159 assert( p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
>= 2 );
160 p_out
+= ( i_size
& ~1 );
161 set_16( p_filter
, p_out
, p_in
[i_size
- 1] << 8 );
162 p_sys
->i_out_offset
+= 2;
166 static void write_buffer( filter_t
*p_filter
, block_t
*p_in_buf
)
168 filter_sys_t
*p_sys
= p_filter
->p_sys
;
169 write_data( p_filter
, p_in_buf
->p_buffer
, p_in_buf
->i_buffer
,
170 is_big_endian( p_filter
, p_in_buf
) );
171 p_sys
->p_out_buf
->i_length
+= p_in_buf
->i_length
;
174 static int write_init( filter_t
*p_filter
, block_t
*p_in_buf
,
175 size_t i_out_size
, unsigned i_nb_samples
)
177 filter_sys_t
*p_sys
= p_filter
->p_sys
;
179 assert( p_sys
->p_out_buf
== NULL
);
180 assert( i_out_size
> SPDIF_HEADER_SIZE
&& ( i_out_size
& 3 ) == 0 );
182 p_sys
->p_out_buf
= block_Alloc( i_out_size
);
183 if( !p_sys
->p_out_buf
)
185 p_sys
->p_out_buf
->i_dts
= p_in_buf
->i_dts
;
186 p_sys
->p_out_buf
->i_pts
= p_in_buf
->i_pts
;
187 p_sys
->p_out_buf
->i_nb_samples
= i_nb_samples
;
189 p_sys
->i_out_offset
= SPDIF_HEADER_SIZE
; /* Place for the S/PDIF header */
193 static void write_finalize( filter_t
*p_filter
, uint16_t i_data_type
,
194 uint8_t i_length_mul
)
196 filter_sys_t
*p_sys
= p_filter
->p_sys
;
197 assert( p_sys
->p_out_buf
!= NULL
);
198 assert( i_data_type
!= 0 );
199 uint8_t *p_out
= p_sys
->p_out_buf
->p_buffer
;
202 assert( p_sys
->i_out_offset
> SPDIF_HEADER_SIZE
);
203 assert( i_length_mul
== 1 || i_length_mul
== 8 );
205 set_16( p_filter
, &p_out
[0], 0xf872 ); /* syncword 1 */
206 set_16( p_filter
, &p_out
[2], 0x4e1f ); /* syncword 2 */
207 set_16( p_filter
, &p_out
[4], i_data_type
); /* data type */
208 /* length in bits or bytes */
209 set_16( p_filter
, &p_out
[6],
210 ( p_sys
->i_out_offset
- SPDIF_HEADER_SIZE
) * i_length_mul
);
213 if( p_sys
->i_out_offset
< p_sys
->p_out_buf
->i_buffer
)
214 write_padding( p_filter
,
215 p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
);
218 static int write_buffer_ac3( filter_t
*p_filter
, block_t
*p_in_buf
)
220 static const size_t a52_size
= A52_FRAME_NB
* 4;
222 if( unlikely( p_in_buf
->i_buffer
< 6
223 || p_in_buf
->i_buffer
> a52_size
224 || p_in_buf
->i_nb_samples
!= A52_FRAME_NB
) )
226 /* Input is not correctly packetizer. Try to parse the buffer in order
227 * to get the mandatory informations to play AC3 over S/PDIF */
228 vlc_a52_header_t a52
;
229 if( vlc_a52_header_Parse( &a52
, p_in_buf
->p_buffer
, p_in_buf
->i_buffer
)
230 != VLC_SUCCESS
|| a52
.b_eac3
|| a52
.i_size
> p_in_buf
->i_buffer
)
232 p_in_buf
->i_buffer
= a52
.i_size
;
233 p_in_buf
->i_nb_samples
= a52
.i_samples
;
236 if( p_in_buf
->i_buffer
+ SPDIF_HEADER_SIZE
> a52_size
237 || write_init( p_filter
, p_in_buf
, a52_size
, A52_FRAME_NB
) )
239 write_buffer( p_filter
, p_in_buf
);
240 write_finalize( p_filter
, IEC61937_AC3
|
241 ( ( p_in_buf
->p_buffer
[5] & 0x7 ) << 8 ) /* bsmod */,
244 return SPDIF_SUCCESS
;
248 static int write_buffer_eac3( filter_t
*p_filter
, block_t
*p_in_buf
)
250 filter_sys_t
*p_sys
= p_filter
->p_sys
;
252 /* The input block can contain the following:
253 * a/ One EAC3 independent stream (with 1, 2, 3 or 6 audio blocks per
255 * b/ One AC3 stream followed by one EAC3 dependent stream (with 6 audio
256 * blocks per syncframe)
257 * c/ One EAC3 independent stream followed by one EAC3 dependent stream
258 * (with 1, 2, 3 or 6 audio blocks per syncframe)
260 * One IEC61937_EAC3 frame must contain 6 audio blocks per syncframe. This
261 * function will gather input blocks until it reaches this amount of audio
264 * Example: for the c/ case with 1 audio blocks per syncframe, a
265 * IEC61937_EAC3 frame will contain 12 a52 streams: 6 independent + 6
266 * dependent EAC3 streams.
269 vlc_a52_header_t a52
;
270 if( vlc_a52_header_Parse( &a52
, p_in_buf
->p_buffer
, p_in_buf
->i_buffer
)
271 != VLC_SUCCESS
|| a52
.i_size
> p_in_buf
->i_buffer
)
274 if( p_in_buf
->i_buffer
> a52
.i_size
)
276 /* Check if the next stream is an eac3 dependent one */
277 vlc_a52_header_t a52_dep
;
278 const uint8_t *dep_buf
= &p_in_buf
->p_buffer
[a52
.i_size
];
279 const size_t dep_size
= p_in_buf
->i_buffer
- a52
.i_size
;
281 if( vlc_a52_header_Parse( &a52_dep
, dep_buf
, dep_size
) != VLC_SUCCESS
282 || a52_dep
.i_size
> dep_size
283 || !a52_dep
.b_eac3
|| a52_dep
.eac3
.strmtyp
!= EAC3_STRMTYP_DEPENDENT
284 || p_in_buf
->i_buffer
> a52
.i_size
+ a52_dep
.i_size
)
288 if( !p_sys
->p_out_buf
289 && write_init( p_filter
, p_in_buf
, AOUT_SPDIF_SIZE
* 4, AOUT_SPDIF_SIZE
) )
291 if( p_in_buf
->i_buffer
> p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
)
294 write_buffer( p_filter
, p_in_buf
);
296 /* cf. Annex E 2.3 of AC3 spec */
297 p_sys
->eac3
.i_nb_blocks
+= a52
.i_blocks_per_sync_frame
;
299 if( p_sys
->eac3
.i_nb_blocks
< 6 )
300 return SPDIF_MORE_DATA
;
301 else if ( p_sys
->eac3
.i_nb_blocks
> 6 )
304 write_finalize( p_filter
, IEC61937_EAC3
, 1 /* in bytes */ );
305 p_sys
->eac3
.i_nb_blocks
= 0;
306 return SPDIF_SUCCESS
;
309 /* Adapted from libavformat/spdifenc.c:
310 * It seems Dolby TrueHD frames have to be encapsulated in MAT frames before
311 * they can be encapsulated in IEC 61937.
312 * Here we encapsulate 24 TrueHD frames in a single MAT frame, padding them
313 * to achieve constant rate.
314 * The actual format of a MAT frame is unknown, but the below seems to work.
315 * However, it seems it is not actually necessary for the 24 TrueHD frames to
316 * be in an exact alignment with the MAT frame
318 static int write_buffer_truehd( filter_t
*p_filter
, block_t
*p_in_buf
)
320 #define TRUEHD_FRAME_OFFSET 2560
322 filter_sys_t
*p_sys
= p_filter
->p_sys
;
324 if( !p_sys
->p_out_buf
325 && write_init( p_filter
, p_in_buf
, 61440, 61440 / 16 ) )
329 if( p_sys
->truehd
.i_frame_count
== 0 )
331 static const char p_mat_start_code
[20] = {
332 0x07, 0x9E, 0x00, 0x03, 0x84, 0x01, 0x01, 0x01, 0x80, 0x00,
333 0x56, 0xA5, 0x3B, 0xF4, 0x81, 0x83, 0x49, 0x80, 0x77, 0xE0
335 write_data( p_filter
, p_mat_start_code
, 20, true );
336 /* We need to include the S/PDIF header in the first MAT frame */
337 i_padding
= TRUEHD_FRAME_OFFSET
- p_in_buf
->i_buffer
- 20
340 else if( p_sys
->truehd
.i_frame_count
== 11 )
342 /* The middle mat code need to be at the ((2560 * 12) - 4) offset */
343 i_padding
= TRUEHD_FRAME_OFFSET
- p_in_buf
->i_buffer
- 4;
345 else if( p_sys
->truehd
.i_frame_count
== 12 )
347 static const char p_mat_middle_code
[12] = {
348 0xC3, 0xC1, 0x42, 0x49, 0x3B, 0xFA,
349 0x82, 0x83, 0x49, 0x80, 0x77, 0xE0
351 write_data( p_filter
, p_mat_middle_code
, 12, true );
352 i_padding
= TRUEHD_FRAME_OFFSET
- p_in_buf
->i_buffer
- ( 12 - 4 );
354 else if( p_sys
->truehd
.i_frame_count
== 23 )
356 static const char p_mat_end_code
[16] = {
357 0xC3, 0xC2, 0xC0, 0xC4, 0x00, 0x00, 0x00, 0x00,
358 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x11
361 /* The end mat code need to be at the ((2560 * 24) - 24) offset */
362 i_padding
= TRUEHD_FRAME_OFFSET
- p_in_buf
->i_buffer
- 24;
364 if( i_padding
< 0 || p_in_buf
->i_buffer
+ i_padding
>
365 p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
)
368 write_buffer( p_filter
, p_in_buf
);
369 write_padding( p_filter
, i_padding
);
370 write_data( p_filter
, p_mat_end_code
, 16, true );
371 write_finalize( p_filter
, IEC61937_TRUEHD
, 1 /* in bytes */ );
372 p_sys
->truehd
.i_frame_count
= 0;
373 return SPDIF_SUCCESS
;
376 i_padding
= TRUEHD_FRAME_OFFSET
- p_in_buf
->i_buffer
;
378 if( i_padding
< 0 || p_in_buf
->i_buffer
+ i_padding
>
379 p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
)
382 write_buffer( p_filter
, p_in_buf
);
383 write_padding( p_filter
, i_padding
);
384 p_sys
->truehd
.i_frame_count
++;
385 return SPDIF_MORE_DATA
;
388 static int write_buffer_dts( filter_t
*p_filter
, block_t
*p_in_buf
)
390 uint16_t i_data_type
;
391 filter_sys_t
*p_sys
= p_filter
->p_sys
;
393 /* Only send the DTS core part */
394 vlc_dts_header_t core
;
395 if( vlc_dts_header_Parse( &core
, p_in_buf
->p_buffer
,
396 p_in_buf
->i_buffer
) != VLC_SUCCESS
)
398 p_in_buf
->i_nb_samples
= core
.i_frame_length
;
399 p_in_buf
->i_buffer
= core
.i_frame_size
;
401 switch( p_in_buf
->i_nb_samples
)
404 i_data_type
= IEC61937_DTS1
;
407 i_data_type
= IEC61937_DTS2
;
410 i_data_type
= IEC61937_DTS3
;
413 msg_Err( p_filter
, "Frame size %d not supported",
414 p_in_buf
->i_nb_samples
);
420 if( p_in_buf
->i_buffer
> p_in_buf
->i_nb_samples
* 4 )
422 if( write_init( p_filter
, p_in_buf
, p_in_buf
->i_nb_samples
* 4,
423 p_in_buf
->i_nb_samples
) )
426 uint8_t *p_out
= &p_sys
->p_out_buf
->p_buffer
[p_sys
->i_out_offset
];
427 ssize_t i_size
= vlc_dts_header_Convert14b16b( p_out
,
428 p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
,
429 p_in_buf
->p_buffer
, p_in_buf
->i_buffer
,
430 p_filter
->fmt_out
.audio
.i_format
== VLC_CODEC_SPDIFL
);
434 p_sys
->i_out_offset
+= i_size
;
435 p_sys
->p_out_buf
->i_length
+= p_in_buf
->i_length
;
439 if( p_in_buf
->i_buffer
+ SPDIF_HEADER_SIZE
> p_in_buf
->i_nb_samples
* 4 )
442 if( write_init( p_filter
, p_in_buf
, p_in_buf
->i_nb_samples
* 4,
443 p_in_buf
->i_nb_samples
) )
445 write_buffer( p_filter
, p_in_buf
);
448 write_finalize( p_filter
, i_data_type
, 8 /* in bits */ );
449 return SPDIF_SUCCESS
;
452 /* Adapted from libavformat/spdifenc.c:
453 * DTS type IV (DTS-HD) can be transmitted with various frame repetition
454 * periods; longer repetition periods allow for longer packets and therefore
455 * higher bitrate. Longer repetition periods mean that the constant bitrate of
456 * the output IEC 61937 stream is higher.
457 * The repetition period is measured in IEC 60958 frames (4 bytes).
459 static int dtshd_get_subtype( unsigned i_frame_length
)
461 switch( i_frame_length
)
463 case 512: return 0x0;
464 case 1024: return 0x1;
465 case 2048: return 0x2;
466 case 4096: return 0x3;
467 case 8192: return 0x4;
468 case 16384: return 0x5;
473 /* Adapted from libavformat/spdifenc.c: */
474 static int write_buffer_dtshd( filter_t
*p_filter
, block_t
*p_in_buf
)
476 static const char p_dtshd_start_code
[10] = {
477 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe
479 static const size_t i_dtshd_start_code
= sizeof( p_dtshd_start_code
);
481 filter_sys_t
*p_sys
= p_filter
->p_sys
;
482 vlc_dts_header_t core
;
483 if( vlc_dts_header_Parse( &core
, p_in_buf
->p_buffer
,
484 p_in_buf
->i_buffer
) != VLC_SUCCESS
)
486 unsigned i_period
= p_filter
->fmt_out
.audio
.i_rate
487 * core
.i_frame_length
/ core
.i_rate
;
489 int i_subtype
= dtshd_get_subtype( i_period
);
490 if( i_subtype
== -1 )
493 size_t i_in_size
= i_dtshd_start_code
+ 2 + p_in_buf
->i_buffer
;
494 size_t i_out_size
= i_period
* 4;
495 uint16_t i_data_type
= IEC61937_DTSHD
| i_subtype
<< 8;
497 if( p_sys
->dtshd
.b_skip
498 || i_in_size
+ SPDIF_HEADER_SIZE
> i_out_size
)
500 /* The bitrate is too high, pass only the core part */
501 p_in_buf
->i_buffer
= core
.i_frame_size
;
502 i_in_size
= i_dtshd_start_code
+ 2 + p_in_buf
->i_buffer
;
503 if( i_in_size
+ SPDIF_HEADER_SIZE
> i_out_size
)
506 /* Don't try to send substreams anymore. That way, we avoid to switch
507 * back and forth between DTD and DTS-HD */
508 p_sys
->dtshd
.b_skip
= true;
511 if( write_init( p_filter
, p_in_buf
, i_out_size
,
512 i_out_size
/ p_filter
->fmt_out
.audio
.i_bytes_per_frame
) )
515 write_data( p_filter
, p_dtshd_start_code
, i_dtshd_start_code
, true );
516 write_16( p_filter
, p_in_buf
->i_buffer
);
517 write_buffer( p_filter
, p_in_buf
);
519 /* Align so that (length_code & 0xf) == 0x8. This is reportedly needed
520 * with some receivers, but the exact requirement is unconfirmed. */
521 #define ALIGN(x, y) (((x) + ((y) - 1)) & ~((y) - 1))
522 size_t i_align
= ALIGN( i_in_size
+ 0x8, 0x10 ) - 0x8;
524 if( i_align
> i_in_size
&& i_align
- i_in_size
525 <= p_sys
->p_out_buf
->i_buffer
- p_sys
->i_out_offset
)
526 write_padding( p_filter
, i_align
- i_in_size
);
528 write_finalize( p_filter
, i_data_type
, 1 /* in bytes */ );
529 return SPDIF_SUCCESS
;
532 static void Flush( filter_t
*p_filter
)
534 filter_sys_t
*p_sys
= p_filter
->p_sys
;
536 if( p_sys
->p_out_buf
!= NULL
)
538 block_Release( p_sys
->p_out_buf
);
539 p_sys
->p_out_buf
= NULL
;
541 switch( p_filter
->fmt_in
.audio
.i_format
)
543 case VLC_CODEC_TRUEHD
:
544 p_sys
->truehd
.i_frame_count
= 0;
547 p_sys
->eac3
.i_nb_blocks
= 0;
554 static block_t
*DoWork( filter_t
*p_filter
, block_t
*p_in_buf
)
556 filter_sys_t
*p_sys
= p_filter
->p_sys
;
557 block_t
*p_out_buf
= NULL
;
560 switch( p_filter
->fmt_in
.audio
.i_format
)
563 i_ret
= write_buffer_ac3( p_filter
, p_in_buf
);
566 i_ret
= write_buffer_eac3( p_filter
, p_in_buf
);
569 case VLC_CODEC_TRUEHD
:
570 i_ret
= write_buffer_truehd( p_filter
, p_in_buf
);
573 /* if the fmt_out is configured for a higher rate than 48kHz
574 * (IEC958 rate), use the DTS-HD framing to pass the DTS Core and
575 * or DTS substreams (like DTS-HD MA). */
576 if( p_filter
->fmt_out
.audio
.i_rate
> 48000 )
577 i_ret
= write_buffer_dtshd( p_filter
, p_in_buf
);
579 i_ret
= write_buffer_dts( p_filter
, p_in_buf
);
582 vlc_assert_unreachable();
588 assert( p_sys
->p_out_buf
->i_buffer
== p_sys
->i_out_offset
);
589 p_out_buf
= p_sys
->p_out_buf
;
590 p_sys
->p_out_buf
= NULL
;
592 case SPDIF_MORE_DATA
:
599 block_Release( p_in_buf
);
603 static int Open( vlc_object_t
*p_this
)
605 filter_t
*p_filter
= (filter_t
*)p_this
;
608 if( ( p_filter
->fmt_in
.audio
.i_format
!= VLC_CODEC_DTS
&&
609 p_filter
->fmt_in
.audio
.i_format
!= VLC_CODEC_A52
&&
610 p_filter
->fmt_in
.audio
.i_format
!= VLC_CODEC_EAC3
&&
611 p_filter
->fmt_in
.audio
.i_format
!= VLC_CODEC_MLP
&&
612 p_filter
->fmt_in
.audio
.i_format
!= VLC_CODEC_TRUEHD
) ||
613 ( p_filter
->fmt_out
.audio
.i_format
!= VLC_CODEC_SPDIFL
&&
614 p_filter
->fmt_out
.audio
.i_format
!= VLC_CODEC_SPDIFB
) )
617 p_sys
= p_filter
->p_sys
= calloc( 1, sizeof(filter_sys_t
) );
618 if( unlikely( p_sys
== NULL
) )
621 p_filter
->pf_audio_filter
= DoWork
;
622 p_filter
->pf_flush
= Flush
;
627 static void Close( vlc_object_t
*p_this
)
629 filter_t
*p_filter
= (filter_t
*)p_this
;
632 free( p_filter
->p_sys
);