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