1 /*qt video encoder using win32 libs
5 #define MAX_IDSIZE 0x6F
11 #include "../config.h"
12 #include "../mp_msg.h"
16 #include "ldt_keeper.h"
20 #include "../loader/qtx/qtxsdk/components.h"
21 #include "wine/windef.h"
23 #include "codec-cfg.h"
30 #include "img_format.h"
34 HMODULE WINAPI
LoadLibraryA(LPCSTR
);
35 FARPROC WINAPI
GetProcAddress(HMODULE
,LPCSTR
);
36 int WINAPI
FreeLibrary(HMODULE
);
37 static HMODULE handler
;
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
,
47 const Rect
*boundsRect
,
49 /*GDHandle*/void* aGDevice
, /*unused anyway*/
53 static OSErr (*NewHandleClear
)(Size byteCount
);
54 static OSErr (*CompressSequenceBegin
) (
62 CompressorComponent codec
,
63 CodecQ spatialQuality
,
64 CodecQ temporalQuality
,
68 ImageDescriptionHandle desc
);
70 static OSErr (*CompressSequenceFrame
) (
78 ICMCompletionProcRecordPtr asyncCompletionProc
);
80 static OSErr (*GetMaxCompressionSize
)(PixMapHandle src
,
85 CompressorComponent codec
,
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
);
94 //static int format=mmioFOURCC('S','V','Q','1');
95 static int format
=mmioFOURCC('S','V','Q','3');
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
;
106 static CompressorComponent compressor
;
107 static DecompressorComponent decompressor
;
108 static ImageDescriptionHandle desc
;
109 static ImageSequence seq
;
120 #define mux_v (vf->priv->mux)
122 //===========================================================================//
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
){
128 ComponentDescription cdesc
;
129 mux_v
->bih
->biWidth
=width
;
130 mux_v
->bih
->biHeight
=height
;
131 mux_v
->bih
->biSizeImage
=width
*height
*2;
132 mux_v
->aspect
= (float)d_width
/d_height
;
136 memset(&desc
,0,sizeof(cdesc
));
137 cdesc
.componentType
= (((unsigned char)'i')<<24)|
138 (((unsigned char)'m')<<16)|
139 (((unsigned char)'c')<<8)|
140 (((unsigned char)'o'));
142 cdesc
.componentSubType
=bswap_32(format
);
143 cdesc
.componentManufacturer
=0;
144 cdesc
.componentFlags
=0;
145 cdesc
.componentFlagsMask
=0;
148 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"Count = %d\n",CountComponents(&cdesc
));
149 compressor
=FindNextComponent(NULL
,&cdesc
);
151 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"Cannot find requested component\n");
154 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"Found it! ID = 0x%X\n",compressor
);
156 // cres= FindCodec (fourcc,anyCodec,&compressor,&decompressor );
157 // printf("FindCodec returned:%i compressor: 0x%X decompressor: 0x%X\n",cres&0xFFFF,compressor,decompressor);
162 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
164 return CONTROL_UNKNOWN
;
167 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
168 if(fmt
==IMGFMT_YUY2
) return 3;
172 static int codec_inited
= 0;
174 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
180 OSType in_format
=kYUVSPixelFormat
;
181 int width
= mpi
->width
;
182 int height
= mpi
->height
;
183 int stride
= width
*2;
187 FrameRect
.right
=width
;
188 FrameRect
.bottom
=height
;
189 cres
= QTNewGWorldFromPtr(
198 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"NewGWorldFromPtr returned:%i\n",cres
&0xFFFF);
199 //dunno what todo about this
200 frame_prev
= malloc(stride
* height
);
201 cres
= QTNewGWorldFromPtr(
210 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"height:%i width:%i stride:%i\n",height
,width
,stride
);
211 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"NewGWorldFromPtr returned:%i\n",cres
&0xFFFF);
212 cres
= GetMaxCompressionSize (
213 GetGWorldPixMap(frame_GWorld_in
),
220 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"GetMaxCompressionSize returned:%i : MaxSize:%i\n",cres
&0xFFFF,framesizemax
);
221 frame_comp
=malloc(framesizemax
);
223 desc
= (ImageDescriptionHandle
)NewHandleClear(MAX_IDSIZE
); //memory where the desc will be stored
224 (*desc
)->idSize
=MAX_IDSIZE
;
226 cres
= CompressSequenceBegin (
228 GetGWorldPixMap( frame_GWorld_in
),
229 GetGWorldPixMap( frame_GWorld_prev
),
233 bswap_32(format
), // fourcc
234 compressor
, // codec component
235 codecNormalQuality
, //codecNormalQuality,
236 codecMaxQuality
, //codecNormalQuality,
237 10*30, // keyframe rate
241 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"CompressSequenceBegin returned:%i\n",cres
&0xFFFF);
242 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"Sequence ID:%i\n",seq
);
244 dump_ImageDescription(*desc
);
247 cres
= CompressSequenceFrame (
249 GetGWorldPixMap(frame_GWorld_in
),
252 (char*)mux_v
->buffer
,
257 if(cres
&0xFFFF)mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"CompressSequenceFrame returned:%i\n",cres
&0xFFFF);
259 printf("Size %i->%i \n",stride
*height
,compressedsize
);
260 printf("Ratio: %i:1\n",(stride
*height
)/compressedsize
);
262 muxer_write_chunk(mux_v
, compressedsize
, similarity
?0:0x10);
264 if(((*desc
)->idSize
)>MAX_IDSIZE
){
265 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc
)->idSize
));
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
);
275 //===========================================================================//
277 static int vf_open(vf_instance_t
*vf
, char* args
){
281 vf
->query_format
=query_format
;
282 vf
->put_image
=put_image
;
283 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
284 memset(vf
->priv
,0,sizeof(struct vf_priv_s
));
285 vf
->priv
->mux
=(muxer_stream_t
*)args
;
287 mux_v
->bih
=malloc(sizeof(BITMAPINFOHEADER
)+MAX_IDSIZE
);
288 mux_v
->bih
->biSize
=sizeof(BITMAPINFOHEADER
)+MAX_IDSIZE
;
289 mux_v
->bih
->biWidth
=0;
290 mux_v
->bih
->biHeight
=0;
291 mux_v
->bih
->biCompression
=format
;
292 mux_v
->bih
->biPlanes
=1;
293 mux_v
->bih
->biBitCount
=24;
299 handler
= LoadLibraryA("qtmlClient.dll");
301 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"unable to load qtmlClient.dll\n");
304 InitializeQTML
= (OSErr (*)(long))GetProcAddress(handler
, "InitializeQTML");
305 GetGWorldPixMap
= (PixMapHandle (*)(GWorldPtr
))GetProcAddress(handler
, "GetGWorldPixMap");
306 QTNewGWorldFromPtr
= (OSErr(*)(GWorldPtr
*,OSType
,const Rect
*,CTabHandle
,void*,GWorldFlags
,void *,long))GetProcAddress(handler
, "QTNewGWorldFromPtr");
307 NewHandleClear
= (OSErr(*)(Size
))GetProcAddress(handler
, "NewHandleClear");
308 FindCodec
= (OSErr (*)(CodecType
,CodecComponent
,CompressorComponent
*,DecompressorComponent
*))GetProcAddress(handler
,"FindCodec");
309 CompressSequenceBegin
= (OSErr(*)(ImageSequence
*,PixMapHandle
,PixMapHandle
,const Rect
*,const Rect
*,short,CodecType
,CompressorComponent
,CodecQ
,CodecQ
,long,CTabHandle
,CodecFlags
,ImageDescriptionHandle
))GetProcAddress(handler
,"CompressSequenceBegin");
310 CompressSequenceFrame
= (OSErr(*)(ImageSequence
,PixMapHandle
,const Rect
*,CodecFlags
,Ptr
,long *,UInt8
*,ICMCompletionProcRecordPtr
))GetProcAddress(handler
,"CompressSequenceFrame");
311 GetMaxCompressionSize
= (OSErr(*)(PixMapHandle
,const Rect
*,short,CodecQ
,CodecType
,CompressorComponent
,long *))GetProcAddress(handler
,"GetMaxCompressionSize");
312 CDSequenceEnd
= (OSErr (*)(ImageSequence
))GetProcAddress(handler
,"CDSequenceEnd");
313 FindNextComponent
= (Component (*)(Component
,ComponentDescription
*))GetProcAddress(handler
, "FindNextComponent");
314 CountComponents
= (long (*)(ComponentDescription
*))GetProcAddress(handler
, "CountComponents");
315 GetComponentInfo
= (OSErr (*)(Component
,ComponentDescription
*,Handle
,Handle
,Handle
))GetProcAddress(handler
, "GetComponentInfo");
316 if(!InitializeQTML
||!CompressSequenceBegin
){
317 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"invalid qt DLL!\n");
320 //printf("%i,%i,%i\n",mmioFOURCC('S','V','Q','1'),'SVQ1',bswap_32(mmioFOURCC('S','V','Q','1')));
321 cres
=InitializeQTML(6+16);
322 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"InitializeQTML returned %i\n",cres
);
326 vf_info_t ve_info_qtvideo
= {
327 "Quicktime video encoder using win32 DLLs",
330 "for internal use by mencoder",
334 //===========================================================================//