Mercurial > mplayer.hg
annotate libmpcodecs/ve_qtvideo.c @ 15597:aa7224b06f8c
geometry support for gl2 under win, default window pos centered for gl, gl2
author | gpoirier |
---|---|
date | Mon, 30 May 2005 11:49:41 +0000 |
parents | d42539110db9 |
children | 6ff3379a0862 |
rev | line source |
---|---|
8471 | 1 /*qt video encoder using win32 libs |
2 released under gnu gpl | |
3 (C)Sascha Sommer */ | |
4 | |
5 #define MAX_IDSIZE 0x6F | |
6 | |
7 #include <stdio.h> | |
8 #include <stdlib.h> | |
9 #include <string.h> | |
10 | |
11 #include "../config.h" | |
12 #include "../mp_msg.h" | |
13 #include "../bswap.h" | |
14 | |
9435 | 15 #ifdef WIN32_LOADER |
9217
420e2b2f8e5a
compiler warning fixes patch by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
9014
diff
changeset
|
16 #include "ldt_keeper.h" |
420e2b2f8e5a
compiler warning fixes patch by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
9014
diff
changeset
|
17 #endif |
420e2b2f8e5a
compiler warning fixes patch by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
9014
diff
changeset
|
18 |
8471 | 19 #ifdef USE_QTX_CODECS |
20 #include "../loader/qtx/qtxsdk/components.h" | |
21 #include "wine/windef.h" | |
22 | |
23 #include "codec-cfg.h" | |
24 #include "stream.h" | |
25 #include "demuxer.h" | |
26 #include "stheader.h" | |
27 | |
8585 | 28 #include "muxer.h" |
8471 | 29 |
30 #include "img_format.h" | |
31 #include "mp_image.h" | |
32 #include "vf.h" | |
33 | |
34 HMODULE WINAPI LoadLibraryA(LPCSTR); | |
35 FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR); | |
36 int WINAPI FreeLibrary(HMODULE); | |
14528
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
37 static HINSTANCE qtime_qts; //handle to preloaded quicktime.qts |
8471 | 38 static HMODULE handler; |
39 | |
40 static OSErr (*FindCodec)(CodecType cType, | |
41 CodecComponent specCodec, | |
42 CompressorComponent * compressor, | |
43 DecompressorComponent * decompressor); | |
44 static OSErr (*InitializeQTML)(long flags); | |
45 static PixMapHandle (*GetGWorldPixMap)(GWorldPtr offscreenGWorld); | |
46 static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw, | |
47 OSType pixelFormat, | |
48 const Rect *boundsRect, | |
49 CTabHandle cTable, | |
50 /*GDHandle*/void* aGDevice, /*unused anyway*/ | |
51 GWorldFlags flags, | |
52 void *baseAddr, | |
53 long rowBytes); | |
54 static OSErr (*NewHandleClear)(Size byteCount); | |
55 static OSErr (*CompressSequenceBegin) ( | |
56 ImageSequence *seqID, | |
57 PixMapHandle src, | |
58 PixMapHandle prev, | |
59 const Rect *srcRect, | |
60 const Rect *prevRect, | |
61 short colorDepth, | |
62 CodecType cType, | |
63 CompressorComponent codec, | |
64 CodecQ spatialQuality, | |
65 CodecQ temporalQuality, | |
66 long keyFrameRate, | |
67 CTabHandle ctable, | |
68 CodecFlags flags, | |
69 ImageDescriptionHandle desc ); | |
70 | |
71 static OSErr (*CompressSequenceFrame) ( | |
72 ImageSequence seqID, | |
73 PixMapHandle src, | |
74 const Rect *srcRect, | |
75 CodecFlags flags, | |
76 Ptr data, | |
77 long *dataSize, | |
78 UInt8 *similarity, | |
79 ICMCompletionProcRecordPtr asyncCompletionProc ); | |
80 | |
81 static OSErr (*GetMaxCompressionSize)(PixMapHandle src, | |
82 const Rect *srcRect, | |
83 short colorDepth, | |
84 CodecQ quality, | |
85 CodecType cType, | |
86 CompressorComponent codec, | |
87 long *size ); | |
88 static OSErr (*CDSequenceEnd)( ImageSequence seqID ); | |
89 static Component (*FindNextComponent)(Component prev,ComponentDescription* desc); | |
90 static long (*CountComponents)(ComponentDescription* desc); | |
91 static OSErr (*GetComponentInfo)(Component prev,ComponentDescription* desc,Handle h1,Handle h2,Handle h3); | |
92 | |
93 | |
94 | |
95 //static int format=mmioFOURCC('S','V','Q','1'); | |
96 static int format=mmioFOURCC('S','V','Q','3'); | |
97 | |
98 | |
99 | |
100 //static void *frame_in; //input frame | |
101 static void *frame_prev; //previous frame | |
102 static void *frame_comp; //compressed frame | |
103 static GWorldPtr frame_GWorld_in = NULL;//a GWorld is some kind of description for a drawing environment | |
104 static GWorldPtr frame_GWorld_prev = NULL; | |
105 static Rect FrameRect; | |
106 | |
107 static CompressorComponent compressor; | |
108 static DecompressorComponent decompressor; | |
109 static ImageDescriptionHandle desc; | |
110 static ImageSequence seq; | |
111 | |
112 | |
113 | |
114 | |
115 | |
116 struct vf_priv_s { | |
8585 | 117 muxer_stream_t* mux; |
8471 | 118 //dv_encoder_t* enc; |
119 | |
120 }; | |
121 #define mux_v (vf->priv->mux) | |
122 | |
123 //===========================================================================// | |
124 | |
125 static int config(struct vf_instance_s* vf, | |
126 int width, int height, int d_width, int d_height, | |
127 unsigned int flags, unsigned int outfmt){ | |
128 OSErr cres; | |
129 ComponentDescription cdesc; | |
130 mux_v->bih->biWidth=width; | |
131 mux_v->bih->biHeight=height; | |
132 mux_v->bih->biSizeImage=width*height*2; | |
12061 | 133 mux_v->aspect = (float)d_width/d_height; |
8471 | 134 |
135 | |
136 | |
15274
d42539110db9
typo, memset 0 was done on desc instead of cdesc, see bug #288
reimar
parents:
15212
diff
changeset
|
137 memset(&cdesc,0,sizeof(cdesc)); |
8471 | 138 cdesc.componentType= (((unsigned char)'i')<<24)| |
139 (((unsigned char)'m')<<16)| | |
140 (((unsigned char)'c')<<8)| | |
141 (((unsigned char)'o')); | |
142 | |
143 cdesc.componentSubType=bswap_32(format); | |
144 cdesc.componentManufacturer=0; | |
145 cdesc.componentFlags=0; | |
146 cdesc.componentFlagsMask=0; | |
147 | |
148 | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
149 mp_msg(MSGT_MENCODER,MSGL_DBG2,"Count = %d\n",CountComponents(&cdesc)); |
8471 | 150 compressor=FindNextComponent(NULL,&cdesc); |
151 if(!compressor){ | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
152 mp_msg(MSGT_MENCODER,MSGL_ERR,"Cannot find requested component\n"); |
8471 | 153 return(0); |
154 } | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
155 mp_msg(MSGT_MENCODER,MSGL_DBG2,"Found it! ID = 0x%X\n",compressor); |
8471 | 156 |
157 // cres= FindCodec (fourcc,anyCodec,&compressor,&decompressor ); | |
158 // printf("FindCodec returned:%i compressor: 0x%X decompressor: 0x%X\n",cres&0xFFFF,compressor,decompressor); | |
159 | |
160 return 1; | |
161 } | |
162 | |
163 static int control(struct vf_instance_s* vf, int request, void* data){ | |
164 | |
165 return CONTROL_UNKNOWN; | |
166 } | |
167 | |
168 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
15212
05aa13cdf92f
replace VO and VF numeric flags with #defined identifiers
henry
parents:
14878
diff
changeset
|
169 if(fmt==IMGFMT_YUY2) return VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW; |
8471 | 170 return 0; |
171 } | |
172 | |
173 static int codec_inited = 0; | |
174 | |
175 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){ | |
176 | |
177 OSErr cres; | |
178 long framesizemax; | |
8511 | 179 UInt8 similarity=0; |
8471 | 180 long compressedsize; |
13188 | 181 OSType in_format=kYUVSPixelFormat; |
8471 | 182 int width = mpi->width; |
183 int height = mpi->height; | |
184 int stride = width*2; | |
185 if(!codec_inited){ | |
186 FrameRect.top=0; | |
187 FrameRect.left=0; | |
188 FrameRect.right=width; | |
189 FrameRect.bottom=height; | |
190 cres = QTNewGWorldFromPtr( | |
191 &frame_GWorld_in, | |
192 in_format, | |
193 &FrameRect, | |
194 0, | |
195 0, | |
196 0, | |
197 mpi->planes[0], | |
198 stride); | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
199 mp_msg(MSGT_MENCODER,MSGL_DBG2,"NewGWorldFromPtr returned:%i\n",cres&0xFFFF); |
8471 | 200 //dunno what todo about this |
201 frame_prev = malloc(stride * height); | |
202 cres = QTNewGWorldFromPtr( | |
203 &frame_GWorld_prev, | |
204 in_format, | |
205 &FrameRect, | |
206 0, | |
207 0, | |
208 0, | |
209 frame_prev, | |
210 stride); | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
211 mp_msg(MSGT_MENCODER,MSGL_DBG2,"height:%i width:%i stride:%i\n",height,width,stride); |
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
212 mp_msg(MSGT_MENCODER,MSGL_DBG2,"NewGWorldFromPtr returned:%i\n",cres&0xFFFF); |
8471 | 213 cres= GetMaxCompressionSize ( |
214 GetGWorldPixMap(frame_GWorld_in), | |
215 &FrameRect, | |
216 24, | |
217 codecNormalQuality, | |
218 bswap_32(format), | |
219 compressor, | |
220 &framesizemax ); | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
221 mp_msg(MSGT_MENCODER,MSGL_DBG2,"GetMaxCompressionSize returned:%i : MaxSize:%i\n",cres&0xFFFF,framesizemax); |
8471 | 222 frame_comp=malloc(framesizemax); |
8511 | 223 |
8471 | 224 desc = (ImageDescriptionHandle)NewHandleClear(MAX_IDSIZE); //memory where the desc will be stored |
225 (*desc)->idSize=MAX_IDSIZE; | |
226 | |
227 cres= CompressSequenceBegin ( | |
228 &seq, | |
229 GetGWorldPixMap( frame_GWorld_in), | |
230 GetGWorldPixMap( frame_GWorld_prev), | |
231 &FrameRect, | |
232 &FrameRect, | |
233 24, // color depth | |
234 bswap_32(format), // fourcc | |
235 compressor, // codec component | |
236 codecNormalQuality, //codecNormalQuality, | |
237 codecMaxQuality, //codecNormalQuality, | |
8511 | 238 10*30, // keyframe rate |
8471 | 239 0, |
240 0, | |
241 desc); | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
242 mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceBegin returned:%i\n",cres&0xFFFF); |
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
243 mp_msg(MSGT_MENCODER,MSGL_DBG2,"Sequence ID:%i\n",seq); |
8471 | 244 |
245 dump_ImageDescription(*desc); | |
246 codec_inited++; | |
247 } | |
248 cres = CompressSequenceFrame ( | |
249 seq, | |
250 GetGWorldPixMap(frame_GWorld_in), | |
251 &FrameRect, | |
252 0, | |
253 (char*)mux_v->buffer, | |
254 &compressedsize, | |
255 &similarity, | |
256 0); | |
257 | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
258 if(cres&0xFFFF)mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceFrame returned:%i\n",cres&0xFFFF); |
8511 | 259 #if 0 |
8471 | 260 printf("Size %i->%i \n",stride*height,compressedsize); |
261 printf("Ratio: %i:1\n",(stride*height)/compressedsize); | |
262 #endif | |
9014
c671e9adbe22
Cleanup of the muxer API, func parameters muxer & muxer_f eliminated.
arpi
parents:
8733
diff
changeset
|
263 muxer_write_chunk(mux_v, compressedsize , similarity?0:0x10); |
8471 | 264 |
265 if(((*desc)->idSize)>MAX_IDSIZE){ | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
266 mp_msg(MSGT_MENCODER,MSGL_ERR,"FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc)->idSize)); |
8471 | 267 } else { |
268 // according to QT docs, imagedescription may be changed while encoding | |
269 // a frame (even its size may (and does!) change!) | |
270 memcpy(mux_v->bih+1,*desc,(*desc)->idSize); | |
271 } | |
272 | |
273 return 1; | |
274 } | |
275 | |
276 //===========================================================================// | |
277 | |
278 static int vf_open(vf_instance_t *vf, char* args){ | |
279 OSErr cres = 1; | |
280 vf->config=config; | |
14878 | 281 vf->default_caps=VFCAP_CONSTANT; |
8471 | 282 vf->control=control; |
283 vf->query_format=query_format; | |
284 vf->put_image=put_image; | |
285 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
286 memset(vf->priv,0,sizeof(struct vf_priv_s)); | |
8585 | 287 vf->priv->mux=(muxer_stream_t*)args; |
8471 | 288 |
14549
acf3241be19b
Initialized BITMAPINFOHEADER to 0 to avoid problems, esp. windows has problems
reimar
parents:
14528
diff
changeset
|
289 mux_v->bih=calloc(1, sizeof(BITMAPINFOHEADER)+MAX_IDSIZE); |
8471 | 290 mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+MAX_IDSIZE; |
291 mux_v->bih->biWidth=0; | |
292 mux_v->bih->biHeight=0; | |
293 mux_v->bih->biCompression=format; | |
294 mux_v->bih->biPlanes=1; | |
295 mux_v->bih->biBitCount=24; | |
296 | |
297 | |
9435 | 298 #ifdef WIN32_LOADER |
8471 | 299 Setup_LDT_Keeper(); |
9435 | 300 #endif |
14528
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
301 //preload quicktime.qts to avoid the problems caused by the hardcoded path inside the dll |
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
302 qtime_qts = LoadLibraryA("QuickTime.qts"); |
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
303 if(!qtime_qts){ |
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
304 mp_msg(MSGT_MENCODER,MSGL_ERR,"unable to load QuickTime.qts\n" ); |
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
305 return 0; |
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
306 } |
860f06087aac
preload quicktime.qts, this allows us to ignore the hardcoded path inside the dlls so that quicktime.qts doesn't need to be in the windows system dir, patch by Gianluigi Tiesi <mplayer at netfarm.it>, comments by myself
faust3
parents:
13188
diff
changeset
|
307 |
8471 | 308 handler = LoadLibraryA("qtmlClient.dll"); |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
309 if(!handler){ |
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
310 mp_msg(MSGT_MENCODER,MSGL_ERR,"unable to load qtmlClient.dll\n"); |
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
311 return 0; |
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
312 } |
8733
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
313 InitializeQTML = (OSErr (*)(long))GetProcAddress(handler, "InitializeQTML"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
314 GetGWorldPixMap = (PixMapHandle (*)(GWorldPtr))GetProcAddress(handler, "GetGWorldPixMap"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
315 QTNewGWorldFromPtr = (OSErr(*)(GWorldPtr *,OSType,const Rect *,CTabHandle,void*,GWorldFlags,void *,long))GetProcAddress(handler, "QTNewGWorldFromPtr"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
316 NewHandleClear = (OSErr(*)(Size))GetProcAddress(handler, "NewHandleClear"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
317 FindCodec = (OSErr (*)(CodecType,CodecComponent,CompressorComponent *,DecompressorComponent *))GetProcAddress(handler,"FindCodec"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
318 CompressSequenceBegin = (OSErr(*)(ImageSequence *,PixMapHandle,PixMapHandle,const Rect *,const Rect *,short,CodecType,CompressorComponent,CodecQ,CodecQ,long,CTabHandle,CodecFlags,ImageDescriptionHandle))GetProcAddress(handler,"CompressSequenceBegin"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
319 CompressSequenceFrame = (OSErr(*)(ImageSequence,PixMapHandle,const Rect *,CodecFlags,Ptr,long *,UInt8 *,ICMCompletionProcRecordPtr))GetProcAddress(handler,"CompressSequenceFrame"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
320 GetMaxCompressionSize = (OSErr(*)(PixMapHandle,const Rect *,short,CodecQ,CodecType,CompressorComponent,long *))GetProcAddress(handler,"GetMaxCompressionSize"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
321 CDSequenceEnd = (OSErr (*)(ImageSequence))GetProcAddress(handler,"CDSequenceEnd"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
322 FindNextComponent = (Component (*)(Component,ComponentDescription*))GetProcAddress(handler, "FindNextComponent"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
323 CountComponents = (long (*)(ComponentDescription*))GetProcAddress(handler, "CountComponents"); |
478561617705
compiler warning fixes by Dominik Mierzejewski <dominik@rangers.eu.org>
arpi
parents:
8585
diff
changeset
|
324 GetComponentInfo = (OSErr (*)(Component,ComponentDescription*,Handle,Handle,Handle))GetProcAddress(handler, "GetComponentInfo"); |
8471 | 325 if(!InitializeQTML ||!CompressSequenceBegin){ |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
326 mp_msg(MSGT_MENCODER,MSGL_ERR,"invalid qt DLL!\n"); |
8471 | 327 return 0; |
328 } | |
329 //printf("%i,%i,%i\n",mmioFOURCC('S','V','Q','1'),'SVQ1',bswap_32(mmioFOURCC('S','V','Q','1'))); | |
330 cres=InitializeQTML(6+16); | |
12195
96b366ed15ad
printf -> mp_msg; print error msg when qtmlClient.dll is missing
faust3
parents:
12061
diff
changeset
|
331 mp_msg(MSGT_MENCODER,MSGL_DBG2,"InitializeQTML returned %i\n",cres); |
8471 | 332 return 1; |
333 } | |
334 | |
335 vf_info_t ve_info_qtvideo = { | |
336 "Quicktime video encoder using win32 DLLs", | |
337 "qtvideo", | |
338 "Sascha Sommer", | |
339 "for internal use by mencoder", | |
340 vf_open | |
341 }; | |
342 | |
343 //===========================================================================// | |
344 #endif |