1 /*****************************************************************************
2 * input_file.c: functions to read from a file
3 *****************************************************************************
4 * Copyright (C) 1999, 2000 VideoLAN
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.
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.
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 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
29 #include <unistd.h> /* close() */
30 #include <sys/types.h> /* on BSD, uio.h needs types.h */
31 #include <sys/uio.h> /* "input.h" */
32 #include <sys/stat.h> /* fstat, off_t ... */
33 #include <netinet/in.h> /* ntohl() */
34 #include <fcntl.h> /* open() */
35 #include <malloc.h> /* malloc, read ... */
47 #include "input_file.h"
49 #define BUF_SIZE (797*3)
54 #define TS_PACKET_SIZE 188
57 #define MAX_AUDIO_CHANNEL 15
58 #define MAX_SUBTITLES_CHANNEL 31
59 #define NO_SUBTITLES 255
61 #define REQUESTED_AC3 0
62 #define REQUESTED_MPEG 1
63 #define REQUESTED_LPCM 2
64 #define REQUESTED_NOAUDIO 255
66 #define PS_BUFFER_SIZE 16384
71 #define SUBTITLE_PES 4
74 #define UNKNOWN_PES 12
76 #define PCR_PID 0x20 /* 0x20 == first video stream
77 * 0x40 == first audio stream */
79 typedef u8 file_ts_packet[TS_PACKET_SIZE];
80 typedef file_ts_packet udp_packet[TS_IN_UDP];
82 typedef struct synchro_struct
86 mtime_t last_pcr_time;
88 file_ts_packet *last_pcr;
91 typedef struct in_data_s
97 udp_packet buf[BUF_SIZE+1];
100 typedef struct own_pcr_s
104 file_ts_packet *buf[(BUF_SIZE+1)*TS_IN_UDP+1];
107 typedef struct options_s
109 unsigned int pcr_pid;
118 unsigned int pat_counter;
119 unsigned int pmt_counter;
122 * These 3 parameters are passed
123 * as command line arguments
125 unsigned int audio_channel;
126 unsigned int subtitles_channel;
127 unsigned int audio_type;
130 * 16 audio mpeg streams
131 * 16 audio AV3 streams
132 * 16 video mpeg streams
133 * 32 subtitle streams
135 unsigned int media_counter[0x100];
136 unsigned int association_table[0x100];
137 unsigned int found_streams;
139 unsigned int found_pts;
141 unsigned int ts_to_write;
142 unsigned int ts_written;
143 unsigned int sent_ts;
145 unsigned char *ps_data;
146 unsigned char *ps_end;
147 unsigned char *ps_buffer;
150 unsigned int private_id;
151 unsigned int has_pts;
152 unsigned int pcr_pid;
154 unsigned int pes_type;
155 unsigned int pes_size;
156 unsigned int to_skip;
160 typedef struct input_file_s
162 boolean_t b_die; /* b_die flag for the disk thread */
163 vlc_thread_t disk_thread;
172 /* local prototypes */
173 void ps_fill( input_file_t * p_if, boolean_t wait );
174 ssize_t safe_read(options_t *p_options, unsigned char *buf, int count);
175 void input_DiskThread( input_file_t * p_if );
176 int init_synchro( input_file_t * p_if );
178 input_file_t input_file;
180 /******************************************************************************
181 * ConvertPCRTime : extracts and converts the PCR time in microseconds
182 ******************************************************************************/
184 s64 ConvertPCRTime(file_ts_packet *pcr_buff)
186 return( (((((s64)U32_AT(((u8*)pcr_buff)+6)) << 1) | (((u8*)pcr_buff)[10] >> 7)) * 300) / 27 );
189 /******************************************************************************
190 * wait_a_moment : Compute how long we must wait before sending a TS packet
191 ******************************************************************************/
193 static void wait_a_moment( input_file_t * p_if, file_ts_packet *ts)
195 synchro_t * p_synchro = &input_file.synchro;
197 static int retard_count = 0;
198 static s64 wait_max = 0;
199 s64 sendtime; /* the date at which the TS packet should be sent */
202 sendtime = p_synchro->last_pcr_time + p_synchro->delta_clock +
203 p_synchro->slope * ((ts - p_synchro->last_pcr + (BUF_SIZE+1)*TS_IN_UDP) % ((BUF_SIZE+1)*TS_IN_UDP));
204 wait = sendtime - mdate();
210 intf_DbgMsg( "input warning: wait time may be too long : %Ld\n", wait );
217 if( wait < wait_max )
222 if( retard_count == 16 )
229 /******************************************************************************
230 * adjust : Adjust the encoder clock & remove the PCR from own_pcr
231 ******************************************************************************/
233 static void adjust( input_file_t * p_if, file_ts_packet *ts )
235 synchro_t * p_synchro = &p_if->synchro;
236 own_pcr_t * p_own_pcr = &p_if->own_pcr;
237 file_ts_packet *next_pcr;
238 int no_discontinuity = 1;
240 if( ((u8*)ts)[5] & 0x80 )
242 /* There is a discontinuity - I recalculate the delta */
243 p_synchro->delta_clock = mdate() - ConvertPCRTime(ts);
244 intf_DbgMsg( "input warning: clock discontinuity\n" );
245 no_discontinuity = 0;
249 p_synchro->last_pcr = ts;
250 p_synchro->last_pcr_time = ConvertPCRTime( ts );
253 vlc_mutex_lock(&p_own_pcr->lock);
255 p_own_pcr->start %= (BUF_SIZE+1)*TS_IN_UDP+1;
257 /* If we have 2 consecutiv PCR, we can reevaluate slope */
258 if( (p_own_pcr->start != p_own_pcr->end) &&
260 !((((u8*) next_pcr = p_own_pcr->buf[p_own_pcr->start]))[5] & 0x80))
262 s64 current_pcr_time = ConvertPCRTime(ts);
263 s64 next_pcr_time = ConvertPCRTime(next_pcr);
265 if( (next_pcr_time - current_pcr_time < 0) || (next_pcr_time - current_pcr_time > 700000))
267 intf_DbgMsg( "input warning: possible discontinuity\n" );
268 p_synchro->delta_clock = mdate() - next_pcr_time;
272 p_synchro->slope = (next_pcr_time - current_pcr_time) /
273 ((next_pcr - ts + (BUF_SIZE+1)*TS_IN_UDP) % ((BUF_SIZE+1)*TS_IN_UDP));
277 vlc_mutex_unlock(&p_own_pcr->lock);
280 /*****************************************************************************
281 * file_next : Opens the next available file
282 *****************************************************************************/
284 int file_next( options_t *options )
286 /* the check for index == 0 should be done _before_ */
287 options->i_list_index--;
289 if( options->in != -1 )
291 close( options->in );
294 if( !strcmp( options->playlist[options->i_list_index], "-" ) )
297 return ( options->in = 0 );
301 /* read the actual file */
302 fprintf( stderr, "Playing file %s\n",
303 options->playlist[options->i_list_index] );
304 return ( options->in = open( options->playlist[options->i_list_index],
305 O_RDONLY | O_NDELAY ) );
309 /*****************************************************************************
310 * safe_read : Buffered reading method
311 *****************************************************************************/
313 ssize_t safe_read( options_t *options, unsigned char *buf, int count )
319 ret = read( options->in, buf + cnt, count - cnt );
326 /* zero means end of file */
327 if( options->i_list_index )
329 file_next( options );
343 /******************************************************************************
344 * keep_pcr : Put a TS packet in the fifo if it owns a PCR
345 ******************************************************************************/
347 int keep_pcr(int pcr_pid, file_ts_packet *ts)
349 own_pcr_t * p_own_pcr = &input_file.own_pcr;
352 if ((p[3] & 0x20) && p[4] && (p[5] & 0x10)
353 && ((((p[1]<<8)+p[2]) & 0x1FFF) == pcr_pid))
355 /* adaptation_field_control is set, adaptation_field_lenght is not 0,
356 * PCR_flag is set, pid == pcr_pid */
357 vlc_mutex_lock(&p_own_pcr->lock);
358 p_own_pcr->buf[p_own_pcr->end++] = ts;
359 p_own_pcr->end %= (BUF_SIZE+1)*TS_IN_UDP+1;
360 vlc_mutex_unlock(&p_own_pcr->lock);
368 /******************************************************************************
369 * get_pid : gets a pid from a PES type
370 ******************************************************************************/
372 int get_pid (ps_t *p_ps)
374 int i, tofind, delta;
377 switch( p_ps->pes_type )
380 delta = 0x20; /* 0x20 - 0x2f */
382 tofind = p_ps->pes_id;
385 delta = 0x40; /* 0x40 - 0x5f */
387 tofind = p_ps->pes_id;
389 /* XXX: 0x64 is for the PMT, so don't take it !!! */
391 delta = 0x80; /* 0x80 - 0x8f */
392 type = "MPEG private (AC3 audio)";
393 tofind = p_ps->private_id;
396 delta = 0x90; /* 0x90 - 0x9f */
397 type = "MPEG private (LPCM audio)";
398 tofind = p_ps->private_id;
401 delta = 0xa0; /* 0xa0 - 0xbf */
402 type = "MPEG private (DVD subtitle)";
403 tofind = p_ps->private_id;
410 i = delta + (tofind & 0x1f);
412 if( p_ps->association_table[i] == 0)
414 intf_Msg( "Found %s stream at 0x%.2x, allocating PID 0x%.2x\n",
416 p_ps->association_table[i] = 1;
423 /******************************************************************************
424 * write_media_ts : writes a ts packet from a ps stream
425 ******************************************************************************/
427 void write_media_ts(ps_t *ps, unsigned char *ts, unsigned int pid)
433 /* if offset == 0, it means we haven't examined the PS yet */
436 if (ps->pes_size < 184) {
438 ts[0] = 0x47; /* sync_byte */
439 ts[1] = 0x40; /* payload_unit_start_indicator si début de PES */
442 ts[3] = 0x30 + (ps->media_counter[pid] & 0x0f);
443 ts[4] = 184 - ps->pes_size - 1;
445 for (i=6 ; i < 188 - ps->pes_size ; i++) ts[i]=0xFF; /* facultatif ? */
446 memcpy(ts + 188 - ps->pes_size, ps->ps_data, ps->pes_size);
448 /* this PS is finished, next time we'll pick a new one */
449 ps->pes_type = NO_PES;
450 ps->ps_data += ps->pes_size;
451 ps->offset += ps->pes_size;
457 /* now we still can have offset == 0, but size is initialized */
459 ts[0] = 0x47; /* sync_byte */
460 ts[1] = (ps->offset == 0) ? 0x40 : 0x00; /* payload_unit_start_indicator si début de PES */
463 if ( (ps->offset == 0) && (ps->has_pts == 0xc0) && (ps->pcr_pid == pid) )
466 ts[3] = 0x30 + (ps->media_counter[pid] & 0x0f);
467 ts[4] = 0x07; /* taille de l'adaptation field */
468 ts[5] = 0x50; /* rtfm */
470 /* on va lire le PTS */
471 clock = ( ((s64)(ps->ps_data[9] & 0x0E) << 29) |
472 (((s64)U16_AT(ps->ps_data + 10) << 14) - (1 << 14)) |
473 ((s64)U16_AT(ps->ps_data + 12) >> 1) );
478 ts[6] = (clock & 0x1fe000000) >> 25; /* ---111111110000000000000000000000000 */
479 ts[7] = (clock & 0x001fe0000) >> 17; /* ---000000001111111100000000000000000 */
480 ts[8] = (clock & 0x00001fe00) >> 9; /* ---000000000000000011111111000000000 */
481 ts[9] = (clock & 0x0000001fe) >> 1; /* ---000000000000000000000000111111110 */
483 ts[10] = 0x7e + ((clock & 0x01) << 7) + ((extclock & 0x100) >> 8);
484 ts[11] = extclock & 0xff;
486 memcpy(ts + 4 + 8, ps->ps_data, 184 - 8);
488 ts[15] = 0xe0; /* FIXME : we don't know how to choose program yet */
490 ps->offset += 184 - 8;
491 ps->ps_data += 184 - 8;
493 else if (ps->offset <= ps->pes_size - 184)
496 ts[3] = 0x10 + (ps->media_counter[pid] & 0x0f);
497 memcpy(ts + 4, ps->ps_data, 184);
506 j = ps->pes_size - ps->offset;
507 ts[3] = 0x30 + (ps->media_counter[pid] & 0x0f);
510 for (i=6 ; i < 188 - j ; i++) ts[i]=0xFF; /* facultatif ? */
511 memcpy(ts + 4 + 184 - j, ps->ps_data, j);
512 ps->offset += j; /* offset = size */
513 ps->ps_data += j; /* offset = size */
515 /* the PES is finished */
516 ps->pes_type = NO_PES;
523 /******************************************************************************
524 * write_pat : writes a program association table
525 ******************************************************************************/
527 void write_pat(ps_t *ps, unsigned char *ts)
531 ts[0] = 0x47; /* sync_byte */
533 ts[2] = 0x00; /* PID = 0x0000 */
534 ts[3] = 0x10 + (ps->pat_counter & 0x0f);
535 ts[4] = ts[5] = 0x00;
538 ts[7] = 0x11; /* section_length = 0x011 */
541 ts[9] = 0xb0; /* TS id = 0x00b0 */
544 /* section # and last section # */
545 ts[11] = ts[12] = 0x00;
547 /* Network PID (useless) */
548 ts[13] = ts[14] = 0x00; ts[15] = 0xe0; ts[16] = 0x10;
550 /* Program Map PID */
551 ts[17] = 0x03; ts[18] = 0xe8; ts[19] = 0xe0; ts[20] = 0x64;
554 ts[21] = 0x4d; ts[22] = 0x6a; ts[23] = 0x8b; ts[24] = 0x0f;
556 for (i=25 ; i < 188 ; i++) ts[i]=0xFF; /* facultatif ? */
561 /******************************************************************************
562 * write_pmt : writes a program map table
563 ******************************************************************************/
565 void write_pmt(ps_t *ps, unsigned char *ts)
569 ts[0] = 0x47; /* sync_byte */
571 ts[2] = 0x0064; /* PID = 0x0064 */
572 ts[3] = 0x10 + (ps->pmt_counter & 0x0f);
578 ts[7] = 0x34; /* section_length = 0x034 */
581 ts[9] = 0xe8; /* prog number */
584 /* section # and last section # */
585 ts[11] = ts[12] = 0x00;
591 /* program_info_length == 0 */
592 ts[15] = 0xf0; ts[16] = 0x00;
594 /* Program Map / Video PID */
595 ts[17] = 0x02; /* stream type = video */
596 ts[18] = 0xe0; ts[19] = 0x20;
597 ts[20] = 0xf0; ts[21] = 0x09; /* es info length */
600 ts[22] = 0x07; ts[23] = 0x04; ts[24] = 0x08; ts[25] = 0x80; ts[26] = 0x24;
601 ts[27] = 0x02; ts[28] = 0x11; ts[29] = 0x01; ts[30] = 0xfe;
603 switch ( ps->audio_type )
608 ts[31] = 0x81; /* stream type = audio */
609 ts[32] = 0xe0; ts[33] = 0x80 + ps->audio_channel;
610 ts[34] = 0xf0; ts[35] = 0x00; /* es info length */
613 case REQUESTED_MPEG :
615 ts[31] = 0x04; /* stream type = audio */
616 ts[32] = 0xe0; ts[33] = 0x40 + ps->audio_channel;
617 ts[34] = 0xf0; ts[35] = 0x00; /* es info length */
620 case REQUESTED_LPCM :
623 ts[32] = 0xe0; ts[33] = 0xa0 + ps->audio_channel;
624 ts[34] = 0xf0; ts[35] = 0x00; /* es info length */
630 ts[35] = 0x00; /* es info length */
634 if( ps->subtitles_channel == NO_SUBTITLES )
637 ts[37] = 0x00; ts[38] = 0x00;
638 ts[39] = 0xf0; ts[40] = 0x00; /* es info length */
643 ts[37] = 0xe0; ts[38] = 0xa0 + ( ps->subtitles_channel );
644 ts[39] = 0xf0; ts[40] = 0x00; /* es info length */
647 /* CRC FIXME: not calculated yet*/
648 ts[41] = 0x96; ts[42] = 0x70; ts[43] = 0x0b; ts[44] = 0x7c;
651 for (i=45 ; i < 188 ; i++) ts[i]=0xff; /* facultatif ? */
657 /******************************************************************************
659 ******************************************************************************
660 * We use threading to allow cool non-blocking read from the disk. This
661 * implicit thread is the disk (producer) thread, it reads packets from
662 * the PS file on the disk, and stores them in a FIFO.
663 ******************************************************************************/
665 void ps_thread( input_file_t * p_if )
668 ps_t * p_ps = &p_if->ps;
669 own_pcr_t * p_own_pcr = &p_if->own_pcr;
670 in_data_t * p_in_data = &p_if->in_data;
672 /* Initialize the structures */
673 p_own_pcr->start = p_own_pcr->end = 0; /* empty FIFO */
674 vlc_mutex_init( &p_own_pcr->lock );
675 p_in_data->start = p_in_data->end = 0; /* empty FIFO */
676 vlc_mutex_init( &p_in_data->lock );
677 vlc_cond_init( &p_in_data->notfull );
678 vlc_cond_init( &p_in_data->notempty );
680 p_ps->audio_type = main_GetIntVariable( INPUT_DVD_AUDIO_VAR, REQUESTED_AC3 );
681 p_ps->audio_channel = main_GetIntVariable( INPUT_DVD_CHANNEL_VAR, 0 );
682 p_ps->subtitles_channel = main_GetIntVariable( INPUT_DVD_SUBTITLE_VAR, 0 );
684 p_ps->pes_type = NO_PES;
686 p_ps->private_id = 0;
689 p_ps->pmt_counter = 0;
690 p_ps->pat_counter = 0;
691 for( i=0; i<256; i++ )
692 p_ps->association_table[i] = 0;
695 p_ps->found_streams = 0;
696 p_ps->pcr_pid = p_if->options.pcr_pid;
698 p_ps->ps_buffer = malloc(PS_BUFFER_SIZE);
699 /* those 2 addresses are initialized so that a new packet is read */
700 p_ps->ps_data = p_ps->ps_buffer + PS_BUFFER_SIZE - 1;
701 /* fix the first byte stuff */
702 p_ps->ps_data[0] = 0x00;
703 p_ps->ps_end = p_ps->ps_buffer + PS_BUFFER_SIZE;
705 /* Fill the fifo until it is full */
707 /* Launch the thread which fills the fifo */
708 vlc_thread_create( &p_if->disk_thread, "disk thread",
709 (vlc_thread_func_t)input_DiskThread, p_if );
710 /* Init the synchronization XXX add error detection !!! */
711 init_synchro( p_if );
714 /******************************************************************************
715 * ps_read : ps reading method
716 ******************************************************************************/
718 ssize_t ps_read( options_t *p_options, ps_t * p_ps, void *ts )
720 int pid, readbytes = 0;
722 p_ps->ts_written = 0;
724 while(p_ps->ts_to_write)
727 /* if there's not enough data to send */
728 if((datasize = p_ps->ps_end - p_ps->ps_data) <= TS_PACKET_SIZE)
730 /* copy the remaining bits at the beginning of the PS buffer */
731 memmove ( p_ps->ps_buffer, p_ps->ps_data, datasize);
732 /* read some bytes */
733 readbytes = safe_read( p_options, p_ps->ps_buffer + datasize, PS_BUFFER_SIZE - datasize);
737 intf_ErrMsg ( "input: ps read error\n");
740 p_ps->ps_data = p_ps->ps_buffer;
741 p_ps->ps_end = p_ps->ps_data + datasize + readbytes;
744 //printf("offset is %x, pes total size is %x, to skip is %x\n", p_ps->offset, p_ps->pes_size, p_ps->to_skip );
745 if( p_ps->to_skip == 0 && p_ps->offset == p_ps->pes_size )
747 if( p_ps->ps_data[0] || p_ps->ps_data[1] || (p_ps->ps_data[2] != 0x01) )
749 intf_ErrMsg ( "input error: not a startcode (0x%.2x%.2x%.2x instead of 0x000001)\n", p_ps->ps_data[0], p_ps->ps_data[1], p_ps->ps_data[2] );
753 p_ps->pes_type = NO_PES;
755 p_ps->pes_size = (p_ps->ps_data[4] << 8) + p_ps->ps_data[5] + 6;
756 p_ps->has_pts = p_ps->ps_data[7] & 0xc0;
759 /* if the actual data we have in pes_data is not a PES, then
760 * we read the next one. */
761 if( (p_ps->pes_type == NO_PES) && !p_ps->to_skip )
763 p_ps->pes_id = p_ps->ps_data[3];
765 if (p_ps->pes_id == 0xbd)
767 p_ps->private_id = p_ps->ps_data[ 9 + p_ps->ps_data[8] ];
768 if ((p_ps->private_id & 0xf0) == 0x80)
771 p_ps->pes_type = AC3_PES;
773 else if ((p_ps->private_id & 0xf0) == 0x20)
776 p_ps->pes_type = SUBTITLE_PES;
780 /* unknown private data */
781 p_ps->pes_type = PRIVATE_PES;
784 else if ((p_ps->pes_id & 0xe0) == 0xc0)
787 p_ps->pes_type = AUDIO_PES;
788 //write (1, p_ps->ps_data + 9 + p_ps->ps_data[8], 2048 - (9 + p_ps->ps_data[8]));
790 else if ((p_ps->pes_id & 0xf0) == 0xe0)
793 p_ps->pes_type = VIDEO_PES;
795 else if (p_ps->pes_id == 0xba)
797 p_ps->pes_type = NO_PES;
798 p_ps->pes_size = 14; /* 8 extra characters after 0x000001ba**** */
803 p_ps->pes_type = UNKNOWN_PES;
804 p_ps->to_skip = p_ps->pes_size;
810 if( p_ps->to_skip < TS_PACKET_SIZE )
812 p_ps->ps_data += p_ps->to_skip;
813 p_ps->offset += p_ps->to_skip;
818 p_ps->ps_data += TS_PACKET_SIZE;
819 p_ps->offset += TS_PACKET_SIZE;
820 p_ps->to_skip -= TS_PACKET_SIZE;
824 /* now that we know what we have, we can either
825 * write this packet's data in the buffer, skip it,
826 * or write a PMT or PAT table and wait for the next
827 * turn before writing the packet. */
828 switch (p_ps->sent_ts & 0xff)
833 p_ps->ts_to_write--; p_ps->ts_written++; ts+=188;
838 p_ps->ts_to_write--; p_ps->ts_written++; ts+=188;
842 /* if there's still no found PCR_PID, and no PTS in this PES, we trash it */
843 if (!p_ps->found_pts)
847 intf_Msg( "input: found a PTS, at last ...\n" );
851 p_ps->pes_type = NO_PES;
854 if (p_ps->ts_to_write)
856 switch(p_ps->pes_type)
862 pid = get_pid (p_ps);
863 write_media_ts(p_ps, ts, pid);
864 p_ps->ts_to_write--; p_ps->ts_written++; ts+=188;
865 p_ps->media_counter[pid]++;
869 p_ps->pes_type = NO_PES;
875 //p_ps->ps_data += TS_PACKET_SIZE;
877 return p_ps->ts_written;
880 /******************************************************************************
881 * ps_fill : Fill the data buffer with TS created from a PS file
882 ******************************************************************************/
884 void ps_fill( input_file_t * p_if, boolean_t wait )
886 in_data_t * p_in_data = &p_if->in_data;
887 ps_t * p_ps = &p_if->ps;
892 /* How many TS packet for the next UDP packet */
893 how_many = TS_IN_UDP;
896 /* for every single TS packet */
897 while( !p_if->b_die )
899 /* wait until we have one free item to store the UDP packet read */
900 vlc_mutex_lock(&p_in_data->lock);
901 while((p_in_data->end+BUF_SIZE+1-p_in_data->start)%(BUF_SIZE+1) == BUF_SIZE )
903 /* The buffer is full */
906 vlc_cond_wait(&p_in_data->notfull, &p_in_data->lock);
912 vlc_mutex_unlock(&p_in_data->lock);
915 intf_ErrMsg( "input error: bad PCR PID\n" );
920 vlc_mutex_unlock(&p_in_data->lock);
922 /* read a whole UDP packet from the file */
923 p_ps->ts_to_write = how_many;
924 if(ps_read(&p_if->options, p_ps, ts = (file_ts_packet *)(p_in_data->buf + p_in_data->end)) != how_many)
926 msleep( 50000 ); /* XXX we need an INPUT_IDLE */
927 intf_ErrMsg( "input error: read() error\n" );
930 /* Scan to mark TS packets containing a PCR */
931 for(i=0; i<how_many; i++, ts++)
933 pcr_flag |= keep_pcr(p_ps->pcr_pid, ts);
936 vlc_mutex_lock(&p_in_data->lock);
938 p_in_data->end %= BUF_SIZE+1;
939 vlc_cond_signal(&p_in_data->notempty);
940 vlc_mutex_unlock(&p_in_data->lock);
944 int init_synchro( input_file_t * p_if )
947 int howmany = TS_IN_UDP;
949 synchro_t * p_synchro = &p_if->synchro;
950 in_data_t * p_in_data = &p_if->in_data;
951 own_pcr_t * p_own_pcr = &p_if->own_pcr;
953 p_synchro->slope = 0;
957 * Initialisation of the synchro mecanism : wait for 1 PCR
958 * to evaluate delta_clock
963 vlc_mutex_lock( &p_in_data->lock );
965 while( p_in_data->end == p_in_data->start )
967 vlc_cond_wait(&p_in_data->notempty, &p_in_data->lock);
970 if( p_in_data->end == p_in_data->start )
972 intf_ErrMsg( "input error: init_synchro error, not enough PCR found\n" );
976 vlc_mutex_unlock( &p_in_data->lock );
978 ts = (file_ts_packet*)(p_in_data->buf + p_in_data->start);
979 for( i=0 ; i < howmany ; i++, ts++ )
981 if( ts == p_own_pcr->buf[p_own_pcr->start] && !(((u8*)ts)[5] & 0x80) )
983 p_synchro->last_pcr = ts;
984 p_synchro->last_pcr_time = ConvertPCRTime( ts );
985 p_synchro->delta_clock = mdate() - ConvertPCRTime(ts);
991 vlc_mutex_lock( &p_in_data->lock );
993 p_in_data->start %= BUF_SIZE + 1;
994 vlc_cond_signal( &p_in_data->notfull );
995 vlc_mutex_unlock( &p_in_data->lock );
1003 /*****************************************************************************
1004 * input_DiskThread : main thread
1005 *****************************************************************************/
1007 void input_DiskThread( input_file_t * p_if )
1013 /*****************************************************************************
1014 * input_FileOpen : open a file descriptor
1015 *****************************************************************************/
1016 int input_FileOpen( input_thread_t *p_input )
1018 options_t * p_options = &input_file.options;
1022 p_options->playlist = (char **)p_input->p_source;
1023 p_options->i_list_index = p_input->i_port;
1025 if( file_next( p_options ) < 0 )
1027 intf_ErrMsg( "input error: cannot open the file %s", p_input->p_source );
1030 input_file.b_die = 0;
1031 safe_read( p_options, &p_options->i_file_type, 1 );
1033 switch( p_options->i_file_type )
1036 p_options->pcr_pid = PCR_PID;
1037 ps_thread( &input_file );
1040 intf_ErrMsg( "input error: ts files are not currently supported\n" );
1043 intf_ErrMsg( "input error: cannot determine stream type\n" );
1051 /*****************************************************************************
1052 * input_FileRead : read from a file
1053 *****************************************************************************/
1054 int input_FileRead( input_thread_t *p_input, const struct iovec *p_vector,
1057 in_data_t * p_in_data = &input_file.in_data;
1058 synchro_t * p_synchro = &input_file.synchro;
1059 own_pcr_t * p_own_pcr = &input_file.own_pcr;
1061 file_ts_packet * ts;
1064 * End condition not verified, should put a flag in ps_fill
1066 howmany = TS_IN_UDP;
1068 vlc_mutex_lock( &p_in_data->lock );
1069 while( p_in_data->end == p_in_data->start )
1071 if( !input_file.b_die )
1072 vlc_cond_wait( &p_in_data->notempty, &p_in_data->lock );
1074 vlc_mutex_unlock( &p_in_data->lock );
1076 ts = (file_ts_packet*)(p_in_data->buf + p_in_data->start);
1077 for( i=0 ; i < howmany ; i++, ts++ )
1079 if( p_synchro->slope && (i == howmany-1) )
1081 wait_a_moment( &input_file, ts );
1083 if( ts == p_own_pcr->buf[p_own_pcr->start] )
1085 /* the TS packet contains a PCR, so we try to adjust the clock */
1086 adjust( &input_file, ts );
1090 for( i=0 ; i<howmany ; i++ )
1092 memcpy( p_vector[i].iov_base, (char*)(ts - howmany + i), p_vector[i].iov_len );
1095 vlc_mutex_lock(&p_in_data->lock);
1097 p_in_data->start %= BUF_SIZE + 1;
1098 vlc_cond_signal(&p_in_data->notfull);
1099 vlc_mutex_unlock(&p_in_data->lock);
1101 return( 188*howmany );
1104 /*****************************************************************************
1105 * input_FileClose : close a file descriptor
1106 *****************************************************************************/
1107 void input_FileClose( input_thread_t *p_input )
1109 input_file.b_die = 1;
1110 vlc_cond_signal( &input_file.in_data.notfull );
1111 vlc_thread_join( input_file.disk_thread );
1113 close( input_file.options.in );