]> git.sesse.net Git - vlc/blob - modules/access/linsys/linsys_sdi.c
Add support for Linear Systems (HD-)SDI cards
[vlc] / modules / access / linsys / linsys_sdi.c
1 /*****************************************************************************
2  * linsys_sdi.c: SDI capture for Linear Systems/Computer Modules cards
3  *****************************************************************************
4  * Copyright (C) 2009-2011 VideoLAN
5  *
6  * Authors: Christophe Massiot <massiot@via.ecp.fr>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
21  *****************************************************************************/
22
23 #ifdef HAVE_CONFIG_H
24 # include "config.h"
25 #endif
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include <poll.h>
31 #include <sys/mman.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <fcntl.h>
35 #include <errno.h>
36
37 #include <vlc_common.h>
38 #include <vlc_plugin.h>
39
40 #include <vlc_input.h>
41 #include <vlc_access.h>
42 #include <vlc_demux.h>
43
44 #include <vlc_fs.h>
45
46 #include "linsys_sdi.h"
47
48 #undef ZVBI_DEBUG
49 #include <libzvbi.h>
50
51 #define SDI_DEVICE        "/dev/sdirx%u"
52 #define SDI_BUFFERS_FILE  "/sys/class/sdi/sdirx%u/buffers"
53 #define SDI_BUFSIZE_FILE  "/sys/class/sdi/sdirx%u/bufsize"
54 #define SDI_MODE_FILE     "/sys/class/sdi/sdirx%u/mode"
55 #define READ_TIMEOUT      80000
56 #define RESYNC_TIMEOUT    500000
57 #define CLOCK_GAP         INT64_C(500000)
58 #define START_DATE        INT64_C(4294967296)
59
60 #define DEMUX_BUFFER_SIZE 1350000
61 #define MAX_AUDIOS        4
62 #define SAMPLERATE_TOLERANCE 0.1
63
64 /*****************************************************************************
65  * Module descriptor
66  *****************************************************************************/
67 #define CACHING_TEXT N_("Caching value in ms")
68 #define CACHING_LONGTEXT N_( \
69     "Allows you to modify the default caching value for sdi capture " \
70     "streams. This value should be set in millisecond units." )
71 #define LINK_TEXT N_("Link #")
72 #define LINK_LONGTEXT N_( \
73     "Allows you to set the desired link of the board for the capture (starting at 0)." )
74 #define VIDEO_TEXT N_("Video ID")
75 #define VIDEO_LONGTEXT N_( \
76     "Allows you to set the ES ID of the video." )
77 #define VIDEO_ASPECT_TEXT N_("Aspect ratio")
78 #define VIDEO_ASPECT_LONGTEXT N_( \
79     "Allows you to force the aspect ratio of the video." )
80 #define AUDIO_TEXT N_("Audio configuration")
81 #define AUDIO_LONGTEXT N_( \
82     "Allows you to set audio configuration (id=group,pair:id=group,pair...)." )
83 #define TELX_TEXT N_("Teletext configuration")
84 #define TELX_LONGTEXT N_( \
85     "Allows you to set Teletext configuration (id=line1-lineN with both fields)." )
86 #define TELX_LANG_TEXT N_("Teletext language")
87 #define TELX_LANG_LONGTEXT N_( \
88     "Allows you to set Teletext language (page=lang/type,...)." )
89
90 static int  Open ( vlc_object_t * );
91 static void Close( vlc_object_t * );
92 static int  DemuxOpen ( vlc_object_t * );
93 static void DemuxClose( vlc_object_t * );
94
95 vlc_module_begin()
96     set_description( N_("SDI Input") )
97     set_shortname( N_("sdi") )
98     set_category( CAT_INPUT )
99     set_subcategory( SUBCAT_INPUT_ACCESS )
100
101     add_integer( "linsys-sdi-caching", DEFAULT_PTS_DELAY / 1000,
102         CACHING_TEXT, CACHING_LONGTEXT, true )
103     add_integer( "linsys-sdi-link", 0,
104         LINK_TEXT, LINK_LONGTEXT, true )
105
106     add_integer( "linsys-sdi-id-video", 0, VIDEO_TEXT, VIDEO_LONGTEXT, true )
107     add_string( "linsys-sdi-aspect-ratio", "", VIDEO_ASPECT_TEXT,
108                 VIDEO_ASPECT_LONGTEXT, true )
109     add_string( "linsys-sdi-audio", "0=1,1", AUDIO_TEXT, AUDIO_LONGTEXT, true )
110     add_string( "linsys-sdi-telx", "", TELX_TEXT, TELX_LONGTEXT, true )
111     add_string( "linsys-sdi-telx-lang", "", TELX_LANG_TEXT, TELX_LANG_LONGTEXT,
112                 true )
113
114     set_capability( "access_demux", 0 )
115     add_shortcut( "linsys-sdi" )
116     set_callbacks( Open, Close )
117
118     add_submodule()
119         set_description( N_("SDI Demux") )
120         set_capability( "demux", 0 )
121         set_callbacks( DemuxOpen, DemuxClose )
122 vlc_module_end()
123
124 /*****************************************************************************
125  * Local prototypes
126  *****************************************************************************/
127 typedef struct sdi_audio_t
128 {
129     unsigned int i_group, i_pair;
130
131     /* SDI parser */
132     int32_t      i_delay;
133     unsigned int i_rate;
134     uint8_t      i_block_number;
135     int16_t      *p_buffer;
136     unsigned int i_left_samples, i_right_samples, i_nb_samples, i_max_samples;
137
138     /* ES stuff */
139     int          i_id;
140     es_out_id_t  *p_es;
141 } sdi_audio_t;
142
143 enum {
144     STATE_NOSYNC,
145     STATE_STARTSYNC,
146     STATE_ANCSYNC,
147     STATE_LINESYNC,
148     STATE_ACTIVESYNC,
149     STATE_VBLANKSYNC,
150     STATE_PICSYNC,
151     STATE_SYNC,
152 };
153
154 struct demux_sys_t
155 {
156     /* device reader */
157     int              i_fd;
158     unsigned int     i_link;
159     uint8_t          **pp_buffers;
160     unsigned int     i_buffers, i_current_buffer;
161     unsigned int     i_buffer_size;
162
163     /* SDI sync */
164     int              i_state;
165     mtime_t          i_last_state_change;
166     unsigned int     i_anc_size, i_active_size, i_picture_size;
167     unsigned int     i_line_offset, i_nb_lines;
168
169     /* SDI parser */
170     unsigned int     i_line_buffer;
171     unsigned int     i_current_line;
172     uint8_t          *p_line_buffer;
173     block_t          *p_current_picture;
174     uint8_t          *p_y, *p_u, *p_v;
175     uint8_t          *p_wss_buffer;
176     uint8_t          *p_telx_buffer;
177
178     /* picture decoding */
179     unsigned int     i_frame_rate, i_frame_rate_base;
180     unsigned int     i_width, i_height, i_aspect, i_forced_aspect;
181     unsigned int     i_block_size;
182     unsigned int     i_telx_line, i_telx_count;
183     char             *psz_telx, *psz_telx_lang;
184     bool             b_hd, b_vbi;
185     vbi_raw_decoder  rd_wss, rd_telx;
186     mtime_t          i_next_date;
187     int              i_incr;
188
189     /* ES stuff */
190     int              i_id_video;
191     es_out_id_t      *p_es_video;
192     sdi_audio_t      p_audios[MAX_AUDIOS];
193     es_out_id_t      *p_es_telx;
194 };
195
196 static int Control( demux_t *, int, va_list );
197 static int DemuxControl( demux_t *, int, va_list );
198 static int Demux( demux_t * );
199 static int DemuxDemux( demux_t * );
200
201 static int InitWSS( demux_t *p_demux );
202 static int InitTelx( demux_t *p_demux );
203
204 static int HandleSDBuffer( demux_t *p_demux, uint8_t *p_buffer,
205                            unsigned int i_buffer_size );
206
207 static int InitCapture( demux_t *p_demux );
208 static void CloseCapture( demux_t *p_demux );
209 static int Capture( demux_t *p_demux );
210
211 /*****************************************************************************
212  * DemuxOpen:
213  *****************************************************************************/
214 static int DemuxOpen( vlc_object_t *p_this )
215 {
216     demux_t     *p_demux = (demux_t *)p_this;
217     demux_sys_t *p_sys;
218     char        *psz_parser;
219
220     /* Fill p_demux field */
221     p_demux->pf_demux = DemuxDemux;
222     p_demux->pf_control = DemuxControl;
223     p_demux->p_sys = p_sys = calloc( 1, sizeof( demux_sys_t ) );
224     if( unlikely(!p_sys ) )
225         return VLC_ENOMEM;
226
227     p_sys->i_state = STATE_NOSYNC;
228     p_sys->i_last_state_change = mdate();
229
230     /* SDI AR */
231     char *psz_ar = var_InheritString( p_demux, "linsys-sdi-aspect-ratio" );
232     if ( psz_ar != NULL )
233     {
234         psz_parser = strchr( psz_ar, ':' );
235         if ( psz_parser )
236         {
237             *psz_parser++ = '\0';
238             p_sys->i_forced_aspect = p_sys->i_aspect =
239                  strtol( psz_ar, NULL, 0 ) * VOUT_ASPECT_FACTOR
240                  / strtol( psz_parser, NULL, 0 );
241         }
242         else
243             p_sys->i_forced_aspect = 0;
244         free( psz_ar );
245     }
246
247     /* */
248     p_sys->i_id_video = var_InheritInteger( p_demux, "linsys-sdi-id-video" );
249
250     /* Audio ES */
251     char *psz_string = psz_parser = var_InheritString( p_demux,
252                                                        "linsys-sdi-audio" );
253     int i = 0;
254
255     while ( psz_parser != NULL && *psz_parser )
256     {
257         int i_id, i_group, i_pair;
258         char *psz_next = strchr( psz_parser, '=' );
259         if ( psz_next != NULL )
260         {
261             *psz_next = '\0';
262             i_id = strtol( psz_parser, NULL, 0 );
263             psz_parser = psz_next + 1;
264         }
265         else
266             i_id = 0;
267
268         psz_next = strchr( psz_parser, ':' );
269         if ( psz_next != NULL )
270         {
271             *psz_next = '\0';
272             psz_next++;
273         }
274
275         if ( sscanf( psz_parser, "%d,%d", &i_group, &i_pair ) == 2 )
276         {
277             p_sys->p_audios[i].i_group = i_group;
278             p_sys->p_audios[i].i_pair = i_pair;
279             p_sys->p_audios[i].i_id = i_id;
280             i++;
281         }
282         else
283             msg_Warn( p_demux, "malformed audio configuration (%s)",
284                       psz_parser );
285
286         psz_parser = psz_next;
287     }
288     free( psz_string );
289
290     /* Teletext ES */
291     p_sys->psz_telx = var_InheritString( p_demux, "linsys-sdi-telx" );
292
293     p_sys->psz_telx_lang = var_InheritString( p_demux, "linsys-sdi-telx-lang" );
294
295     return VLC_SUCCESS;
296 }
297
298 static int Open( vlc_object_t *p_this )
299 {
300     demux_t     *p_demux = (demux_t *)p_this;
301     demux_sys_t *p_sys;
302     int         i_ret;
303
304     if ( (i_ret = DemuxOpen( p_this )) != VLC_SUCCESS )
305         return i_ret;
306
307     /* Fill p_demux field */
308     p_demux->pf_demux    = Demux;
309     p_demux->pf_control  = Control;
310     p_sys = p_demux->p_sys;
311
312     /* Update default_pts to a suitable value for sdi access */
313     var_Create( p_demux, "linsys-sdi-caching", VLC_VAR_INTEGER|VLC_VAR_DOINHERIT );
314
315     p_sys->i_link = var_InheritInteger( p_demux, "linsys-sdi-link" );
316
317     if( InitCapture( p_demux ) != VLC_SUCCESS )
318     {
319         free( p_sys );
320         return VLC_EGENERIC;
321     }
322
323     return VLC_SUCCESS;
324 }
325
326 /*****************************************************************************
327  * DemuxClose:
328  *****************************************************************************/
329 static void DemuxClose( vlc_object_t *p_this )
330 {
331     demux_t     *p_demux = (demux_t *)p_this;
332     demux_sys_t *p_sys   = p_demux->p_sys;
333
334     free( p_sys->psz_telx );
335     free( p_sys->psz_telx_lang );
336     free( p_sys );
337 }
338
339 static void Close( vlc_object_t *p_this )
340 {
341     demux_t     *p_demux = (demux_t *)p_this;
342
343     CloseCapture( p_demux );
344     DemuxClose( p_this );
345 }
346
347 /*****************************************************************************
348  * DemuxDemux:
349  *****************************************************************************/
350 static int DemuxDemux( demux_t *p_demux )
351 {
352     block_t *p_block = stream_Block( p_demux->s, DEMUX_BUFFER_SIZE );
353     int i_ret;
354
355     if ( p_block == NULL )
356         return 0;
357
358     i_ret = HandleSDBuffer( p_demux, p_block->p_buffer, p_block->i_buffer );
359     block_Release( p_block );
360
361     return ( i_ret == VLC_SUCCESS );
362 }
363
364 static int Demux( demux_t *p_demux )
365 {
366     return ( Capture( p_demux ) == VLC_SUCCESS );
367 }
368
369 /*****************************************************************************
370  * Control:
371  *****************************************************************************/
372 static int DemuxControl( demux_t *p_demux, int i_query, va_list args )
373 {
374     return demux_vaControlHelper( p_demux->s, -1, -1, 270000000, 1, i_query,
375                                    args );
376 }
377
378 static int Control( demux_t *p_demux, int i_query, va_list args )
379 {
380     bool *pb;
381     int64_t *pi64;
382
383     switch( i_query )
384     {
385         /* Special for access_demux */
386         case DEMUX_CAN_PAUSE:
387         case DEMUX_CAN_CONTROL_PACE:
388             /* TODO */
389             pb = (bool*)va_arg( args, bool * );
390             *pb = false;
391             return VLC_SUCCESS;
392
393         case DEMUX_GET_PTS_DELAY:
394             pi64 = (int64_t*)va_arg( args, int64_t * );
395             *pi64 = (int64_t)var_GetInteger( p_demux, "linsys-sdi-caching" ) * 1000;
396             return VLC_SUCCESS;
397
398         /* TODO implement others */
399         default:
400             return VLC_EGENERIC;
401     }
402 }
403
404 /*****************************************************************************
405  * Video, audio & VBI decoding
406  *****************************************************************************/
407 #define WSS_LINE        23
408
409 struct block_extension_t
410 {
411     bool            b_progressive;          /**< is it a progressive frame ? */
412     bool            b_top_field_first;             /**< which field is first */
413     unsigned int    i_nb_fields;                  /**< # of displayed fields */
414     unsigned int    i_aspect;                     /**< aspect ratio of frame */
415 };
416
417 static int NewFrame( demux_t *p_demux )
418 {
419     demux_sys_t *p_sys = p_demux->p_sys;
420
421     p_sys->p_current_picture = block_New( p_demux, p_sys->i_block_size );
422     if( unlikely( !p_sys->p_current_picture ) )
423         return VLC_ENOMEM;
424     p_sys->p_y = p_sys->p_current_picture->p_buffer;
425     p_sys->p_u = p_sys->p_y + p_sys->i_width * p_sys->i_height;
426     p_sys->p_v = p_sys->p_u + p_sys->i_width * p_sys->i_height / 4;
427
428     for ( int i = 0; i < MAX_AUDIOS; i++ )
429     {
430         sdi_audio_t *p_audio = &p_sys->p_audios[i];
431         p_audio->i_left_samples = p_audio->i_right_samples = 0;
432     }
433     return VLC_SUCCESS;
434 }
435
436 static int StartDecode( demux_t *p_demux )
437 {
438     demux_sys_t *p_sys = p_demux->p_sys;
439     es_format_t fmt;
440     char *psz_parser;
441
442     p_sys->i_next_date = START_DATE;
443     p_sys->i_incr = 1000000 * p_sys->i_frame_rate_base / p_sys->i_frame_rate;
444     p_sys->i_block_size = p_sys->i_width * p_sys->i_height * 3 / 2
445                            + sizeof(struct block_extension_t);
446     if( NewFrame( p_demux ) != VLC_SUCCESS )
447         return VLC_ENOMEM;
448
449     /* Video ES */
450     es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_I420 );
451     fmt.i_id                    = p_sys->i_id_video;
452     fmt.video.i_frame_rate      = p_sys->i_frame_rate;
453     fmt.video.i_frame_rate_base = p_sys->i_frame_rate_base;
454     fmt.video.i_width           = p_sys->i_width;
455     fmt.video.i_height          = p_sys->i_height;
456     int i_aspect = p_sys->i_forced_aspect ? p_sys->i_forced_aspect
457                                           : p_sys->i_aspect;
458     fmt.video.i_sar_num = i_aspect * fmt.video.i_height
459                            / fmt.video.i_width;
460     fmt.video.i_sar_den = VOUT_ASPECT_FACTOR;
461     p_sys->p_es_video   = es_out_Add( p_demux->out, &fmt );
462
463     if ( p_sys->b_vbi && InitWSS( p_demux ) != VLC_SUCCESS )
464         p_sys->b_vbi = 0;
465
466     /* Teletext ES */
467     psz_parser = p_sys->psz_telx;
468     if ( psz_parser != NULL && *psz_parser )
469     {
470         if ( !p_sys->b_vbi )
471         {
472             msg_Warn( p_demux, "VBI is unsupported on this input stream" );
473         }
474         else
475         {
476             int i_id;
477             char *psz_next = strchr( psz_parser, '=' );
478             if ( psz_next != NULL )
479             {
480                 *psz_next = '\0';
481                 i_id = strtol( psz_parser, NULL, 0 );
482                 psz_parser = psz_next + 1;
483             }
484             else
485                 i_id = 0;
486
487             psz_next = strchr( psz_parser, '-' );
488             if ( psz_next != NULL )
489                 *psz_next++ = '\0';
490
491             p_sys->i_telx_line = strtol( psz_parser, NULL, 0 ) - 1;
492             if ( psz_next != NULL )
493                 p_sys->i_telx_count = strtol( psz_next, NULL, 0 )
494                                        - p_sys->i_telx_line - 1 + 1;
495             else
496                 p_sys->i_telx_count = 1;
497
498             if ( InitTelx( p_demux ) == VLC_SUCCESS )
499             {
500                 int i_dr_size = 0;
501                 uint8_t *p_dr = NULL;
502
503                 msg_Dbg( p_demux, "capturing VBI lines %d-%d and %d-%d",
504                          p_sys->i_telx_line + 1,
505                          p_sys->i_telx_line + 1 + p_sys->i_telx_count - 1,
506                          p_sys->i_telx_line + 1 + 313,
507                          p_sys->i_telx_line + 1 + 313
508                                                 + p_sys->i_telx_count - 1 );
509
510                 es_format_Init( &fmt, SPU_ES, VLC_CODEC_TELETEXT );
511                 fmt.i_id = i_id;
512
513                 /* Teletext language & type */
514                 psz_parser = p_sys->psz_telx_lang;
515
516                 while ( (psz_next = strchr( psz_parser, '=' )) != NULL )
517                 {
518                     int i_page;
519                     *psz_next++ = '\0';
520                     if ( !psz_next[0] || !psz_next[1] || !psz_next[2] )
521                         break;
522                     i_page = strtol( psz_parser, NULL, 0 );
523                     i_dr_size += 5;
524                     p_dr = realloc( p_dr, i_dr_size );
525                     p_dr[i_dr_size - 5] = *psz_next++;
526                     p_dr[i_dr_size - 4] = *psz_next++;
527                     p_dr[i_dr_size - 3] = *psz_next++;
528                     if ( *psz_next == '/' )
529                     {
530                         psz_next++;
531                         p_dr[i_dr_size - 2] = strtol( psz_next, &psz_next, 0 )
532                                                << 3;
533                     }
534                     else  /* subtitle for hearing impaired */
535                         p_dr[i_dr_size - 2] = 0x5 << 3;
536                     p_dr[i_dr_size - 2] |= (i_page / 100) & 0x7;
537                     p_dr[i_dr_size - 1] = i_page % 100;
538
539                     if ( *psz_next == ',' )
540                         psz_next++;
541                     psz_parser = psz_next;
542                 }
543
544                 fmt.i_extra = i_dr_size;
545                 fmt.p_extra = p_dr;
546                 p_sys->p_es_telx = es_out_Add( p_demux->out, &fmt );
547             }
548             else
549                 p_sys->i_telx_count = 0;
550         }
551     }
552     return VLC_SUCCESS;
553 }
554
555 static void StopDecode( demux_t *p_demux )
556 {
557     demux_sys_t *p_sys = p_demux->p_sys;
558
559     if ( p_sys->i_state != STATE_SYNC )
560         return;
561
562     free( p_sys->p_line_buffer );
563
564     block_Release( p_sys->p_current_picture );
565     p_sys->p_current_picture = NULL;
566     es_out_Del( p_demux->out, p_sys->p_es_video );
567
568     if ( p_sys->b_vbi )
569     {
570         free( p_sys->p_wss_buffer );
571         p_sys->p_wss_buffer = NULL;
572         vbi_raw_decoder_destroy( &p_sys->rd_wss );
573
574         if ( p_sys->p_es_telx )
575         {
576             es_out_Del( p_demux->out, p_sys->p_es_telx );
577             free( p_sys->p_telx_buffer );
578             p_sys->p_telx_buffer = NULL;
579             vbi_raw_decoder_destroy( &p_sys->rd_telx );
580         }
581     }
582
583     for ( int i = 0; i < MAX_AUDIOS; i++ )
584     {
585         sdi_audio_t *p_audio = &p_sys->p_audios[i];
586         if ( p_audio->i_group && p_audio->p_es != NULL )
587         {
588             es_out_Del( p_demux->out, p_audio->p_es );
589             p_audio->p_es = NULL;
590             free( p_audio->p_buffer );
591             p_audio->p_buffer = NULL;
592         }
593     }
594 }
595
596 static void InitVideo( demux_t *p_demux )
597 {
598     demux_sys_t *p_sys = p_demux->p_sys;
599     int i_total_width = (p_sys->i_anc_size + p_sys->i_active_size) * 4 / 5;
600     p_sys->i_width = (p_sys->i_active_size - 5) * 4 / 10;
601     if ( p_sys->i_nb_lines == 625 )
602     {
603         /* PAL */
604         p_sys->i_frame_rate      = 25;
605         p_sys->i_frame_rate_base = 1;
606         p_sys->i_height          = 576;
607         p_sys->i_aspect          = 4 * VOUT_ASPECT_FACTOR / 3;
608         p_sys->b_hd              = false;
609     }
610     else if ( p_sys->i_nb_lines == 525 )
611     {
612         /* NTSC */
613         p_sys->i_frame_rate      = 30000;
614         p_sys->i_frame_rate_base = 1001;
615         p_sys->i_height          = 480;
616         p_sys->i_aspect          = 4 * VOUT_ASPECT_FACTOR / 3;
617         p_sys->b_hd              = false;
618     }
619     else if ( p_sys->i_nb_lines == 1125 && i_total_width == 2640 )
620     {
621         /* 1080i50 or 1080p25 */
622         p_sys->i_frame_rate      = 25;
623         p_sys->i_frame_rate_base = 1;
624         p_sys->i_height          = 1080;
625         p_sys->i_aspect          = 16 * VOUT_ASPECT_FACTOR / 9;
626         p_sys->b_hd              = true;
627     }
628     else if ( p_sys->i_nb_lines == 1125 && i_total_width == 2200 )
629     {
630         /* 1080i60 or 1080p30 */
631         p_sys->i_frame_rate      = 30000;
632         p_sys->i_frame_rate_base = 1001;
633         p_sys->i_height          = 1080;
634         p_sys->i_aspect          = 16 * VOUT_ASPECT_FACTOR / 9;
635         p_sys->b_hd              = true;
636     }
637     else if ( p_sys->i_nb_lines == 750 && i_total_width == 1980 )
638     {
639         /* 720p50 */
640         p_sys->i_frame_rate      = 50;
641         p_sys->i_frame_rate_base = 1;
642         p_sys->i_height          = 720;
643         p_sys->i_aspect          = 16 * VOUT_ASPECT_FACTOR / 9;
644         p_sys->b_hd              = true;
645     }
646     else if ( p_sys->i_nb_lines == 750 && i_total_width == 1650 )
647     {
648         /* 720p60 */
649         p_sys->i_frame_rate      = 60000;
650         p_sys->i_frame_rate_base = 1001;
651         p_sys->i_height          = 720;
652         p_sys->i_aspect          = 16 * VOUT_ASPECT_FACTOR / 9;
653         p_sys->b_hd              = true;
654     }
655     else
656     {
657         msg_Warn( p_demux, "unable to determine video type" );
658         /* Put sensitive defaults */
659         p_sys->i_frame_rate      = 25;
660         p_sys->i_frame_rate_base = 1;
661         p_sys->i_height          = p_sys->i_nb_lines;
662         p_sys->i_aspect          = 16 * VOUT_ASPECT_FACTOR / 9;
663         p_sys->b_hd              = true;
664     }
665     p_sys->b_vbi = !p_sys->b_hd;
666 }
667
668 static void DecodeVideo( demux_t *p_demux )
669 {
670     demux_sys_t *p_sys = p_demux->p_sys;
671     struct block_extension_t ext;
672
673     /* FIXME: progressive formats ? */
674     ext.b_progressive     = false;
675     ext.i_nb_fields       = 2;
676     ext.b_top_field_first = true;
677     ext.i_aspect = p_sys->i_forced_aspect ? p_sys->i_forced_aspect :
678                    p_sys->i_aspect;
679
680     memcpy( &p_sys->p_current_picture->p_buffer[p_sys->i_block_size
681                                      - sizeof(struct block_extension_t)],
682             &ext, sizeof(struct block_extension_t) );
683
684     p_sys->p_current_picture->i_dts = p_sys->p_current_picture->i_pts
685         = p_sys->i_next_date;
686     es_out_Send( p_demux->out, p_sys->p_es_video, p_sys->p_current_picture );
687 }
688
689 static int InitWSS( demux_t *p_demux )
690 {
691     demux_sys_t *p_sys = p_demux->p_sys;
692     vbi_raw_decoder_init( &p_sys->rd_wss );
693
694     p_sys->rd_wss.scanning        = 625;
695     p_sys->rd_wss.sampling_format = VBI_PIXFMT_UYVY;
696     p_sys->rd_wss.sampling_rate   = 13.5e6;
697     p_sys->rd_wss.bytes_per_line  = 720 * 2;
698     p_sys->rd_wss.offset          = 9.5e-6 * 13.5e6;
699
700     p_sys->rd_wss.start[0] = 23;
701     p_sys->rd_wss.count[0] = 1;
702     p_sys->rd_wss.start[1] = 0;
703     p_sys->rd_wss.count[1] = 0;
704
705     p_sys->rd_wss.interlaced = FALSE;
706     p_sys->rd_wss.synchronous = TRUE;
707
708     if ( vbi_raw_decoder_add_services( &p_sys->rd_wss,
709                                        VBI_SLICED_WSS_625,
710                                        /* strict */ 2 ) == 0 )
711     {
712         msg_Warn( p_demux, "cannot initialize zvbi for WSS" );
713         vbi_raw_decoder_destroy ( &p_sys->rd_telx );
714         return VLC_EGENERIC;
715     }
716
717     p_sys->p_wss_buffer = malloc( p_sys->i_width * 2 );
718     if( !p_sys->p_wss_buffer )
719     {
720         vbi_raw_decoder_destroy ( &p_sys->rd_telx );
721         return VLC_ENOMEM;
722     }
723     return VLC_SUCCESS;
724 }
725
726 static void DecodeWSS( demux_t *p_demux )
727 {
728     demux_sys_t *p_sys = p_demux->p_sys;
729     vbi_sliced p_sliced[1];
730
731     if ( vbi_raw_decode( &p_sys->rd_wss, p_sys->p_wss_buffer, p_sliced ) == 0 )
732     {
733         p_sys->i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
734     }
735     else
736     {
737         unsigned int i_old_aspect = p_sys->i_aspect;
738         uint8_t *p = p_sliced[0].data;
739         int i_aspect, i_parity;
740
741         i_aspect = p[0] & 15;
742         i_parity = i_aspect;
743         i_parity ^= i_parity >> 2;
744         i_parity ^= i_parity >> 1;
745         i_aspect &= 7;
746
747         if ( !(i_parity & 1) )
748             msg_Warn( p_demux, "WSS parity error" );
749         else if ( i_aspect == 7 )
750             p_sys->i_aspect = 16 * VOUT_ASPECT_FACTOR / 9;
751         else
752             p_sys->i_aspect = 4 * VOUT_ASPECT_FACTOR / 3;
753
754         if ( p_sys->i_aspect != i_old_aspect )
755             msg_Dbg( p_demux, "new WSS information (ra=%x md=%x cod=%x hlp=%x rvd=%x sub=%x pos=%x srd=%x c=%x cp=%x)",
756                      i_aspect, (p[0] & 0x10) >> 4, (p[0] & 0x20) >> 5,
757                      (p[0] & 0x40) >> 6, (p[0] & 0x80) >> 7, p[1] & 0x01,
758                      (p[1] >> 1) & 3, (p[1] & 0x08) >> 3, (p[1] & 0x10) >> 4,
759                      (p[1] & 0x20) >> 5 );
760     }
761 }
762
763 static int InitTelx( demux_t *p_demux )
764 {
765     demux_sys_t *p_sys = p_demux->p_sys;
766     vbi_raw_decoder_init( &p_sys->rd_telx );
767
768     p_sys->rd_telx.scanning        = 625;
769     p_sys->rd_telx.sampling_format = VBI_PIXFMT_UYVY;
770     p_sys->rd_telx.sampling_rate   = 13.5e6;
771     p_sys->rd_telx.bytes_per_line  = 720 * 2;
772     p_sys->rd_telx.offset          = 9.5e-6 * 13.5e6;
773
774     p_sys->rd_telx.start[0] = p_sys->i_telx_line + 1;
775     p_sys->rd_telx.count[0] = p_sys->i_telx_count;
776     p_sys->rd_telx.start[1] = p_sys->i_telx_line + 1 + 313;
777     p_sys->rd_telx.count[1] = p_sys->i_telx_count;
778
779     p_sys->rd_telx.interlaced = FALSE;
780     p_sys->rd_telx.synchronous = TRUE;
781
782     if ( vbi_raw_decoder_add_services( &p_sys->rd_telx, VBI_SLICED_TELETEXT_B,
783                                        0 ) == 0 )
784     {
785         msg_Warn( p_demux, "cannot initialize zvbi for Teletext" );
786         vbi_raw_decoder_destroy ( &p_sys->rd_telx );
787         return VLC_EGENERIC;
788     }
789
790     p_sys->p_telx_buffer = malloc( p_sys->i_telx_count * p_sys->i_width * 4 );
791     if( !p_sys->p_telx_buffer )
792     {
793         vbi_raw_decoder_destroy ( &p_sys->rd_telx );
794         return VLC_ENOMEM;
795     }
796     return VLC_SUCCESS;
797 }
798
799 static int DecodeTelx( demux_t *p_demux )
800 {
801     demux_sys_t *p_sys = p_demux->p_sys;
802     vbi_sliced p_sliced[p_sys->i_telx_count * 2];
803     int i_nb_slices = vbi_raw_decode( &p_sys->rd_telx, p_sys->p_telx_buffer,
804                                       p_sliced );
805
806     if ( i_nb_slices )
807     {
808         /* 3, 7, 11, 15, etc. */
809         int i_nb_slices_rounded = 3 + (i_nb_slices / 4) * 4;
810         int i;
811         uint8_t *p;
812         block_t *p_block = block_New( p_demux,
813                                       1 + i_nb_slices_rounded * 46 );
814         if( unlikely( !p_block ) )
815             return VLC_ENOMEM;
816         p_block->p_buffer[0] = 0x10; /* FIXME ? data_identifier */
817         p = p_block->p_buffer + 1;
818
819         for ( i = 0; i < i_nb_slices; i++ )
820         {
821             int i_line = p_sliced[i].line;
822             p[0] = 0x3; /* FIXME data_unit_id == subtitles */
823             p[1] = 0x2c; /* data_unit_length */
824             /* reserved | field_parity (kind of inverted) | line */
825             p[2] = 0xc0 | (i_line > 313 ? 0 : 0x20) | (i_line % 313);
826             p[3] = 0xe4; /* framing code */
827             for ( int j = 0; j < 42; j++ )
828                 p[4 + j] = vbi_rev8( p_sliced[i].data[j] );
829             p += 46;
830         }
831
832         /* Let's stuff */
833         for ( ; i < i_nb_slices_rounded; i++ )
834         {
835             p[0] = 0xff;
836             p[1] = 0x2c;
837             memset( p + 2, 0xff, 44 );
838             p += 46;
839         }
840
841         p_block->i_dts = p_block->i_pts = p_sys->i_next_date;
842         es_out_Send( p_demux->out, p_sys->p_es_telx, p_block );
843     }
844     return VLC_SUCCESS;
845 }
846
847 static int InitAudio( demux_t *p_demux, sdi_audio_t *p_audio )
848 {
849     demux_sys_t *p_sys = p_demux->p_sys;
850     es_format_t fmt;
851
852     msg_Dbg( p_demux, "starting audio %u/%u rate:%u delay:%d", p_audio->i_group,
853              p_audio->i_pair, p_audio->i_rate, p_audio->i_delay );
854
855     es_format_Init( &fmt, AUDIO_ES, VLC_CODEC_S16L );
856     fmt.i_id = p_audio->i_id;
857     fmt.audio.i_channels          = 2;
858     fmt.audio.i_physical_channels = 6;
859     fmt.audio.i_original_channels = 6;
860     fmt.audio.i_rate              = p_audio->i_rate;
861     fmt.audio.i_bitspersample     = 16;
862     fmt.audio.i_blockalign        = fmt.audio.i_channels *
863                                     fmt.audio.i_bitspersample / 8;
864     fmt.i_bitrate                 = fmt.audio.i_channels * fmt.audio.i_rate *
865                                     fmt.audio.i_bitspersample;
866     p_audio->p_es                 = es_out_Add( p_demux->out, &fmt );
867
868     p_audio->i_nb_samples         = p_audio->i_rate * p_sys->i_frame_rate_base
869                                     / p_sys->i_frame_rate;
870     p_audio->i_max_samples        = (float)p_audio->i_nb_samples *
871                                     (1. + SAMPLERATE_TOLERANCE);
872
873     p_audio->p_buffer             = malloc( p_audio->i_max_samples * sizeof(int16_t) * 2 );
874     p_audio->i_left_samples       = p_audio->i_right_samples = 0;
875     p_audio->i_block_number       = 0;
876
877     if( unlikely( !p_audio->p_buffer ) )
878         return VLC_ENOMEM;
879     return VLC_SUCCESS;
880 }
881
882 /* Fast and efficient linear resampling routine */
883 static void ResampleAudio( int16_t *p_out, int16_t *p_in,
884                            unsigned int i_out, unsigned int i_in )
885 {
886     unsigned int i_remainder = 0;
887     float f_last_sample = (float)*p_in / 32768.0;
888
889     *p_out = *p_in;
890     p_out += 2;
891     p_in += 2;
892
893     for ( unsigned int i = 1; i < i_in; i++ )
894     {
895         float f_in = (float)*p_in / 32768.0;
896         while ( i_remainder < i_out )
897         {
898             float f_out = f_last_sample;
899             f_out += (f_in - f_last_sample) * i_remainder / i_out;
900             if ( f_out >= 1.0 ) *p_out = 32767;
901             else if ( f_out < -1.0 ) *p_out = -32768;
902             else *p_out = f_out * 32768.0;
903             p_out += 2;
904             i_remainder += i_in;
905         }
906
907         f_last_sample = f_in;
908         p_in += 2;
909         i_remainder -= i_out;
910     }
911 }
912
913 static int DecodeAudio( demux_t *p_demux, sdi_audio_t *p_audio )
914 {
915     demux_sys_t *p_sys = p_demux->p_sys;
916     block_t *p_block;
917     int16_t *p_output;
918
919     if ( p_audio->p_buffer == NULL )
920         return VLC_EGENERIC;
921     if ( !p_audio->i_left_samples && !p_audio->i_right_samples )
922     {
923         msg_Warn( p_demux, "no audio %u/%u", p_audio->i_group,
924                   p_audio->i_pair );
925         return VLC_EGENERIC;
926     }
927     if ( p_audio->i_left_samples <
928             (float)p_audio->i_nb_samples * (1. - SAMPLERATE_TOLERANCE) ||
929         p_audio->i_left_samples >
930             (float)p_audio->i_nb_samples * (1. + SAMPLERATE_TOLERANCE) )
931     {
932         msg_Warn( p_demux,
933             "left samplerate out of tolerance for audio %u/%u (%u vs. %u)",
934             p_audio->i_group, p_audio->i_pair,
935             p_audio->i_left_samples, p_audio->i_nb_samples );
936         return VLC_EGENERIC;
937     }
938     if ( p_audio->i_right_samples <
939             (float)p_audio->i_nb_samples * (1. - SAMPLERATE_TOLERANCE) ||
940         p_audio->i_right_samples >
941             (float)p_audio->i_nb_samples * (1. + SAMPLERATE_TOLERANCE) )
942     {
943         msg_Warn( p_demux,
944             "right samplerate out of tolerance for audio %u/%u (%u vs. %u)",
945             p_audio->i_group, p_audio->i_pair,
946             p_audio->i_right_samples, p_audio->i_nb_samples );
947         return VLC_EGENERIC;
948     }
949
950     p_block = block_New( p_demux, p_audio->i_nb_samples * sizeof(int16_t) * 2 );
951     if( unlikely( !p_block ) )
952         return VLC_ENOMEM;
953     p_block->i_dts = p_block->i_pts = p_sys->i_next_date
954         + (mtime_t)p_audio->i_delay * INT64_C(1000000) / p_audio->i_rate;
955     p_output = (int16_t *)p_block->p_buffer;
956
957     if ( p_audio->i_left_samples == p_audio->i_nb_samples &&
958          p_audio->i_right_samples == p_audio->i_nb_samples )
959         vlc_memcpy( p_output, p_audio->p_buffer,
960                     p_audio->i_nb_samples * sizeof(int16_t) * 2 );
961     else
962     {
963         ResampleAudio( p_output, p_audio->p_buffer,
964                        p_audio->i_nb_samples, p_audio->i_left_samples );
965
966         ResampleAudio( p_output + 1, p_audio->p_buffer + 1,
967                        p_audio->i_nb_samples, p_audio->i_right_samples );
968     }
969
970     es_out_Send( p_demux->out, p_audio->p_es, p_block );
971     return VLC_SUCCESS;
972 }
973
974 static int DecodeFrame( demux_t *p_demux )
975 {
976     demux_sys_t *p_sys = p_demux->p_sys;
977
978     if ( p_sys->b_vbi )
979     {
980         DecodeWSS( p_demux );
981
982         if ( p_sys->i_height == 576 )
983         {
984             /* For PAL, erase first half of line 23, last half of line 623,
985              * and line 624 ; no need to erase chrominance */
986             vlc_memset( p_sys->p_y, 0, p_sys->i_width / 2 );
987             vlc_memset( p_sys->p_y + p_sys->i_width * 574 + p_sys->i_width / 2,
988                         0, p_sys->i_width * 3 / 2 );
989         }
990     }
991
992     if ( p_sys->i_telx_count )
993         if ( DecodeTelx( p_demux ) != VLC_SUCCESS )
994             return VLC_ENOMEM;
995
996     for ( int i = 0; i < MAX_AUDIOS; i++ )
997     {
998         if ( p_sys->p_audios[i].i_group && p_sys->p_audios[i].p_es != NULL )
999             if( DecodeAudio( p_demux, &p_sys->p_audios[i] ) != VLC_SUCCESS )
1000                 return VLC_EGENERIC;
1001     }
1002
1003     DecodeVideo( p_demux );
1004
1005     es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_next_date );
1006     p_sys->i_next_date += p_sys->i_incr;
1007
1008     if( NewFrame( p_demux ) != VLC_SUCCESS )
1009         return VLC_ENOMEM;
1010
1011     return VLC_SUCCESS;
1012 }
1013
1014 /*****************************************************************************
1015  * SDI syntax parsing stuff
1016  *****************************************************************************/
1017 #define FIELD_1_VBLANK_EAV  0xB6
1018 #define FIELD_1_VBLANK_SAV  0xAB
1019 #define FIELD_1_ACTIVE_EAV  0x9D
1020 #define FIELD_1_ACTIVE_SAV  0x80
1021 #define FIELD_2_VBLANK_EAV  0xF1
1022 #define FIELD_2_VBLANK_SAV  0xEC
1023 #define FIELD_2_ACTIVE_EAV  0xDA
1024 #define FIELD_2_ACTIVE_SAV  0xC7
1025
1026 static const uint8_t *FindReferenceCode( uint8_t i_code,
1027                                          const uint8_t *p_parser,
1028                                          const uint8_t *p_end )
1029 {
1030     while ( p_parser <= p_end - 5 )
1031     {
1032         if ( p_parser[0] == 0xff && p_parser[1] == 0x3 && p_parser[2] == 0x0
1033               && p_parser[3] == 0x0 && p_parser[4] == i_code )
1034             return p_parser;
1035         p_parser += 5;
1036     }
1037
1038     return NULL;
1039 }
1040
1041 static const uint8_t *CountReference( unsigned int *pi_count, uint8_t i_code,
1042                                       const uint8_t *p_parser,
1043                                       const uint8_t *p_end )
1044 {
1045     const uint8_t *p_tmp = FindReferenceCode( i_code, p_parser, p_end );
1046     if ( p_tmp == NULL )
1047     {
1048         *pi_count += p_end - p_parser;
1049         return NULL;
1050     }
1051     *pi_count += p_tmp - p_parser;
1052     return p_tmp;
1053 }
1054
1055 static const uint8_t *GetLine( demux_t *p_demux, const uint8_t **pp_parser,
1056                                const uint8_t *p_end )
1057 {
1058     demux_sys_t *p_sys = p_demux->p_sys;
1059     unsigned int i_total_size = p_sys->i_anc_size + p_sys->i_active_size;
1060     const uint8_t *p_tmp;
1061
1062     if ( p_sys->i_line_buffer )
1063     {
1064         unsigned int i_remaining = i_total_size - p_sys->i_line_buffer;
1065         vlc_memcpy( p_sys->p_line_buffer + p_sys->i_line_buffer,
1066                                    *pp_parser, i_remaining );
1067         *pp_parser += i_remaining;
1068         p_sys->i_line_buffer = 0;
1069
1070         return p_sys->p_line_buffer;
1071     }
1072
1073     if ( p_end - *pp_parser < (int)i_total_size )
1074     {
1075         vlc_memcpy( p_sys->p_line_buffer, *pp_parser,
1076                                    p_end - *pp_parser );
1077         p_sys->i_line_buffer = p_end - *pp_parser;
1078         return NULL;
1079     }
1080
1081     p_tmp = *pp_parser;
1082     *pp_parser += i_total_size;
1083     return p_tmp;
1084 }
1085
1086 #define U   (uint16_t)((p_line[0]) | ((p_line[1] & 0x3) << 8))
1087 #define Y1  (uint16_t)((p_line[1] >> 2) | ((p_line[2] & 0xf) << 6))
1088 #define V   (uint16_t)((p_line[2] >> 4) | ((p_line[3] & 0x3f) << 4))
1089 #define Y2  (uint16_t)((p_line[3] >> 6) | (p_line[4] << 2))
1090
1091 static void UnpackVBI( const uint8_t *p_line, unsigned int i_size,
1092                        uint8_t *p_dest )
1093 {
1094     const uint8_t *p_end = p_line + i_size;
1095
1096     while ( p_line < p_end )
1097     {
1098         *p_dest++ = (U + 2) / 4;
1099         *p_dest++ = (Y1 + 2) / 4;
1100         *p_dest++ = (V + 2) / 4;
1101         *p_dest++ = (Y2 + 2) / 4;
1102         p_line += 5;
1103     }
1104 }
1105
1106 /* For lines 0 [4] or 1 [4] */
1107 static void Unpack01( const uint8_t *p_line, unsigned int i_size,
1108                       uint8_t *p_y, uint8_t *p_u, uint8_t *p_v )
1109 {
1110     const uint8_t *p_end = p_line + i_size;
1111
1112     while ( p_line < p_end )
1113     {
1114         *p_u++ = (U + 2) / 4;
1115         *p_y++ = (Y1 + 2) / 4;
1116         *p_v++ = (V + 2) / 4;
1117         *p_y++ = (Y2 + 2) / 4;
1118         p_line += 5;
1119     }
1120 }
1121
1122 /* For lines 2 [4] */
1123 static void Unpack2( const uint8_t *p_line, unsigned int i_size,
1124                      uint8_t *p_y, uint8_t *p_u, uint8_t *p_v )
1125 {
1126     const uint8_t *p_end = p_line + i_size;
1127
1128     while ( p_line < p_end )
1129     {
1130         uint16_t tmp;
1131         tmp = 3 * *p_u;
1132         tmp += (U + 2) / 4;
1133         *p_u++ = tmp / 4;
1134         *p_y++ = (Y1 + 2) / 4;
1135         tmp = 3 * *p_v;
1136         tmp += (V + 2) / 4;
1137         *p_v++ = tmp / 4;
1138         *p_y++ = (Y2 + 2) / 4;
1139         p_line += 5;
1140     }
1141 }
1142
1143 /* For lines 3 [4] */
1144 static void Unpack3( const uint8_t *p_line, unsigned int i_size,
1145                      uint8_t *p_y, uint8_t *p_u, uint8_t *p_v )
1146 {
1147     const uint8_t *p_end = p_line + i_size;
1148
1149     while ( p_line < p_end )
1150     {
1151         uint16_t tmp;
1152         tmp = *p_u;
1153         tmp += 3 * (U + 2) / 4;
1154         *p_u++ = tmp / 4;
1155         *p_y++ = (Y1 + 2) / 4;
1156         tmp = *p_v;
1157         tmp += 3 * (V + 2) / 4;
1158         *p_v++ = tmp / 4;
1159         *p_y++ = (Y2 + 2) / 4;
1160         p_line += 5;
1161     }
1162 }
1163
1164 #undef U
1165 #undef Y1
1166 #undef V
1167 #undef Y2
1168
1169 #define A0  (uint16_t)((p_anc[0]) | ((p_anc[1] & 0x3) << 8))
1170 #define A1  (uint16_t)((p_anc[1] >> 2) | ((p_anc[2] & 0xf) << 6))
1171 #define A2  (uint16_t)((p_anc[2] >> 4) | ((p_anc[3] & 0x3f) << 4))
1172 #define A3  (uint16_t)((p_anc[3] >> 6) | (p_anc[4] << 2))
1173
1174 static void UnpackAnc( const uint8_t *p_anc, unsigned int i_size,
1175                        uint16_t *p_dest )
1176 {
1177     const uint8_t *p_end = p_anc + i_size;
1178
1179     while ( p_anc <= p_end - 5 )
1180     {
1181         *p_dest++ = A0;
1182         *p_dest++ = A1;
1183         *p_dest++ = A2;
1184         *p_dest++ = A3;
1185         p_anc += 5;
1186     }
1187 }
1188
1189 #undef A0
1190 #undef A1
1191 #undef A2
1192 #undef A3
1193
1194 static int HasAncillary( const uint8_t *p_anc )
1195 {
1196     return ( (p_anc[0] == 0x0 && p_anc[1] == 0xfc && p_anc[2] == 0xff
1197                && (p_anc[3] & 0x3f) == 0x3f) );
1198 }
1199
1200 static void HandleAudioData( demux_t *p_demux, const uint16_t *p_anc,
1201                              uint8_t i_data_count, uint8_t i_group,
1202                              uint8_t i_block_number )
1203 {
1204     demux_sys_t *p_sys = p_demux->p_sys;
1205
1206     if ( i_data_count % 3 )
1207     {
1208         msg_Warn( p_demux, "malformed audio data for group %u", i_group );
1209         return;
1210     }
1211
1212     for ( int i = 0; i < MAX_AUDIOS; i++ )
1213     {
1214         sdi_audio_t *p_audio = &p_sys->p_audios[i];
1215         if ( p_audio->i_group == i_group )
1216         {
1217             const uint16_t *x = p_anc;
1218
1219             /* SMPTE 272M says that when parsing a frame, if an audio config
1220              * structure is present we will encounter it first. Otherwise
1221              * it is assumed to be 48 kHz. */
1222             if ( p_audio->p_es == NULL )
1223             {
1224                 p_audio->i_rate = 48000;
1225                 p_audio->i_delay = 0;
1226                 if( InitAudio( p_demux, p_audio ) != VLC_SUCCESS )
1227                     return;
1228             }
1229
1230             if ( i_block_number )
1231             {
1232                 if ( p_audio->i_block_number + 1 != i_block_number )
1233                     msg_Warn( p_demux,
1234                               "audio data block discontinuity (%"PRIu8"->%"PRIu8") for group %"PRIu8,
1235                               p_audio->i_block_number, i_block_number,
1236                               i_group );
1237                 if ( i_block_number == 0xff )
1238                     p_audio->i_block_number = 0;
1239                 else
1240                     p_audio->i_block_number = i_block_number;
1241             }
1242
1243             while ( x < p_anc + i_data_count )
1244             {
1245                 if ( ((*x & 0x4) && p_audio->i_pair == 2)
1246                       || (!(*x & 0x4) && p_audio->i_pair == 1) )
1247                 {
1248                     uint32_t i_tmp = (uint32_t)((x[0] & 0x1f1) >> 3)
1249                                                   | ((x[1] & 0x1ff) << 6)
1250                                                   | ((x[2] & 0x1f) << 15);
1251                     int32_t i_sample;
1252                     if ( x[2] & 0x10 )
1253                         i_sample = i_tmp | 0xfff00000;
1254                     else
1255                         i_sample = i_tmp;
1256
1257                     if ( x[0] & 0x2 )
1258                     {
1259                         if ( p_audio->i_right_samples < p_audio->i_max_samples )
1260                             p_audio->p_buffer[2 * p_audio->i_right_samples
1261                                                + 1] = (i_sample + 8) / 16;
1262                         p_audio->i_right_samples++;
1263                     }
1264                     else
1265                     {
1266                         if ( p_audio->i_left_samples < p_audio->i_max_samples )
1267                             p_audio->p_buffer[2 * p_audio->i_left_samples]
1268                                 = (i_sample + 8) / 16;
1269                         p_audio->i_left_samples++;
1270                     }
1271                 }
1272                 x += 3;
1273             }
1274         }
1275     }
1276 }
1277
1278 static void HandleAudioConfig( demux_t *p_demux, const uint16_t *p_anc,
1279                                uint8_t i_data_count, uint8_t i_group )
1280 {
1281     demux_sys_t *p_sys = p_demux->p_sys;
1282
1283     if ( i_data_count != 18 )
1284     {
1285         msg_Warn( p_demux, "malformed audio config for group %u", i_group );
1286         return;
1287     }
1288
1289     for ( int i = 0; i < MAX_AUDIOS; i++ )
1290     {
1291         sdi_audio_t *p_audio = &p_sys->p_audios[i];
1292         if ( p_audio->i_group == i_group && p_audio->p_es == NULL )
1293         {
1294             unsigned int i_rate;
1295
1296             if ( p_audio->i_pair == 2 )
1297             {
1298                 i_rate = (p_anc[2] & 0xe0) >> 5;
1299                 if ( p_anc[7] & 0x1 )
1300                 {
1301                     uint32_t i_tmp = ((p_anc[7] & 0x1fe) >> 1)
1302                                        | ((p_anc[8] & 0x1ff) << 8)
1303                                        | ((p_anc[9] & 0x1ff) << 17);
1304                     if ( p_anc[9] & 0x80 )
1305                         p_audio->i_delay = i_tmp | 0xfc000000;
1306                     else
1307                         p_audio->i_delay = i_tmp;
1308                 }
1309                 if ( p_anc[13] & 0x1 )
1310                     msg_Warn( p_demux, "asymetric audio is not supported" );
1311             }
1312             else
1313             {
1314                 i_rate = (p_anc[2] & 0xe) >> 1;
1315                 if ( p_anc[4] & 0x1 )
1316                 {
1317                     uint32_t i_tmp = ((p_anc[4] & 0x1fe) >> 1)
1318                                        | ((p_anc[5] & 0x1ff) << 8)
1319                                        | ((p_anc[6] & 0x1ff) << 17);
1320                     if ( p_anc[6] & 0x80 )
1321                         p_audio->i_delay = i_tmp | 0xfc000000;
1322                     else
1323                         p_audio->i_delay = i_tmp;
1324                 }
1325                 if ( p_anc[10] & 0x1 )
1326                     msg_Warn( p_demux, "asymetric audio is not supported" );
1327             }
1328
1329             switch ( i_rate )
1330             {
1331             case 0: p_audio->i_rate = 48000; break;
1332             case 1: p_audio->i_rate = 44100; break;
1333             case 2: p_audio->i_rate = 32000; break;
1334             default:
1335                 msg_Warn( p_demux, "unknown rate for audio %u/%u (%u)",
1336                           i_group, p_sys->p_audios[i].i_pair, i_rate );
1337                 continue;
1338             }
1339
1340             if( InitAudio( p_demux, p_audio ) != VLC_SUCCESS )
1341                 return;
1342         }
1343     }
1344 }
1345
1346 /*
1347  * Ancillary packet structure:
1348  *  byte 0: Ancillary Data Flag (0)
1349  *  byte 1: Ancillary Data Flag (0x3ff)
1350  *  byte 2: Ancillary Data Flag (0x3ff)
1351  *  byte 3: Data ID (2 high order bits = parity)
1352  *  byte 4: Data Block Number 1-255 or 0=unknown (if DID < 0x80)
1353  *       or Secondary Data ID (if DID >= 0x80)
1354  *  byte 5: Data Count (10 bits)
1355  *  byte 6+DC: Checksum
1356  */
1357 static void HandleAncillary( demux_t *p_demux, const uint16_t *p_anc,
1358                              unsigned int i_size )
1359 {
1360     uint8_t i_data_count;
1361
1362     if ( i_size < 7
1363           || p_anc[0] != 0x0 || p_anc[1] != 0x3ff || p_anc[2] != 0x3ff )
1364         return;
1365
1366     i_data_count = p_anc[5] & 0xff;
1367     if ( i_size - 6 < i_data_count )
1368     {
1369         msg_Warn( p_demux, "malformed ancillary packet (size %u > %u)",
1370                   i_data_count, i_size - 6 );
1371         return;
1372     }
1373
1374     switch ( p_anc[3] ) /* Data ID */
1375     {
1376     case 0x2ff:
1377         HandleAudioData( p_demux, p_anc + 6, i_data_count, 1, p_anc[4] & 0xff );
1378         break;
1379     case 0x1fd:
1380         HandleAudioData( p_demux, p_anc + 6, i_data_count, 2, p_anc[4] & 0xff );
1381         break;
1382     case 0x1fb:
1383         HandleAudioData( p_demux, p_anc + 6, i_data_count, 3, p_anc[4] & 0xff );
1384         break;
1385     case 0x2f9:
1386         HandleAudioData( p_demux, p_anc + 6, i_data_count, 4, p_anc[4] & 0xff );
1387         break;
1388
1389     case 0x1ef:
1390         HandleAudioConfig( p_demux, p_anc + 6, i_data_count, 1 );
1391         break;
1392     case 0x2ee:
1393         HandleAudioConfig( p_demux, p_anc + 6, i_data_count, 2 );
1394         break;
1395     case 0x2ed:
1396         HandleAudioConfig( p_demux, p_anc + 6, i_data_count, 3 );
1397         break;
1398     case 0x1ec:
1399         HandleAudioConfig( p_demux, p_anc + 6, i_data_count, 4 );
1400         break;
1401
1402     /* Extended data packets, same order */
1403     case 0x1fe:
1404     case 0x2fc:
1405     case 0x2fa:
1406     case 0x1f8:
1407
1408     default:
1409         break;
1410
1411     case 0x88: /* non-conforming ANC packet */
1412         p_anc += 7;
1413         i_size -= 7;
1414         while ( i_size >= 7 && (p_anc[0] != 0x0 || p_anc[1] != 0x3ff
1415                                  || p_anc[2] != 0x3ff) )
1416         {
1417             p_anc++;
1418             i_size--;
1419         }
1420         if ( i_size >= 7 )
1421             HandleAncillary( p_demux, p_anc, i_size );
1422         return;
1423     }
1424
1425     return HandleAncillary( p_demux, p_anc + i_data_count + 7,
1426                             i_size - i_data_count - 7 );
1427
1428 }
1429
1430 static int HandleSDBuffer( demux_t *p_demux, uint8_t *p_buffer,
1431                            unsigned int i_buffer_size )
1432 {
1433     demux_sys_t *p_sys = p_demux->p_sys;
1434     const uint8_t *p_parser = p_buffer;
1435     const uint8_t *p_end = p_parser + i_buffer_size;
1436     const uint8_t *p_line;
1437
1438     if ( p_sys->i_state != STATE_SYNC
1439           && p_sys->i_last_state_change < mdate() - RESYNC_TIMEOUT )
1440     {
1441         p_sys->i_state = STATE_NOSYNC;
1442         p_sys->i_last_state_change = mdate();
1443         return VLC_EGENERIC;
1444     }
1445
1446     switch ( p_sys->i_state )
1447     {
1448     case STATE_NOSYNC:
1449     default:
1450         p_parser = FindReferenceCode( FIELD_2_VBLANK_SAV, p_parser, p_end );
1451         if ( p_parser == NULL )
1452             break;
1453         p_sys->i_state = STATE_STARTSYNC;
1454         p_sys->i_last_state_change = mdate();
1455
1456     case STATE_STARTSYNC:
1457         p_parser = FindReferenceCode( FIELD_1_VBLANK_EAV, p_parser, p_end );
1458         if ( p_parser == NULL )
1459             break;
1460         p_sys->i_anc_size = 0;
1461         p_sys->i_state = STATE_ANCSYNC;
1462         p_sys->i_last_state_change = mdate();
1463
1464     case STATE_ANCSYNC:
1465         p_parser = CountReference( &p_sys->i_anc_size,
1466                                    FIELD_1_VBLANK_SAV, p_parser, p_end );
1467         if ( p_parser == NULL )
1468             break;
1469         p_sys->i_active_size = 0;
1470         p_sys->i_state = STATE_LINESYNC;
1471         p_sys->i_last_state_change = mdate();
1472
1473     case STATE_LINESYNC:
1474         p_parser = CountReference( &p_sys->i_active_size,
1475                                    FIELD_1_VBLANK_EAV, p_parser, p_end );
1476         if ( p_parser == NULL )
1477             break;
1478         p_sys->i_picture_size = p_sys->i_anc_size + p_sys->i_active_size;
1479         p_sys->i_state = STATE_ACTIVESYNC;
1480         p_sys->i_last_state_change = mdate();
1481
1482     case STATE_ACTIVESYNC:
1483         p_parser = CountReference( &p_sys->i_picture_size,
1484                                    FIELD_1_ACTIVE_EAV, p_parser, p_end );
1485         if ( p_parser == NULL )
1486             break;
1487         p_sys->i_line_offset = p_sys->i_picture_size
1488                              / (p_sys->i_anc_size + p_sys->i_active_size);
1489         p_sys->i_state = STATE_VBLANKSYNC;
1490         p_sys->i_last_state_change = mdate();
1491
1492     case STATE_VBLANKSYNC:
1493         p_parser = CountReference( &p_sys->i_picture_size,
1494                                    FIELD_2_ACTIVE_EAV, p_parser, p_end );
1495         if ( p_parser == NULL )
1496             break;
1497         p_sys->i_state = STATE_PICSYNC;
1498         p_sys->i_last_state_change = mdate();
1499
1500     case STATE_PICSYNC:
1501         p_parser = CountReference( &p_sys->i_picture_size,
1502                                    FIELD_1_VBLANK_EAV, p_parser, p_end );
1503         if ( p_parser == NULL )
1504             break;
1505
1506         if ( p_sys->i_picture_size
1507               % (p_sys->i_anc_size + p_sys->i_active_size) )
1508         {
1509             msg_Warn( p_demux, "wrong picture size (anc=%d active=%d total=%d offset=%d), syncing",
1510                  p_sys->i_anc_size, p_sys->i_active_size,
1511                  p_sys->i_picture_size, p_sys->i_line_offset + 1 );
1512             p_sys->i_state = STATE_NOSYNC;
1513             p_sys->i_last_state_change = mdate();
1514             break;
1515         }
1516
1517         p_sys->i_nb_lines = p_sys->i_picture_size
1518                              / (p_sys->i_anc_size + p_sys->i_active_size);
1519         InitVideo( p_demux );
1520         msg_Dbg( p_demux,
1521                  "acquired sync, anc=%d active=%d lines=%d offset=%d",
1522                  p_sys->i_anc_size, p_sys->i_active_size,
1523                  p_sys->i_nb_lines, p_sys->i_line_offset + 1 );
1524         p_sys->i_state = STATE_SYNC;
1525         if( StartDecode( p_demux ) != VLC_SUCCESS )
1526         {
1527             StopDecode( p_demux );
1528             return VLC_ENOMEM;
1529         }
1530         p_sys->i_current_line = 0;
1531         p_sys->p_line_buffer = malloc( p_sys->i_anc_size
1532                                         + p_sys->i_active_size );
1533         if( !p_sys->p_line_buffer )
1534         {
1535             StopDecode( p_demux );
1536             return VLC_ENOMEM;
1537         }
1538         p_sys->i_line_buffer = 0;
1539
1540     case STATE_SYNC:
1541         while ( (p_line = GetLine( p_demux, &p_parser, p_end )) != NULL )
1542         {
1543             bool b_field = p_sys->b_hd ? false :
1544                 (p_sys->i_current_line >= p_sys->i_nb_lines / 2);
1545             unsigned int i_field_height = p_sys->b_hd ? p_sys->i_height :
1546                 p_sys->i_height / 2;
1547             unsigned int i_field_line = b_field ?
1548                 p_sys->i_current_line - (p_sys->i_nb_lines + 1) / 2 :
1549                 p_sys->i_current_line;
1550             bool b_vbi = i_field_line < p_sys->i_line_offset ||
1551                 i_field_line >= p_sys->i_line_offset + i_field_height;
1552             unsigned int anc = p_sys->i_anc_size;
1553
1554             if ( p_line[0] != 0xff || p_line[1] != 0x3
1555                   || p_line[2] != 0x0 || p_line[3] != 0x0
1556                   || p_line[anc+0] != 0xff || p_line[anc+1] != 0x3
1557                   || p_line[anc+2] != 0x0 || p_line[anc+3] != 0x0
1558                   || (!b_field && b_vbi &&
1559                       (p_line[4] != FIELD_1_VBLANK_EAV ||
1560                        p_line[anc+4] != FIELD_1_VBLANK_SAV))
1561                   || (!b_field && !b_vbi &&
1562                       (p_line[4] != FIELD_1_ACTIVE_EAV ||
1563                        p_line[anc+4] != FIELD_1_ACTIVE_SAV))
1564                   || (b_field && b_vbi &&
1565                       (p_line[4] != FIELD_2_VBLANK_EAV ||
1566                        p_line[anc+4] != FIELD_2_VBLANK_SAV))
1567                   || (b_field && !b_vbi &&
1568                       (p_line[4] != FIELD_2_ACTIVE_EAV ||
1569                        p_line[anc+4] != FIELD_2_ACTIVE_SAV)) )
1570             {
1571                 msg_Warn( p_demux, "lost sync line:%u SAV:%x EAV:%x",
1572                           p_sys->i_current_line + 1, p_line[4], p_line[anc+4] );
1573                 StopDecode( p_demux );
1574                 p_sys->i_state = STATE_NOSYNC;
1575                 p_sys->i_last_state_change = mdate();
1576                 break;
1577             }
1578
1579             if ( HasAncillary( p_line + 5 ) )
1580             {
1581                 /* HANC */
1582                 unsigned int i_anc_words = (p_sys->i_anc_size - 5) * 4 / 5;
1583                 uint16_t p_anc[i_anc_words];
1584                 UnpackAnc( p_line + 5, p_sys->i_anc_size - 5, p_anc );
1585                 HandleAncillary( p_demux, p_anc, i_anc_words );
1586             }
1587
1588             if ( !b_vbi )
1589             {
1590                 unsigned int i_active_field_line = i_field_line
1591                                                     - p_sys->i_line_offset;
1592                 unsigned int i_active_line = b_field
1593                                               + i_active_field_line * 2;
1594                 if ( !(i_active_field_line % 2) && !b_field )
1595                     Unpack01( p_line + anc + 5, p_sys->i_active_size - 5,
1596                               p_sys->p_y + p_sys->i_width * i_active_line,
1597                               p_sys->p_u + (p_sys->i_width / 2)
1598                                * (i_active_line / 2),
1599                               p_sys->p_v + (p_sys->i_width / 2)
1600                                * (i_active_line / 2) );
1601                 else if ( !(i_active_field_line % 2) )
1602                     Unpack01( p_line + anc + 5, p_sys->i_active_size - 5,
1603                               p_sys->p_y + p_sys->i_width * i_active_line,
1604                               p_sys->p_u + (p_sys->i_width / 2)
1605                                * (i_active_line / 2 + 1),
1606                               p_sys->p_v + (p_sys->i_width / 2)
1607                                * (i_active_line / 2 + 1) );
1608                 else if ( !b_field )
1609                     Unpack2( p_line + anc + 5, p_sys->i_active_size - 5,
1610                              p_sys->p_y + p_sys->i_width * i_active_line,
1611                              p_sys->p_u + (p_sys->i_width / 2)
1612                               * (i_active_line / 2 - 1),
1613                              p_sys->p_v + (p_sys->i_width / 2)
1614                               * (i_active_line / 2 - 1) );
1615                 else
1616                     Unpack3( p_line + anc + 5, p_sys->i_active_size - 5,
1617                              p_sys->p_y + p_sys->i_width * i_active_line,
1618                              p_sys->p_u + (p_sys->i_width / 2)
1619                               * (i_active_line / 2),
1620                              p_sys->p_v + (p_sys->i_width / 2)
1621                               * (i_active_line / 2) );
1622
1623                 if ( p_sys->b_vbi && p_sys->i_height == 576
1624                       && p_sys->i_current_line == p_sys->i_line_offset )
1625                 {
1626                     /* Line 23 is half VBI, half active */
1627                     UnpackVBI( p_line + anc + 5, p_sys->i_active_size - 5,
1628                                p_sys->p_wss_buffer );
1629                 }
1630             }
1631             else if ( p_sys->b_vbi && p_sys->i_telx_count &&
1632                       i_field_line >= p_sys->i_telx_line &&
1633                       i_field_line < p_sys->i_telx_line
1634                                       + p_sys->i_telx_count )
1635             {
1636                 UnpackVBI( p_line + anc + 5, p_sys->i_active_size - 5,
1637                     &p_sys->p_telx_buffer[(i_field_line
1638                         - p_sys->i_telx_line + b_field * p_sys->i_telx_count)
1639                         * p_sys->i_width * 2] );
1640             }
1641             else if ( b_vbi && HasAncillary( p_line + anc + 5 ) )
1642             {
1643                 /* VANC */
1644                 unsigned int i_anc_words = (p_sys->i_active_size - 5) * 4 / 5;
1645                 uint16_t p_anc[i_anc_words];
1646                 UnpackAnc( p_line + 5, p_sys->i_active_size - 5,
1647                            p_anc );
1648                 HandleAncillary( p_demux, p_anc, i_anc_words );
1649             }
1650
1651             p_sys->i_current_line++;
1652             if ( p_sys->i_current_line == p_sys->i_nb_lines )
1653             {
1654                 p_sys->i_current_line %= p_sys->i_nb_lines;
1655                 if( DecodeFrame( p_demux ) != VLC_SUCCESS )
1656                     return VLC_EGENERIC;
1657             }
1658         }
1659         break;
1660     }
1661
1662     return VLC_SUCCESS;
1663 }
1664
1665 /*****************************************************************************
1666  * Low-level device stuff
1667  *****************************************************************************/
1668 #define MAXLEN 256
1669
1670 static int ReadULSysfs( const char *psz_fmt, unsigned int i_link )
1671 {
1672     char psz_file[MAXLEN], psz_data[MAXLEN];
1673     char *psz_tmp;
1674     int i_fd;
1675     ssize_t i_ret;
1676     unsigned int i_data;
1677
1678     snprintf( psz_file, sizeof(psz_file) - 1, psz_fmt, i_link );
1679
1680     if ( (i_fd = vlc_open( psz_file, O_RDONLY )) < 0 )
1681         return i_fd;
1682
1683     i_ret = read( i_fd, psz_data, sizeof(psz_data) );
1684     close( i_fd );
1685
1686     if ( i_ret < 0 )
1687         return i_ret;
1688
1689     i_data = strtoul( psz_data, &psz_tmp, 0 );
1690     if ( *psz_tmp != '\n' )
1691         return -1;
1692
1693     return i_data;
1694 }
1695
1696 static ssize_t WriteULSysfs( const char *psz_fmt, unsigned int i_link,
1697                              unsigned int i_buf )
1698 {
1699     char psz_file[MAXLEN], psz_data[MAXLEN];
1700     int i_fd;
1701     ssize_t i_ret;
1702
1703     snprintf( psz_file, sizeof(psz_file) -1, psz_fmt, i_link );
1704
1705     snprintf( psz_data, sizeof(psz_data) -1, "%u\n", i_buf );
1706
1707     if ( (i_fd = vlc_open( psz_file, O_WRONLY )) < 0 )
1708         return i_fd;
1709
1710     i_ret = write( i_fd, psz_data, strlen(psz_data) + 1 );
1711     close( i_fd );
1712     return i_ret;
1713 }
1714
1715 static int InitCapture( demux_t *p_demux )
1716 {
1717     demux_sys_t *p_sys = p_demux->p_sys;
1718     const int i_page_size = getpagesize();
1719     unsigned int i_bufmemsize;
1720     int i_ret;
1721     char psz_dev[MAXLEN];
1722
1723     /* 10-bit mode or nothing */
1724     if ( WriteULSysfs( SDI_MODE_FILE, p_sys->i_link, SDI_CTL_MODE_10BIT ) < 0 )
1725     {
1726         msg_Err( p_demux, "couldn't write file " SDI_MODE_FILE, p_sys->i_link );
1727         return VLC_EGENERIC;
1728     }
1729
1730     if ( (i_ret = ReadULSysfs( SDI_BUFFERS_FILE, p_sys->i_link )) < 0 )
1731     {
1732         msg_Err( p_demux, "couldn't read file " SDI_BUFFERS_FILE,
1733                  p_sys->i_link );
1734         return VLC_EGENERIC;
1735     }
1736     p_sys->i_buffers = i_ret;
1737     p_sys->i_current_buffer = 0;
1738
1739     if ( (i_ret = ReadULSysfs( SDI_BUFSIZE_FILE, p_sys->i_link )) < 0 )
1740     {
1741         msg_Err( p_demux, "couldn't read file " SDI_BUFSIZE_FILE,
1742                  p_sys->i_link );
1743         return VLC_EGENERIC;
1744     }
1745     p_sys->i_buffer_size = i_ret;
1746     if ( p_sys->i_buffer_size % 20 )
1747     {
1748         msg_Err( p_demux, "buffer size must be a multiple of 20" );
1749         return VLC_EGENERIC;
1750     }
1751
1752     snprintf( psz_dev, sizeof(psz_dev) - 1, SDI_DEVICE, p_sys->i_link );
1753     if ( (p_sys->i_fd = vlc_open( psz_dev, O_RDONLY ) ) < 0 )
1754     {
1755         msg_Err( p_demux, "couldn't open device %s", psz_dev );
1756         return VLC_EGENERIC;
1757     }
1758
1759     i_bufmemsize = ((p_sys->i_buffer_size + i_page_size - 1) / i_page_size)
1760                      * i_page_size;
1761     p_sys->pp_buffers = malloc( p_sys->i_buffers * sizeof(uint8_t *) );
1762     if( !p_sys->pp_buffers )
1763         return VLC_ENOMEM;
1764
1765     for ( unsigned int i = 0; i < p_sys->i_buffers; i++ )
1766     {
1767         if ( (p_sys->pp_buffers[i] = mmap( NULL, p_sys->i_buffer_size,
1768                                            PROT_READ, MAP_SHARED, p_sys->i_fd,
1769                                            i * i_bufmemsize )) == MAP_FAILED )
1770         {
1771             msg_Err( p_demux, "couldn't mmap(%d): %s", i, strerror(errno) );
1772             free( p_sys->pp_buffers );
1773             return VLC_EGENERIC;
1774         }
1775     }
1776
1777     return VLC_SUCCESS;
1778 }
1779
1780 static void CloseCapture( demux_t *p_demux )
1781 {
1782     demux_sys_t *p_sys = p_demux->p_sys;
1783
1784     StopDecode( p_demux );
1785     for ( unsigned int i = 0; i < p_sys->i_buffers; i++ )
1786         munmap( p_sys->pp_buffers[i], p_sys->i_buffer_size );
1787     close( p_sys->i_fd );
1788     free( p_sys->pp_buffers );
1789 }
1790
1791 static int Capture( demux_t *p_demux )
1792 {
1793     demux_sys_t *p_sys = p_demux->p_sys;
1794     struct pollfd pfd;
1795
1796     pfd.fd = p_sys->i_fd;
1797     pfd.events = POLLIN | POLLPRI;
1798
1799     if ( poll( &pfd, 1, READ_TIMEOUT ) < 0 )
1800     {
1801         msg_Warn( p_demux, "couldn't poll(): %s", strerror(errno) );
1802         return VLC_EGENERIC;
1803     }
1804
1805     if ( pfd.revents & POLLPRI )
1806     {
1807         unsigned int i_val;
1808
1809         if ( ioctl( p_sys->i_fd, SDI_IOC_RXGETEVENTS, &i_val ) < 0 )
1810             msg_Warn( p_demux, "couldn't SDI_IOC_RXGETEVENTS %s", strerror(errno) );
1811         else
1812         {
1813             if ( i_val & SDI_EVENT_RX_BUFFER )
1814                 msg_Warn( p_demux, "driver receive buffer queue overrun" );
1815             if ( i_val & SDI_EVENT_RX_FIFO )
1816                 msg_Warn( p_demux, "onboard receive FIFO overrun");
1817             if ( i_val & SDI_EVENT_RX_CARRIER )
1818                 msg_Warn( p_demux, "carrier status change");
1819         }
1820
1821         p_sys->i_next_date += CLOCK_GAP;
1822     }
1823
1824     if ( pfd.revents & POLLIN )
1825     {
1826         int i_ret;
1827
1828         if ( ioctl( p_sys->i_fd, SDI_IOC_DQBUF, p_sys->i_current_buffer ) < 0 )
1829         {
1830             msg_Warn( p_demux, "couldn't SDI_IOC_DQBUF %s", strerror(errno) );
1831             return VLC_EGENERIC;
1832         }
1833
1834         i_ret = HandleSDBuffer( p_demux,
1835                                 p_sys->pp_buffers[p_sys->i_current_buffer],
1836                                 p_sys->i_buffer_size );
1837
1838         if ( ioctl( p_sys->i_fd, SDI_IOC_QBUF, p_sys->i_current_buffer ) < 0 )
1839         {
1840             msg_Warn( p_demux, "couldn't SDI_IOC_QBUF %s", strerror(errno) );
1841             return VLC_EGENERIC;
1842         }
1843
1844         if ( i_ret == VLC_SUCCESS )
1845         {
1846             p_sys->i_current_buffer++;
1847             p_sys->i_current_buffer %= p_sys->i_buffers;
1848         }
1849         else
1850         {
1851             /* Reference codes do not start on a multiple of 5. This sometimes
1852              * happen. We really don't want to allow this. */
1853             msg_Warn( p_demux, "resetting board" );
1854             CloseCapture( p_demux );
1855             InitCapture( p_demux );
1856         }
1857     }
1858
1859     return VLC_SUCCESS;
1860 }
1861