2 Convert avi movie files into swf.
3 As soon as there's an algorithm implemented for writing the
4 data directly to disk, this file should maybe go to ../src.
6 Part of the swftools package.
8 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
10 This file is distributed under the GPL, see file COPYING for details */
15 #include "../rfxswf.h"
22 char * outputfilename = "output.swf";
23 unsigned int lastframe = 0xffffffff;
25 int jpeg_quality = 40;
27 struct options_t options[] =
36 int args_callback_option(char*name,char*val)
38 if(!strcmp(name, "V")) {
39 printf("avi2swf - part of %s %s\n", PACKAGE, VERSION);
42 else if(!strcmp(name, "o")) {
46 else if(!strcmp(name, "e")) {
47 lastframe = atoi(val);
51 int args_callback_longoption(char*name,char*val)
53 return args_long2shortoption(options, name, val);
55 void args_callback_usage(char*name)
57 printf("\nUsage: %s file.swf\n", name);
58 printf("\t-h , --help\t\t Print help and exit\n");
59 printf("\t-o , --output=filename\t Specify output filename\n");
60 printf("\t-e , --end=frame\t\t Last frame to encode\n");
61 printf("\t-V , --version\t\t Print program version and exit\n");
64 int args_callback_command(char*name,char*val)
67 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
77 int main (int argc,char ** argv)
80 IAviReadStream* astream;
81 IAviReadStream* vstream;
85 processargs(argc, argv);
89 player = CreateIAviReadFile(filename);
90 player->GetFileHeader(&head);
91 printf("fps: %d\n", 1000000/head.dwMicroSecPerFrame);
92 printf("frames: %d\n", head.dwTotalFrames);
93 printf("streams: %d\n", head.dwStreams);
94 printf("streams: %d\n", player->StreamCount());
95 printf("width: %d\n", head.dwWidth);
96 printf("height: %d\n", head.dwHeight);
98 astream = player->GetStream(0, AviStream::Audio);
99 vstream = player->GetStream(0, AviStream::Video);
101 vstream -> StartStreaming();
103 file = open(outputfilename,O_WRONLY|O_CREAT|O_TRUNC, 0644);
105 memset(&swf, 0, sizeof(swf));
106 swf.frameRate = (int)(1000000.0/head.dwMicroSecPerFrame*256);
108 swf.fileSize = 0x0fffffff;
111 r.xmax = head.dwWidth*20;
112 r.ymax = head.dwHeight*20;
115 swf_WriteHeader(file, &swf);
117 tag = swf_InsertTag(NULL, ST_SETBACKGROUNDCOLOR);
118 swf_SetU8(tag,0); //black
121 swf_WriteTag(file, tag);
124 U8*newdata = (U8*)malloc((head.dwWidth+3) * head.dwHeight * 4);
128 int lastsize = (head.dwWidth+3) * head.dwHeight * 4;
129 U8* lastdata = (U8*)malloc(lastsize);
131 memset(lastdata,0, lastsize);
134 if(vstream->ReadFrame()<0) {
138 printf("\rconvert frame %d",frame);
140 CImage*img = vstream->GetFrame();
143 int width = img->width();
144 int bpp = img->bpp();
145 int width4 = width*4;
146 int height = img->height();
155 tag = swf_InsertTag(NULL, ST_REMOVEOBJECT2);
156 swf_SetU16(tag, 1); //depth
157 swf_WriteTag(file, tag);
161 /* todo: dynamically decide whether to generate jpeg/lossless
162 bitmaps, (using transparency to modify the previous
163 picture), and which jpeg compression depth to use.
164 (btw: Are there video frame transitions which can
165 reasonably be approximated by shapes?)
171 tag = swf_InsertTag(NULL, ST_DEFINEBITSLOSSLESS);
172 swf_SetU16(tag, frame*2);
173 U8*mylastdata = lastdata;
174 for(y=0;y<height;y++) {
175 U8*nd = &newdata[width4*y];
176 U8*mydata = img->at(y);
178 for(x=0;x<width;x++) {
182 mylastdata[2] = mydata[2];
183 mylastdata[1] = mydata[1];
184 mylastdata[0] = mydata[0];
190 for(x=0;x<width;x++) {
191 int a = mylastdata[3]-data[3];
192 int b = mylastdata[2]-data[2];
193 int c = mylastdata[1]-data[1];
206 mylastdata[2] = mydata[2];
207 mylastdata[1] = mydata[1];
208 mylastdata[0] = mydata[0];
214 swf_SetLosslessBits(tag,width,height,newdata,BMF_32BIT);
215 swf_WriteTag(file, tag);
219 tag = swf_InsertTag(NULL, ST_DEFINEBITSJPEG2);
220 swf_SetU16(tag, frame*2);
221 JPEGBITS * jb = swf_SetJPEGBitsStart(tag,width,height,jpeg_quality);
222 U8*mylastdata = lastdata;
223 for(y=0;y<height;y++) {
225 U8*mydata = img->at(y);
226 for(x=0;x<width;x++) {
231 nd[0] = (mydata[2]-mylastdata[2])/2+0x80;
232 nd[1] = (mydata[1]-mylastdata[1])/2+0x80;
233 nd[2] = (mydata[0]-mylastdata[0])/2+0x80;
235 mylastdata[2] = mydata[2];
236 mylastdata[1] = mydata[1];
237 mylastdata[0] = mydata[0];
242 swf_SetJPEGBitsLine(jb,newdata);
244 swf_SetJPEGBitsFinish(jb);
245 swf_WriteTag(file, tag);
249 tag = swf_InsertTag(NULL, ST_DEFINESHAPE);
251 rgb.b = rgb.g = rgb.r = 0xff;
252 ls = swf_ShapeAddLineStyle(s,20,&rgb);
253 swf_GetMatrix(NULL,&m);
257 fs = swf_ShapeAddBitmapFillStyle(s,&m,frame*2,0);
258 swf_SetU16(tag ,frame*2+1); // ID
265 swf_SetShapeStyles(tag,s);
266 swf_ShapeCountBits(s,NULL,NULL);
267 swf_SetShapeBits(tag,s);
269 swf_ShapeSetAll(tag,s,0,0,ls,fs,0);
271 swf_ShapeSetLine(tag,s,width*20,0);
272 swf_ShapeSetLine(tag,s,0,height*20);
273 swf_ShapeSetLine(tag,s,-width*20,0);
274 swf_ShapeSetLine(tag,s,0,-height*20);
275 swf_ShapeSetEnd(tag);
276 swf_WriteTag(file, tag);
279 tag = swf_InsertTag(NULL,ST_PLACEOBJECT2);
280 swf_ObjectPlace(tag,frame*2+1,1,0,0,0);
281 swf_WriteTag(file, tag);
284 tag = swf_InsertTag(NULL, ST_SHOWFRAME);
285 swf_WriteTag(file, tag);
289 if(frame == lastframe)
295 tag = swf_InsertTag(NULL, ST_END);
296 swf_WriteTag(file, tag);