]> git.sesse.net Git - vlc/blob - src/input/input_netlist.c
5b40c56a8d26d9967c94378f97dd50502153bfcd
[vlc] / src / input / input_netlist.c
1 /*****************************************************************************
2  * netlist.c: input thread
3  * Manages the TS and PES netlists (see netlist.h).
4  *****************************************************************************
5  * Copyright (C) 1998, 1999, 2000 VideoLAN
6  *
7  * Authors: Christophe Massiot <massiot@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include "defs.h"
28
29 #include <sys/types.h>                        /* on BSD, uio.h needs types.h */
30 #include <sys/uio.h>                                            /* "input.h" */
31
32 #include <stdlib.h>                                                /* free() */
33 #include <string.h>                                            /* strerror() */
34 #include <errno.h>                                                  /* errno */
35
36 #include "config.h"
37 #include "common.h"
38 #include "threads.h"
39 #include "mtime.h"
40 #include "intf_msg.h"
41 #include "debug.h"
42 #include "input.h"
43 #include "input_netlist.h"
44
45 /*****************************************************************************
46  * Local prototypes
47  *****************************************************************************/
48
49 /*****************************************************************************
50  * input_NetlistOpen: initialize the netlists buffers
51  *****************************************************************************/
52 int input_NetlistInit( input_thread_t *p_input )
53 {
54     int                 i_base, i_packets, i_iovec;
55
56     /* Initialize running indexes. */
57 #ifdef INPUT_LIFO_TS_NETLIST
58     p_input->netlist.i_ts_index = INPUT_TS_READ_ONCE;
59 #else
60     p_input->netlist.i_ts_start = 0;
61     p_input->netlist.i_ts_end = 0;
62 #endif
63 #ifdef INPUT_LIFO_PES_NETLIST
64     p_input->netlist.i_pes_index = 1; /* We allocate one PES at a time */
65 #else
66     p_input->netlist.i_pes_start = 0;
67     p_input->netlist.i_pes_end = 0;
68 #endif
69
70     /* Initialize all iovec from the TS netlist with the length of a packet */
71     for( i_iovec = 0; i_iovec < INPUT_MAX_TS + INPUT_TS_READ_ONCE; i_iovec++ )
72     {
73         p_input->netlist.p_ts_free[i_iovec].iov_len = TS_PACKET_SIZE;
74     }
75
76     /* Allocate a big piece of memory to contain the INPUT_MAX_TS TS packets */
77     if( ( p_input->netlist.p_ts_packets = malloc( (INPUT_MAX_TS + 1)
78                                              * sizeof(ts_packet_t) ) ) == NULL )
79     {
80         intf_ErrMsg("input error: can't allocate TS netlist buffer (%s)\n",
81                     strerror(errno) );
82         return( -1 );
83     }
84
85   /* Allocate a big piece of memory to contain the INPUT_MAX_PES PES packets */
86     if( !( p_input->netlist.p_pes_packets = malloc( (INPUT_MAX_PES + 1)
87                                              * sizeof(pes_packet_t) ) ) )
88     {
89         intf_ErrMsg("input error: can't allocate PES netlist buffer (%s)\n",
90                     strerror(errno) );
91         free( p_input->netlist.p_ts_packets );
92         return( -1 );
93     }
94
95     /* Insert TS packets into the TS netlist */
96 #ifdef INPUT_LIFO_TS_NETLIST
97     i_base = p_input->netlist.i_ts_index;
98 #else
99     i_base = p_input->netlist.i_ts_start;
100 #endif
101     /* i_base is now the base address to locate free packets in the netlist */
102
103     for( i_packets = 0; i_packets < INPUT_MAX_TS + 1; i_packets++ )
104     {
105         p_input->netlist.p_ts_free[i_base + i_packets].iov_base
106                           = (void *)(p_input->netlist.p_ts_packets + i_packets);
107         /* Initialize TS length. */
108         (p_input->netlist.p_ts_packets[i_packets]).i_payload_end = TS_PACKET_SIZE;
109     }
110
111     /* Insert PES packets into the netlist */
112 #ifdef INPUT_LIFO_PES_NETLIST
113     i_base = p_input->netlist.i_pes_index;
114 #else
115     i_base = p_input->netlist.i_pes_start;
116 #endif
117     /* i_base is now the base address to locate free packets in the netlist */
118
119     for( i_packets = 0; i_packets < INPUT_MAX_PES + 1; i_packets++ )
120     {
121         p_input->netlist.p_pes_free[i_base + i_packets]
122                               = p_input->netlist.p_pes_packets + i_packets;
123     }
124
125     /* the p_pes_header_save buffer is allocated on the fly by the PES
126        demux if needed, and freed with the PES packet when the netlist
127        is destroyed. We initialise the field to NULL so that the demux
128        can determine if it has already allocated this buffer or not. */
129     for( i_packets = 0; i_packets < INPUT_MAX_PES + 1; i_packets++ )
130     {
131       p_input->netlist.p_pes_packets[i_packets].p_pes_header_save = NULL;
132     }
133
134     return( 0 );
135 }
136
137 /*****************************************************************************
138  * input_NetlistClean: clean the netlists buffers
139  *****************************************************************************/
140 void input_NetlistEnd( input_thread_t *p_input )
141 {
142     int i;
143
144     /* free TS netlist */
145     free( p_input->netlist.p_ts_packets );
146
147     /* free the pes_buffer_save buffers of the PES packets if they have
148        been allocated */
149     for( i = 0; i < INPUT_MAX_PES + 1; i++ )
150     {
151         byte_t* p_buffer = p_input->netlist.p_pes_packets[i].p_pes_header_save;
152         if(p_buffer)
153             free(p_buffer);
154     }
155
156     /* free PES netlist */
157     free( p_input->netlist.p_pes_packets );
158 }
159