comparison libmpcodecs/ve_qtvideo.c @ 8471:0b7839c27be9

Sorenson 1/3 encoding just for fun :) ve_qtvideo code by Sascha Sommer SVQ3 support hack by /me
author arpi
date Mon, 16 Dec 2002 01:49:39 +0000
parents
children 2b955a07fdcf
comparison
equal deleted inserted replaced
8470:08d7e1718dd0 8471:0b7839c27be9
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
15 #ifdef USE_QTX_CODECS
16 #include "../loader/qtx/qtxsdk/components.h"
17 #include "wine/windef.h"
18
19 #include "codec-cfg.h"
20 #include "stream.h"
21 #include "demuxer.h"
22 #include "stheader.h"
23
24 #include "aviwrite.h"
25
26 #include "img_format.h"
27 #include "mp_image.h"
28 #include "vf.h"
29
30 HMODULE WINAPI LoadLibraryA(LPCSTR);
31 FARPROC WINAPI GetProcAddress(HMODULE,LPCSTR);
32 int WINAPI FreeLibrary(HMODULE);
33 static HMODULE handler;
34
35 static OSErr (*FindCodec)(CodecType cType,
36 CodecComponent specCodec,
37 CompressorComponent * compressor,
38 DecompressorComponent * decompressor);
39 static OSErr (*InitializeQTML)(long flags);
40 static PixMapHandle (*GetGWorldPixMap)(GWorldPtr offscreenGWorld);
41 static OSErr (*QTNewGWorldFromPtr)(GWorldPtr *gw,
42 OSType pixelFormat,
43 const Rect *boundsRect,
44 CTabHandle cTable,
45 /*GDHandle*/void* aGDevice, /*unused anyway*/
46 GWorldFlags flags,
47 void *baseAddr,
48 long rowBytes);
49 static OSErr (*NewHandleClear)(Size byteCount);
50 static OSErr (*CompressSequenceBegin) (
51 ImageSequence *seqID,
52 PixMapHandle src,
53 PixMapHandle prev,
54 const Rect *srcRect,
55 const Rect *prevRect,
56 short colorDepth,
57 CodecType cType,
58 CompressorComponent codec,
59 CodecQ spatialQuality,
60 CodecQ temporalQuality,
61 long keyFrameRate,
62 CTabHandle ctable,
63 CodecFlags flags,
64 ImageDescriptionHandle desc );
65
66 static OSErr (*CompressSequenceFrame) (
67 ImageSequence seqID,
68 PixMapHandle src,
69 const Rect *srcRect,
70 CodecFlags flags,
71 Ptr data,
72 long *dataSize,
73 UInt8 *similarity,
74 ICMCompletionProcRecordPtr asyncCompletionProc );
75
76 static OSErr (*GetMaxCompressionSize)(PixMapHandle src,
77 const Rect *srcRect,
78 short colorDepth,
79 CodecQ quality,
80 CodecType cType,
81 CompressorComponent codec,
82 long *size );
83 static OSErr (*CDSequenceEnd)( ImageSequence seqID );
84 static Component (*FindNextComponent)(Component prev,ComponentDescription* desc);
85 static long (*CountComponents)(ComponentDescription* desc);
86 static OSErr (*GetComponentInfo)(Component prev,ComponentDescription* desc,Handle h1,Handle h2,Handle h3);
87
88
89 extern void mencoder_write_chunk(aviwrite_stream_t *s,int len,unsigned int flags);
90
91
92 //static int format=mmioFOURCC('S','V','Q','1');
93 static int format=mmioFOURCC('S','V','Q','3');
94
95
96
97 //static void *frame_in; //input frame
98 static void *frame_prev; //previous frame
99 static void *frame_comp; //compressed frame
100 static GWorldPtr frame_GWorld_in = NULL;//a GWorld is some kind of description for a drawing environment
101 static GWorldPtr frame_GWorld_prev = NULL;
102 static Rect FrameRect;
103
104 static CompressorComponent compressor;
105 static DecompressorComponent decompressor;
106 static ImageDescriptionHandle desc;
107 static ImageSequence seq;
108
109
110
111
112
113 struct vf_priv_s {
114 aviwrite_stream_t* mux;
115 //dv_encoder_t* enc;
116
117 };
118 #define mux_v (vf->priv->mux)
119
120 //===========================================================================//
121
122 static int config(struct vf_instance_s* vf,
123 int width, int height, int d_width, int d_height,
124 unsigned int flags, unsigned int outfmt){
125 OSErr cres;
126 ComponentDescription cdesc;
127 mux_v->bih->biWidth=width;
128 mux_v->bih->biHeight=height;
129 mux_v->bih->biSizeImage=width*height*2;
130
131
132
133 memset(&desc,0,sizeof(cdesc));
134 cdesc.componentType= (((unsigned char)'i')<<24)|
135 (((unsigned char)'m')<<16)|
136 (((unsigned char)'c')<<8)|
137 (((unsigned char)'o'));
138
139 cdesc.componentSubType=bswap_32(format);
140 cdesc.componentManufacturer=0;
141 cdesc.componentFlags=0;
142 cdesc.componentFlagsMask=0;
143
144
145 printf("Count = %d\n",CountComponents(&cdesc));
146 compressor=FindNextComponent(NULL,&cdesc);
147 if(!compressor){
148 printf("Cannot find requested component\n");
149 return(0);
150 }
151 printf("Found it! ID = 0x%X\n",compressor);
152
153 // cres= FindCodec (fourcc,anyCodec,&compressor,&decompressor );
154 // printf("FindCodec returned:%i compressor: 0x%X decompressor: 0x%X\n",cres&0xFFFF,compressor,decompressor);
155
156 return 1;
157 }
158
159 static int control(struct vf_instance_s* vf, int request, void* data){
160
161 return CONTROL_UNKNOWN;
162 }
163
164 static int query_format(struct vf_instance_s* vf, unsigned int fmt){
165 if(fmt==IMGFMT_YUY2) return 3;
166 return 0;
167 }
168
169 static int codec_inited = 0;
170
171 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){
172
173 OSErr cres;
174 long framesizemax;
175 UInt8 similarity;
176 long compressedsize;
177 int in_format=kYUVSPixelFormat;
178 int width = mpi->width;
179 int height = mpi->height;
180 int stride = width*2;
181 if(!codec_inited){
182 FrameRect.top=0;
183 FrameRect.left=0;
184 FrameRect.right=width;
185 FrameRect.bottom=height;
186 cres = QTNewGWorldFromPtr(
187 &frame_GWorld_in,
188 in_format,
189 &FrameRect,
190 0,
191 0,
192 0,
193 mpi->planes[0],
194 stride);
195 printf("NewGWorldFromPtr returned:%i\n",cres&0xFFFF);
196 //dunno what todo about this
197 frame_prev = malloc(stride * height);
198 cres = QTNewGWorldFromPtr(
199 &frame_GWorld_prev,
200 in_format,
201 &FrameRect,
202 0,
203 0,
204 0,
205 frame_prev,
206 stride);
207 printf("height:%i width:%i stride:%i\n",height,width,stride);
208 printf("NewGWorldFromPtr returned:%i\n",cres&0xFFFF);
209 cres= GetMaxCompressionSize (
210 GetGWorldPixMap(frame_GWorld_in),
211 &FrameRect,
212 24,
213 codecNormalQuality,
214 bswap_32(format),
215 compressor,
216 &framesizemax );
217 printf("GetMaxCompressionSize returned:%i : MaxSize:%i\n",cres&0xFFFF,framesizemax);
218 frame_comp=malloc(framesizemax);
219 desc = (ImageDescriptionHandle)NewHandleClear(MAX_IDSIZE); //memory where the desc will be stored
220 (*desc)->idSize=MAX_IDSIZE;
221
222 cres= CompressSequenceBegin (
223 &seq,
224 GetGWorldPixMap( frame_GWorld_in),
225 GetGWorldPixMap( frame_GWorld_prev),
226 &FrameRect,
227 &FrameRect,
228 24, // color depth
229 bswap_32(format), // fourcc
230 compressor, // codec component
231 codecNormalQuality, //codecNormalQuality,
232 codecMaxQuality, //codecNormalQuality,
233 10*25, // keyframe rate
234 0,
235 0,
236 desc);
237 printf("CompressSequenceBegin returned:%i\n",cres&0xFFFF);
238 printf("Sequence ID:%i\n",seq);
239
240 dump_ImageDescription(*desc);
241 codec_inited++;
242 }
243 cres = CompressSequenceFrame (
244 seq,
245 GetGWorldPixMap(frame_GWorld_in),
246 &FrameRect,
247 0,
248 (char*)mux_v->buffer,
249 &compressedsize,
250 &similarity,
251 0);
252
253 if(cres&0xFFFF)printf("CompressSequenceFrame returned:%i\n",cres&0xFFFF);
254 printf("Size %i->%i \n",stride*height,compressedsize);
255 #if 0
256 printf("Ratio: %i:1\n",(stride*height)/compressedsize);
257 #endif
258 mencoder_write_chunk(mux_v, compressedsize , 0x10);
259
260 if(((*desc)->idSize)>MAX_IDSIZE){
261 printf("FATAL! idSize=%d too big, increase MAX_IDSIZE in ve_qtvideo.c!\n",((*desc)->idSize));
262 } else {
263 // according to QT docs, imagedescription may be changed while encoding
264 // a frame (even its size may (and does!) change!)
265 memcpy(mux_v->bih+1,*desc,(*desc)->idSize);
266 }
267
268 return 1;
269 }
270
271 //===========================================================================//
272
273 static int vf_open(vf_instance_t *vf, char* args){
274 OSErr cres = 1;
275 vf->config=config;
276 vf->control=control;
277 vf->query_format=query_format;
278 vf->put_image=put_image;
279 vf->priv=malloc(sizeof(struct vf_priv_s));
280 memset(vf->priv,0,sizeof(struct vf_priv_s));
281 vf->priv->mux=(aviwrite_stream_t*)args;
282
283 mux_v->bih=malloc(sizeof(BITMAPINFOHEADER)+MAX_IDSIZE);
284 mux_v->bih->biSize=sizeof(BITMAPINFOHEADER)+MAX_IDSIZE;
285 mux_v->bih->biWidth=0;
286 mux_v->bih->biHeight=0;
287 mux_v->bih->biCompression=format;
288 mux_v->bih->biPlanes=1;
289 mux_v->bih->biBitCount=24;
290
291
292 Setup_LDT_Keeper();
293 handler = LoadLibraryA("qtmlClient.dll");
294 InitializeQTML = GetProcAddress(handler, "InitializeQTML");
295 GetGWorldPixMap = GetProcAddress(handler, "GetGWorldPixMap");
296 QTNewGWorldFromPtr = GetProcAddress(handler, "QTNewGWorldFromPtr");
297 NewHandleClear = GetProcAddress(handler, "NewHandleClear");
298 FindCodec = GetProcAddress(handler,"FindCodec");
299 CompressSequenceBegin = GetProcAddress(handler,"CompressSequenceBegin");
300 CompressSequenceFrame = GetProcAddress(handler,"CompressSequenceFrame");
301 GetMaxCompressionSize = GetProcAddress(handler,"GetMaxCompressionSize");
302 CDSequenceEnd = GetProcAddress(handler,"CDSequenceEnd");
303 FindNextComponent = GetProcAddress(handler, "FindNextComponent");
304 CountComponents = GetProcAddress(handler, "CountComponents");
305 GetComponentInfo = GetProcAddress(handler, "GetComponentInfo");
306 if(!InitializeQTML ||!CompressSequenceBegin){
307 printf("invalid qt DLL!\n");
308 return 0;
309 }
310 //printf("%i,%i,%i\n",mmioFOURCC('S','V','Q','1'),'SVQ1',bswap_32(mmioFOURCC('S','V','Q','1')));
311 cres=InitializeQTML(6+16);
312 printf("InitializeQTML returned %i\n",cres);
313 return 1;
314 }
315
316 vf_info_t ve_info_qtvideo = {
317 "Quicktime video encoder using win32 DLLs",
318 "qtvideo",
319 "Sascha Sommer",
320 "for internal use by mencoder",
321 vf_open
322 };
323
324 //===========================================================================//
325 #endif