disable all unknown formats in the windows aos
[mplayer/greg.git] / libmpcodecs / ve_qtvideo.c
blobbe10d86942c600babf8231055641023758129b8d
1 /*qt video encoder using win32 libs
2 released under gnu gpl
3 (C)Sascha Sommer */
5 #define MAX_IDSIZE 0x6F
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
11 #include "../config.h"
12 #include "../mp_msg.h"
13 #include "../bswap.h"
15 #ifdef WIN32_LOADER
16 #include "ldt_keeper.h"
17 #endif
19 #ifdef USE_QTX_CODECS
20 #include "../loader/qtx/qtxsdk/components.h"
21 #include "wine/windef.h"
23 #include "codec-cfg.h"
24 #include "stream.h"
25 #include "demuxer.h"
26 #include "stheader.h"
28 #include "muxer.h"
30 #include "img_format.h"
31 #include "mp_image.h"
32 #include "vf.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,
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 );
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 );
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);
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;
115 struct vf_priv_s {
116 muxer_stream_t* mux;
117 //dv_encoder_t* enc;
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){
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;
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);
150 if(!compressor){
151 mp_msg(MSGT_MENCODER,MSGL_ERR,"Cannot find requested component\n");
152 return(0);
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);
159 return 1;
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;
169 return 0;
172 static int codec_inited = 0;
174 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
176 OSErr cres;
177 long framesizemax;
178 UInt8 similarity=0;
179 long compressedsize;
180 OSType in_format=kYUVSPixelFormat;
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,
196 mpi->planes[0],
197 stride);
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(
202 &frame_GWorld_prev,
203 in_format,
204 &FrameRect,
208 frame_prev,
209 stride);
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),
214 &FrameRect,
216 codecNormalQuality,
217 bswap_32(format),
218 compressor,
219 &framesizemax );
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 (
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,
237 10*30, // keyframe rate
240 desc);
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);
245 codec_inited++;
247 cres = CompressSequenceFrame (
248 seq,
249 GetGWorldPixMap(frame_GWorld_in),
250 &FrameRect,
252 (char*)mux_v->buffer,
253 &compressedsize,
254 &similarity,
257 if(cres&0xFFFF)mp_msg(MSGT_MENCODER,MSGL_DBG2,"CompressSequenceFrame returned:%i\n",cres&0xFFFF);
258 #if 0
259 printf("Size %i->%i \n",stride*height,compressedsize);
260 printf("Ratio: %i:1\n",(stride*height)/compressedsize);
261 #endif
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));
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);
272 return 1;
275 //===========================================================================//
277 static int vf_open(vf_instance_t *vf, char* args){
278 OSErr cres = 1;
279 vf->config=config;
280 vf->control=control;
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;
296 #ifdef WIN32_LOADER
297 Setup_LDT_Keeper();
298 #endif
299 handler = LoadLibraryA("qtmlClient.dll");
300 if(!handler){
301 mp_msg(MSGT_MENCODER,MSGL_ERR,"unable to load qtmlClient.dll\n");
302 return 0;
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");
318 return 0;
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);
323 return 1;
326 vf_info_t ve_info_qtvideo = {
327 "Quicktime video encoder using win32 DLLs",
328 "qtvideo",
329 "Sascha Sommer",
330 "for internal use by mencoder",
331 vf_open
334 //===========================================================================//
335 #endif