1 /*qt video encoder using win32 libs
5 #define MAX_IDSIZE 0x6F
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 HINSTANCE qtime_qts
; //handle to preloaded quicktime.qts
38 static HMODULE handler
;
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
,
48 const Rect
*boundsRect
,
50 /*GDHandle*/void* aGDevice
, /*unused anyway*/
54 static OSErr (*NewHandleClear
)(Size byteCount
);
55 static OSErr (*CompressSequenceBegin
) (
63 CompressorComponent codec
,
64 CodecQ spatialQuality
,
65 CodecQ temporalQuality
,
69 ImageDescriptionHandle desc
);
71 static OSErr (*CompressSequenceFrame
) (
79 ICMCompletionProcRecordPtr asyncCompletionProc
);
81 static OSErr (*GetMaxCompressionSize
)(PixMapHandle src
,
86 CompressorComponent codec
,
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
);
95 //static int format=mmioFOURCC('S','V','Q','1');
96 static int format
=mmioFOURCC('S','V','Q','3');
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
;
107 static CompressorComponent compressor
;
108 static DecompressorComponent decompressor
;
109 static ImageDescriptionHandle desc
;
110 static ImageSequence seq
;
121 #define mux_v (vf->priv->mux)
123 //===========================================================================//
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
){
129 ComponentDescription cdesc
;
130 mux_v
->bih
->biWidth
=width
;
131 mux_v
->bih
->biHeight
=height
;
132 mux_v
->bih
->biSizeImage
=width
*height
*2;
133 mux_v
->aspect
= (float)d_width
/d_height
;
137 memset(&cdesc
,0,sizeof(cdesc
));
138 cdesc
.componentType
= (((unsigned char)'i')<<24)|
139 (((unsigned char)'m')<<16)|
140 (((unsigned char)'c')<<8)|
141 (((unsigned char)'o'));
143 cdesc
.componentSubType
=bswap_32(format
);
144 cdesc
.componentManufacturer
=0;
145 cdesc
.componentFlags
=0;
146 cdesc
.componentFlagsMask
=0;
149 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"Count = %d\n",CountComponents(&cdesc
));
150 compressor
=FindNextComponent(NULL
,&cdesc
);
152 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"Cannot find requested component\n");
155 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"Found it! ID = 0x%X\n",compressor
);
157 // cres= FindCodec (fourcc,anyCodec,&compressor,&decompressor );
158 // printf("FindCodec returned:%i compressor: 0x%X decompressor: 0x%X\n",cres&0xFFFF,compressor,decompressor);
163 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
165 return CONTROL_UNKNOWN
;
168 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
169 if(fmt
==IMGFMT_YUY2
) return VFCAP_CSP_SUPPORTED
| VFCAP_CSP_SUPPORTED_BY_HW
;
173 static int codec_inited
= 0;
175 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
){
181 OSType in_format
=kYUVSPixelFormat
;
182 int width
= mpi
->width
;
183 int height
= mpi
->height
;
184 int stride
= width
*2;
188 FrameRect
.right
=width
;
189 FrameRect
.bottom
=height
;
190 cres
= QTNewGWorldFromPtr(
199 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"NewGWorldFromPtr returned:%i\n",cres
&0xFFFF);
200 //dunno what todo about this
201 frame_prev
= malloc(stride
* height
);
202 cres
= QTNewGWorldFromPtr(
211 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"height:%i width:%i stride:%i\n",height
,width
,stride
);
212 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"NewGWorldFromPtr returned:%i\n",cres
&0xFFFF);
213 cres
= GetMaxCompressionSize (
214 GetGWorldPixMap(frame_GWorld_in
),
221 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"GetMaxCompressionSize returned:%i : MaxSize:%i\n",cres
&0xFFFF,framesizemax
);
222 frame_comp
=malloc(framesizemax
);
224 desc
= (ImageDescriptionHandle
)NewHandleClear(MAX_IDSIZE
); //memory where the desc will be stored
225 (*desc
)->idSize
=MAX_IDSIZE
;
227 cres
= CompressSequenceBegin (
229 GetGWorldPixMap( frame_GWorld_in
),
230 GetGWorldPixMap( frame_GWorld_prev
),
234 bswap_32(format
), // fourcc
235 compressor
, // codec component
236 codecNormalQuality
, //codecNormalQuality,
237 codecMaxQuality
, //codecNormalQuality,
238 10*30, // keyframe rate
242 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"CompressSequenceBegin returned:%i\n",cres
&0xFFFF);
243 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"Sequence ID:%i\n",seq
);
245 dump_ImageDescription(*desc
);
248 cres
= CompressSequenceFrame (
250 GetGWorldPixMap(frame_GWorld_in
),
253 (char*)mux_v
->buffer
,
258 if(cres
&0xFFFF)mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"CompressSequenceFrame returned:%i\n",cres
&0xFFFF);
260 printf("Size %i->%i \n",stride
*height
,compressedsize
);
261 printf("Ratio: %i:1\n",(stride
*height
)/compressedsize
);
263 muxer_write_chunk(mux_v
, compressedsize
, similarity
?0:0x10);
265 if(((*desc
)->idSize
)>MAX_IDSIZE
){
266 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc
)->idSize
));
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
);
276 //===========================================================================//
278 static int vf_open(vf_instance_t
*vf
, char* args
){
281 vf
->default_caps
=VFCAP_CONSTANT
;
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
));
287 vf
->priv
->mux
=(muxer_stream_t
*)args
;
289 mux_v
->bih
=calloc(1, sizeof(BITMAPINFOHEADER
)+MAX_IDSIZE
);
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;
301 //preload quicktime.qts to avoid the problems caused by the hardcoded path inside the dll
302 qtime_qts
= LoadLibraryA("QuickTime.qts");
304 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"unable to load QuickTime.qts\n" );
308 handler
= LoadLibraryA("qtmlClient.dll");
310 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"unable to load qtmlClient.dll\n");
313 InitializeQTML
= (OSErr (*)(long))GetProcAddress(handler
, "InitializeQTML");
314 GetGWorldPixMap
= (PixMapHandle (*)(GWorldPtr
))GetProcAddress(handler
, "GetGWorldPixMap");
315 QTNewGWorldFromPtr
= (OSErr(*)(GWorldPtr
*,OSType
,const Rect
*,CTabHandle
,void*,GWorldFlags
,void *,long))GetProcAddress(handler
, "QTNewGWorldFromPtr");
316 NewHandleClear
= (OSErr(*)(Size
))GetProcAddress(handler
, "NewHandleClear");
317 FindCodec
= (OSErr (*)(CodecType
,CodecComponent
,CompressorComponent
*,DecompressorComponent
*))GetProcAddress(handler
,"FindCodec");
318 CompressSequenceBegin
= (OSErr(*)(ImageSequence
*,PixMapHandle
,PixMapHandle
,const Rect
*,const Rect
*,short,CodecType
,CompressorComponent
,CodecQ
,CodecQ
,long,CTabHandle
,CodecFlags
,ImageDescriptionHandle
))GetProcAddress(handler
,"CompressSequenceBegin");
319 CompressSequenceFrame
= (OSErr(*)(ImageSequence
,PixMapHandle
,const Rect
*,CodecFlags
,Ptr
,long *,UInt8
*,ICMCompletionProcRecordPtr
))GetProcAddress(handler
,"CompressSequenceFrame");
320 GetMaxCompressionSize
= (OSErr(*)(PixMapHandle
,const Rect
*,short,CodecQ
,CodecType
,CompressorComponent
,long *))GetProcAddress(handler
,"GetMaxCompressionSize");
321 CDSequenceEnd
= (OSErr (*)(ImageSequence
))GetProcAddress(handler
,"CDSequenceEnd");
322 FindNextComponent
= (Component (*)(Component
,ComponentDescription
*))GetProcAddress(handler
, "FindNextComponent");
323 CountComponents
= (long (*)(ComponentDescription
*))GetProcAddress(handler
, "CountComponents");
324 GetComponentInfo
= (OSErr (*)(Component
,ComponentDescription
*,Handle
,Handle
,Handle
))GetProcAddress(handler
, "GetComponentInfo");
325 if(!InitializeQTML
||!CompressSequenceBegin
){
326 mp_msg(MSGT_MENCODER
,MSGL_ERR
,"invalid qt DLL!\n");
329 //printf("%i,%i,%i\n",mmioFOURCC('S','V','Q','1'),'SVQ1',bswap_32(mmioFOURCC('S','V','Q','1')));
330 cres
=InitializeQTML(6+16);
331 mp_msg(MSGT_MENCODER
,MSGL_DBG2
,"InitializeQTML returned %i\n",cres
);
335 vf_info_t ve_info_qtvideo
= {
336 "Quicktime video encoder using win32 DLLs",
339 "for internal use by mencoder",
343 //===========================================================================//