Mercurial > mplayer.hg
annotate stream/stream.h @ 23510:a6c619ee9d30
Teletext support for tv:// (v4l and v4l2 only)
modified patch from Otvos Attila oattila at chello dot hu
Module uses zvbi library for all low-level VBI operations (like I/O with vbi
device, converting vbi pages into usefull vbi_page stuctures, rendering them
into RGB32 images).
All teletext related stuff (except properties, slave commands and rendering
osd in text mode or RGB32 rendered teletext pages in spu mode) is implemented
in tvi_vbi.c
New properties:
teletext_page - switching between pages
teletext_mode - switch between on/off/opaque/transparent modes
teletext_format - (currently read-only) allows to get format info
(black/white,gray,text)
teletext_half_page - trivial zooming (displaying top/bottom half of teletext
page)
New slave commands:
teletext_add_dec - user interface for jumping to any page by editing page number
interactively
teletext_go_link - goes though links, specified on current page
author | voroshil |
---|---|
date | Sun, 10 Jun 2007 00:06:12 +0000 |
parents | 52c574919687 |
children | 3f0d00abc073 |
rev | line source |
---|---|
998
8c83e3ff26cc
Added ifndef to prevent multiple header file inclusion.
bertrand
parents:
692
diff
changeset
|
1 #ifndef __STREAM_H |
8c83e3ff26cc
Added ifndef to prevent multiple header file inclusion.
bertrand
parents:
692
diff
changeset
|
2 #define __STREAM_H |
578 | 3 |
5086 | 4 #include "mp_msg.h" |
7412
ecef4f2191b2
some cosmetics - reordering declarations, 10l for cache2
arpi
parents:
7408
diff
changeset
|
5 #include <string.h> |
4029
3c87dee7a324
patch for missing include by Steven M. Schultz <sms@2BSD.COM>
pl
parents:
3998
diff
changeset
|
6 #include <inttypes.h> |
5292 | 7 #include <sys/types.h> |
4029
3c87dee7a324
patch for missing include by Steven M. Schultz <sms@2BSD.COM>
pl
parents:
3998
diff
changeset
|
8 |
7407 | 9 #define STREAMTYPE_DUMMY -1 // for placeholders, when the actual reading is handled in the demuxer |
10 #define STREAMTYPE_FILE 0 // read from seekable file | |
11 #define STREAMTYPE_VCD 1 // raw mode-2 CDROM reading, 2324 bytes/sector | |
12 #define STREAMTYPE_STREAM 2 // same as FILE but no seeking (for net/stdin) | |
13 #define STREAMTYPE_DVD 3 // libdvdread | |
14 #define STREAMTYPE_MEMORY 4 // read data from memory area | |
15 #define STREAMTYPE_PLAYLIST 6 // FIXME!!! same as STREAMTYPE_FILE now | |
16 #define STREAMTYPE_DS 8 // read from a demuxer stream | |
17 #define STREAMTYPE_DVDNAV 9 // we cannot safely "seek" in this... | |
18 #define STREAMTYPE_CDDA 10 // raw audio CD reader | |
7630
4c51ce16c4a2
smb:// (samba client) support by Vladimir Moushkov <vlindos_mpdev@abv.bg>
arpi
parents:
7412
diff
changeset
|
19 #define STREAMTYPE_SMB 11 // smb:// url, using libsmbclient (samba) |
8782
6af7a6595cc9
cdrwin-style bin/cue VCD image support (-vcd <track> -cuefile file.cue)
arpi
parents:
8164
diff
changeset
|
20 #define STREAMTYPE_VCDBINCUE 12 // vcd directly from bin/cue files |
9610 | 21 #define STREAMTYPE_DVB 13 |
14836
8b9738526dd7
added a stream module for the vstream client library
joey
parents:
13089
diff
changeset
|
22 #define STREAMTYPE_VSTREAM 14 |
15585 | 23 #define STREAMTYPE_SDP 15 |
18997 | 24 #define STREAMTYPE_PVR 16 |
19295
f6316aa3a7f2
conversion from stream_null to stream_tv was missing stream type
ben
parents:
19271
diff
changeset
|
25 #define STREAMTYPE_TV 17 |
19301 | 26 #define STREAMTYPE_MF 18 |
19568
bd821fd3e244
Radio support, patch by Vladimir Voroshilov (voroshil gmail com)
reimar
parents:
19475
diff
changeset
|
27 #define STREAMTYPE_RADIO 19 |
578 | 28 |
7412
ecef4f2191b2
some cosmetics - reordering declarations, 10l for cache2
arpi
parents:
7408
diff
changeset
|
29 #define STREAM_BUFFER_SIZE 2048 |
ecef4f2191b2
some cosmetics - reordering declarations, 10l for cache2
arpi
parents:
7408
diff
changeset
|
30 |
578 | 31 #define VCD_SECTOR_SIZE 2352 |
32 #define VCD_SECTOR_OFFS 24 | |
33 #define VCD_SECTOR_DATA 2324 | |
34 | |
9794 | 35 /// atm it will always use mode == STREAM_READ |
36 /// streams that use the new api should check the mode at open | |
37 #define STREAM_READ 0 | |
38 #define STREAM_WRITE 1 | |
39 /// Seek flags, if not mannualy set and s->seek isn't NULL | |
40 /// STREAM_SEEK is automaticly set | |
41 #define STREAM_SEEK_BW 2 | |
42 #define STREAM_SEEK_FW 4 | |
43 #define STREAM_SEEK (STREAM_SEEK_BW|STREAM_SEEK_FW) | |
44 | |
45 //////////// Open return code | |
46 /// This can't open the requested protocol (used by stream wich have a | |
47 /// * protocol when they don't know the requested protocol) | |
48 #define STREAM_UNSUPORTED -1 | |
49 #define STREAM_ERROR 0 | |
50 #define STREAM_OK 1 | |
51 | |
52 #define MAX_STREAM_PROTOCOLS 10 | |
53 | |
9851 | 54 #define STREAM_CTRL_RESET 0 |
17696
66d7afee9a46
added new stream_control() and new command: STREAM_CTRL_GET_TIME_LENGTH
nicodvb
parents:
17012
diff
changeset
|
55 #define STREAM_CTRL_GET_TIME_LENGTH 1 |
19434
f2da98669a77
new STREAM_CTRL_SEEK_TO_CHAPTER (will be used by streams dvd[nav], maybe [s]vcd
nicodvb
parents:
19301
diff
changeset
|
56 #define STREAM_CTRL_SEEK_TO_CHAPTER 2 |
19437
c73bf418b291
new stream_ctrl to get currently playing chapter (needed for stream-driven relative chapter seeking)
nicodvb
parents:
19434
diff
changeset
|
57 #define STREAM_CTRL_GET_CURRENT_CHAPTER 3 |
19475
1f117b5fb5a1
added STREAM_CTRL_GET_NUM_CHAPTERS to get total number of chapters from the stream reader
nicodvb
parents:
19437
diff
changeset
|
58 #define STREAM_CTRL_GET_NUM_CHAPTERS 4 |
20744
30091c3ad3cd
added definitions of STREAM_CTRL_GET_CURRENT_TIME STREAM_CTRL_SEEK_TO_TIME
nicodvb
parents:
19568
diff
changeset
|
59 #define STREAM_CTRL_GET_CURRENT_TIME 5 |
30091c3ad3cd
added definitions of STREAM_CTRL_GET_CURRENT_TIME STREAM_CTRL_SEEK_TO_TIME
nicodvb
parents:
19568
diff
changeset
|
60 #define STREAM_CTRL_SEEK_TO_TIME 6 |
21657
5f5ed194b54b
new STREAM_CTRL_GET_SIZE to get size of output stream
nicodvb
parents:
21655
diff
changeset
|
61 #define STREAM_CTRL_GET_SIZE 7 |
9794 | 62 |
10121
d42177a0da2a
Changed the STREAMING defines to MPLAYER_NETWORK to avoid name definition clash.
bertrand
parents:
9886
diff
changeset
|
63 #ifdef MPLAYER_NETWORK |
3043
02a43ca97b52
Added a new struct to stream_t to handle, network streaming.
bertrand
parents:
2935
diff
changeset
|
64 #include "network.h" |
02a43ca97b52
Added a new struct to stream_t to handle, network streaming.
bertrand
parents:
2935
diff
changeset
|
65 #endif |
02a43ca97b52
Added a new struct to stream_t to handle, network streaming.
bertrand
parents:
2935
diff
changeset
|
66 |
9794 | 67 struct stream_st; |
68 typedef struct stream_info_st { | |
69 const char *info; | |
70 const char *name; | |
71 const char *author; | |
72 const char *comment; | |
73 /// mode isn't used atm (ie always READ) but it shouldn't be ignored | |
74 /// opts is at least in it's defaults settings and may have been | |
75 /// altered by url parsing if enabled and the options string parsing. | |
76 int (*open)(struct stream_st* st, int mode, void* opts, int* file_format); | |
77 char* protocols[MAX_STREAM_PROTOCOLS]; | |
78 void* opts; | |
79 int opts_url; /* If this is 1 we will parse the url as an option string | |
80 * too. Otherwise options are only parsed from the | |
81 * options string given to open_stream_plugin */ | |
82 } stream_info_t; | |
83 | |
8164
487cfc28525d
New config system + cleanup of header inter dependency
albeu
parents:
7854
diff
changeset
|
84 typedef struct stream_st { |
9794 | 85 // Read |
86 int (*fill_buffer)(struct stream_st *s, char* buffer, int max_len); | |
87 // Write | |
88 int (*write_buffer)(struct stream_st *s, char* buffer, int len); | |
89 // Seek | |
90 int (*seek)(struct stream_st *s,off_t pos); | |
91 // Control | |
92 // Will be later used to let streams like dvd and cdda report | |
93 // their structure (ie tracks, chapters, etc) | |
94 int (*control)(struct stream_st *s,int cmd,void* arg); | |
95 // Close | |
96 void (*close)(struct stream_st *s); | |
97 | |
7407 | 98 int fd; // file descriptor, see man open(2) |
99 int type; // see STREAMTYPE_* | |
9794 | 100 int flags; |
101 int sector_size; // sector size (seek will be aligned on this size if non 0) | |
578 | 102 unsigned int buf_pos,buf_len; |
6224
79b2b4c3c435
off_t fields reordered, to avoid problems due to struct padding
arpi
parents:
5819
diff
changeset
|
103 off_t pos,start_pos,end_pos; |
79b2b4c3c435
off_t fields reordered, to avoid problems due to struct padding
arpi
parents:
5819
diff
changeset
|
104 int eof; |
21655 | 105 int mode; //STREAM_READ or STREAM_WRITE |
2322 | 106 unsigned int cache_pid; |
107 void* cache_data; | |
7329
9129781e5939
removed messy global 'tv_handle', use stream->priv for that purpose
arpi
parents:
7245
diff
changeset
|
108 void* priv; // used for DVD, TV, RTSP etc |
7407 | 109 char* url; // strdup() of filename/url |
10121
d42177a0da2a
Changed the STREAMING defines to MPLAYER_NETWORK to avoid name definition clash.
bertrand
parents:
9886
diff
changeset
|
110 #ifdef MPLAYER_NETWORK |
3043
02a43ca97b52
Added a new struct to stream_t to handle, network streaming.
bertrand
parents:
2935
diff
changeset
|
111 streaming_ctrl_t *streaming_ctrl; |
02a43ca97b52
Added a new struct to stream_t to handle, network streaming.
bertrand
parents:
2935
diff
changeset
|
112 #endif |
7407 | 113 unsigned char buffer[STREAM_BUFFER_SIZE>VCD_SECTOR_SIZE?STREAM_BUFFER_SIZE:VCD_SECTOR_SIZE]; |
578 | 114 } stream_t; |
115 | |
2322 | 116 #ifdef USE_STREAM_CACHE |
4825
41d2da3bd082
Make blocking call in libmpdemux interuptable (only with new input,
albeu
parents:
4551
diff
changeset
|
117 int stream_enable_cache(stream_t *stream,int size,int min,int prefill); |
7412
ecef4f2191b2
some cosmetics - reordering declarations, 10l for cache2
arpi
parents:
7408
diff
changeset
|
118 int cache_stream_fill_buffer(stream_t *s); |
ecef4f2191b2
some cosmetics - reordering declarations, 10l for cache2
arpi
parents:
7408
diff
changeset
|
119 int cache_stream_seek_long(stream_t *s,off_t pos); |
2322 | 120 #else |
7412
ecef4f2191b2
some cosmetics - reordering declarations, 10l for cache2
arpi
parents:
7408
diff
changeset
|
121 // no cache, define wrappers: |
22540
52c574919687
Fix live555 compilation when stream cache is disabled.
diego
parents:
21657
diff
changeset
|
122 int stream_fill_buffer(stream_t *s); |
52c574919687
Fix live555 compilation when stream cache is disabled.
diego
parents:
21657
diff
changeset
|
123 int stream_seek_long(stream_t *s,off_t pos); |
2322 | 124 #define cache_stream_fill_buffer(x) stream_fill_buffer(x) |
125 #define cache_stream_seek_long(x,y) stream_seek_long(x,y) | |
5292 | 126 #define stream_enable_cache(x,y,z,w) 1 |
2322 | 127 #endif |
15954 | 128 void fixup_network_stream_cache(stream_t *stream); |
21655 | 129 int stream_write_buffer(stream_t *s, unsigned char *buf, int len); |
1428
a90d889eb649
largefile patch by Stephen Davies <steve@daviesfam.org>
arpi
parents:
998
diff
changeset
|
130 |
578 | 131 inline static int stream_read_char(stream_t *s){ |
132 return (s->buf_pos<s->buf_len)?s->buffer[s->buf_pos++]: | |
2322 | 133 (cache_stream_fill_buffer(s)?s->buffer[s->buf_pos++]:-256); |
578 | 134 // if(s->buf_pos<s->buf_len) return s->buffer[s->buf_pos++]; |
135 // stream_fill_buffer(s); | |
136 // if(s->buf_pos<s->buf_len) return s->buffer[s->buf_pos++]; | |
137 // return 0; // EOF | |
138 } | |
139 | |
140 inline static unsigned int stream_read_word(stream_t *s){ | |
141 int x,y; | |
142 x=stream_read_char(s); | |
143 y=stream_read_char(s); | |
144 return (x<<8)|y; | |
145 } | |
146 | |
147 inline static unsigned int stream_read_dword(stream_t *s){ | |
148 unsigned int y; | |
149 y=stream_read_char(s); | |
150 y=(y<<8)|stream_read_char(s); | |
151 y=(y<<8)|stream_read_char(s); | |
152 y=(y<<8)|stream_read_char(s); | |
153 return y; | |
154 } | |
155 | |
4189 | 156 #define stream_read_fourcc stream_read_dword_le |
157 | |
578 | 158 inline static unsigned int stream_read_word_le(stream_t *s){ |
159 int x,y; | |
160 x=stream_read_char(s); | |
161 y=stream_read_char(s); | |
162 return (y<<8)|x; | |
163 } | |
164 | |
165 inline static unsigned int stream_read_dword_le(stream_t *s){ | |
166 unsigned int y; | |
167 y=stream_read_char(s); | |
168 y|=stream_read_char(s)<<8; | |
169 y|=stream_read_char(s)<<16; | |
170 y|=stream_read_char(s)<<24; | |
171 return y; | |
172 } | |
173 | |
3998 | 174 inline static uint64_t stream_read_qword(stream_t *s){ |
175 uint64_t y; | |
176 y = stream_read_char(s); | |
177 y=(y<<8)|stream_read_char(s); | |
178 y=(y<<8)|stream_read_char(s); | |
179 y=(y<<8)|stream_read_char(s); | |
180 y=(y<<8)|stream_read_char(s); | |
181 y=(y<<8)|stream_read_char(s); | |
182 y=(y<<8)|stream_read_char(s); | |
183 y=(y<<8)|stream_read_char(s); | |
184 return y; | |
185 } | |
186 | |
11807
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
187 inline static uint64_t stream_read_qword_le(stream_t *s){ |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
188 uint64_t y; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
189 y = stream_read_char(s); |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
190 y|=stream_read_char(s)<<8; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
191 y|=stream_read_char(s)<<16; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
192 y|=stream_read_char(s)<<24; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
193 y|=(uint64_t)stream_read_char(s)<<32; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
194 y|=(uint64_t)stream_read_char(s)<<40; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
195 y|=(uint64_t)stream_read_char(s)<<48; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
196 y|=(uint64_t)stream_read_char(s)<<56; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
197 return y; |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
198 } |
9a81d7b4c0b6
Added the new C based Matroska demuxer by Aurelien Jacobs.
mosu
parents:
10594
diff
changeset
|
199 |
5301 | 200 inline static unsigned int stream_read_int24(stream_t *s){ |
201 unsigned int y; | |
202 y = stream_read_char(s); | |
203 y=(y<<8)|stream_read_char(s); | |
204 y=(y<<8)|stream_read_char(s); | |
205 return y; | |
206 } | |
207 | |
2347 | 208 inline static int stream_read(stream_t *s,char* mem,int total){ |
209 int len=total; | |
578 | 210 while(len>0){ |
211 int x; | |
212 x=s->buf_len-s->buf_pos; | |
213 if(x==0){ | |
2347 | 214 if(!cache_stream_fill_buffer(s)) return total-len; // EOF |
578 | 215 x=s->buf_len-s->buf_pos; |
216 } | |
5086 | 217 if(s->buf_pos>s->buf_len) mp_msg(MSGT_DEMUX, MSGL_WARN, "stream_read: WARNING! s->buf_pos>s->buf_len\n"); |
578 | 218 if(x>len) x=len; |
219 memcpy(mem,&s->buffer[s->buf_pos],x); | |
220 s->buf_pos+=x; mem+=x; len-=x; | |
221 } | |
2347 | 222 return total; |
578 | 223 } |
224 | |
17879 | 225 inline static unsigned char* stream_read_line(stream_t *s,unsigned char* mem, int max) { |
226 int len; | |
227 unsigned char* end,*ptr = mem;; | |
228 do { | |
229 len = s->buf_len-s->buf_pos; | |
230 // try to fill the buffer | |
231 if(len <= 0 && | |
232 (!cache_stream_fill_buffer(s) || | |
233 (len = s->buf_len-s->buf_pos) <= 0)) break; | |
17880
c0fa48581ccf
Fix compilation with stupid C++ compilers that shock on valid C
albeu
parents:
17879
diff
changeset
|
234 end = (unsigned char*) memchr((void*)(s->buffer+s->buf_pos),'\n',len); |
17879 | 235 if(end) len = end - (s->buffer+s->buf_pos) + 1; |
236 if(len > 0 && max > 1) { | |
237 int l = len > max-1 ? max-1 : len; | |
238 memcpy(ptr,s->buffer+s->buf_pos,l); | |
239 max -= l; | |
240 ptr += l; | |
241 } | |
242 s->buf_pos += len; | |
243 } while(!end); | |
244 if(s->eof && ptr == mem) return NULL; | |
245 if(max > 0) ptr[0] = 0; | |
246 return mem; | |
247 } | |
248 | |
249 | |
578 | 250 inline static int stream_eof(stream_t *s){ |
251 return s->eof; | |
252 } | |
253 | |
1428
a90d889eb649
largefile patch by Stephen Davies <steve@daviesfam.org>
arpi
parents:
998
diff
changeset
|
254 inline static off_t stream_tell(stream_t *s){ |
578 | 255 return s->pos+s->buf_pos-s->buf_len; |
256 } | |
257 | |
1428
a90d889eb649
largefile patch by Stephen Davies <steve@daviesfam.org>
arpi
parents:
998
diff
changeset
|
258 inline static int stream_seek(stream_t *s,off_t pos){ |
578 | 259 |
5086 | 260 mp_dbg(MSGT_DEMUX, MSGL_DBG3, "seek to 0x%qX\n",(long long)pos); |
578 | 261 |
262 if(pos<s->pos){ | |
1428
a90d889eb649
largefile patch by Stephen Davies <steve@daviesfam.org>
arpi
parents:
998
diff
changeset
|
263 off_t x=pos-(s->pos-s->buf_len); |
578 | 264 if(x>=0){ |
265 s->buf_pos=x; | |
266 // putchar('*');fflush(stdout); | |
267 return 1; | |
268 } | |
269 } | |
270 | |
2322 | 271 return cache_stream_seek_long(s,pos); |
578 | 272 } |
273 | |
3962 | 274 inline static int stream_skip(stream_t *s,off_t len){ |
12018 | 275 if( (len<0 && (s->flags & STREAM_SEEK_BW)) || (len>2*STREAM_BUFFER_SIZE && (s->flags & STREAM_SEEK_FW)) ) { |
578 | 276 // negative or big skip! |
1491 | 277 return stream_seek(s,stream_tell(s)+len); |
578 | 278 } |
279 while(len>0){ | |
280 int x=s->buf_len-s->buf_pos; | |
281 if(x==0){ | |
2322 | 282 if(!cache_stream_fill_buffer(s)) return 0; // EOF |
578 | 283 x=s->buf_len-s->buf_pos; |
284 } | |
285 if(x>len) x=len; | |
286 //memcpy(mem,&s->buf[s->buf_pos],x); | |
287 s->buf_pos+=x; len-=x; | |
288 } | |
1491 | 289 return 1; |
578 | 290 } |
291 | |
292 void stream_reset(stream_t *s); | |
17712 | 293 int stream_control(stream_t *s, int cmd, void *arg); |
578 | 294 stream_t* new_stream(int fd,int type); |
295 void free_stream(stream_t *s); | |
2144 | 296 stream_t* new_memory_stream(unsigned char* data,int len); |
9794 | 297 stream_t* open_stream(char* filename,char** options,int* file_format); |
298 stream_t* open_stream_full(char* filename,int mode, char** options, int* file_format); | |
21655 | 299 stream_t* open_output_stream(char* filename,char** options); |
2555
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2347
diff
changeset
|
300 |
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2347
diff
changeset
|
301 extern int dvd_title; |
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2347
diff
changeset
|
302 extern int dvd_chapter; |
4291
e889d37f25b2
Add option -last-chapter for DVD playing/encoding
kmkaplan
parents:
4189
diff
changeset
|
303 extern int dvd_last_chapter; |
2555
66837325b929
config.h cleanup, few things added to steram/demuxer headers
arpi
parents:
2347
diff
changeset
|
304 extern int dvd_angle; |
998
8c83e3ff26cc
Added ifndef to prevent multiple header file inclusion.
bertrand
parents:
692
diff
changeset
|
305 |
6623 | 306 extern char * audio_stream; |
307 | |
2935 | 308 typedef struct { |
309 int id; // 0 - 31 mpeg; 128 - 159 ac3; 160 - 191 pcm | |
310 int language; | |
6651 | 311 int type; |
312 int channels; | |
3751
d9d2ee82a243
subtitle_t + audio_stream_t -> stream_language_t (cleanup)
arpi
parents:
3726
diff
changeset
|
313 } stream_language_t; |
3048 | 314 |
998
8c83e3ff26cc
Added ifndef to prevent multiple header file inclusion.
bertrand
parents:
692
diff
changeset
|
315 #endif // __STREAM_H |