2 Convert avi movie files into swf.
4 Part of the swftools package.
6 Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
8 This file is distributed under the GPL, see file COPYING for details */
15 // TODO: those two should be checked for by configure
19 #include "../config.h"
21 #include "../lib/args.h"
26 #include <avifile/version.h>
27 #if (AVIFILE_MAJOR_VERSION == 0) && (AVIFILE_MINOR_VERSION>=6)
32 #include <StreamInfo.h>
44 static char * filename = 0;
45 static char * outputfilename = "output.swf";
48 static int quality = 80;
49 static double scale = 1.0;
51 static int expensive = 0;
53 struct options_t options[] =
66 int args_callback_option(char*name,char*val)
68 if(!strcmp(name, "V")) {
69 printf("avi2swf - part of %s %s\n", PACKAGE, VERSION);
72 else if(!strcmp(name, "o")) {
76 else if(!strcmp(name, "q")) {
84 else if(!strcmp(name, "p")) {
88 else if(!strcmp(name, "v")) {
92 else if(!strcmp(name, "x")) {
96 else if(!strcmp(name, "d")) {
97 scale = atoi(val)/100.0;
98 if(scale>1.0 || scale<=0) {
99 fprintf(stderr, "Scale must be in the range 1-100!\n");
104 fprintf(stderr, "Unknown option: -%s\n", name);
107 int args_callback_longoption(char*name,char*val)
109 return args_long2shortoption(options, name, val);
111 void args_callback_usage(char*name)
113 printf("\nUsage: %s file.avi\n", name);
114 printf("\t-h , --help\t\t Print help and exit\n");
115 printf("\t-o , --output filename\t Specify output filename\n");
116 printf("\t-n , --num frames\t Number of frames to encode\n");
117 printf("\t-s , --start frame\t First frame to encode\n");
118 printf("\t-d , --scale factor\t Scale to factor percent\n");
119 printf("\t-p , --flip\t\t Turn movie upside down\n");
120 printf("\t-V , --version\t\t Print program version and exit\n");
123 int args_callback_command(char*name,char*val)
126 fprintf(stderr, "Only one file allowed. You supplied at least two. (%s and %s)\n",
133 static char toabuf[128];
134 static char*ftoa(double a)
136 sprintf(toabuf, "%f", a);
139 static char*itoa(int a)
141 sprintf(toabuf, "%d", a);
145 typedef struct _videoreader_avifile_internal
147 IAviReadFile* player;
148 IAviReadStream* astream;
149 IAviReadStream* vstream;
155 } videoreader_avifile_internal;
157 static int shutdown_avi2swf = 0;
158 static int frameno = 0;
159 pthread_t main_thread;
160 static void sigterm(int sig)
162 if(pthread_equal (pthread_self(), main_thread))
164 if(frameno>0 && !shutdown_avi2swf) {
166 printf("Thread [%08x] got sigterm %d\n", pthread_self(), sig);
174 int videoreader_avifile_getsamples(videoreader_t* v, void*buffer, int num)
177 unsigned int samples_read, bytes_read;
179 printf("videoreader_getsamples(%d)\n", num);fflush(stdout);
181 videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
182 if(i->soundbits == 8) {
183 ret = i->astream->ReadFrames(buffer, num/2, num/(v->channels*2), samples_read, bytes_read);
184 unsigned char*b = (unsigned char*)buffer;
186 for(t=num-2;t>=0;t-=2) {
187 unsigned char x = b[t/2];
193 if(i->soundbits == 16) {
194 ret = i->astream->ReadFrames(buffer, num, num/(v->channels*2), samples_read, bytes_read);
199 int videoreader_avifile_getimage(videoreader_t* v, void*buffer)
201 videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
203 printf("videoreader_getimage()\n");fflush(stdout);
212 if(i->vstream->ReadFrame() < 0) {
216 CImage*img = i->vstream->GetFrame(true);
224 unsigned char*data = img->Data();
225 int bpp = img->Bpp();
228 for(y=0;y<v->height;y++) {
229 unsigned char*from,*to;
230 to = &((unsigned char*)buffer)[y*v->width*4];
232 from = img->At(v->height-y-1);
235 for(x=0;x<v->width;x++) {
237 to[x*4+1] = from[x*3+2];
238 to[x*4+2] = from[x*3+1];
239 to[x*4+3] = from[x*3+0];
242 return v->width*v->height*4;
247 bool videoreader_avifile_eof(videoreader_t* v)
249 videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
251 printf("videoreader_eof()\n");fflush(stdout);
255 void videoreader_avifile_close(videoreader_t* v)
257 videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
259 printf("videoreader_close()\n");fflush(stdout);
262 void* videoreader_avifile_getinfo(videoreader_t* v, char* name)
266 void videoreader_avifile_setparameter(videoreader_t*v, char*name, char*value)
269 printf("videoreader_setparameter(%s, %s)\n", name, value);fflush(stdout);
273 int videoreader_avifile_open(videoreader_t* v, char* filename)
275 videoreader_avifile_internal* i;
276 i = (videoreader_avifile_internal*)malloc(sizeof(videoreader_avifile_internal));
277 memset(i, 0, sizeof(videoreader_avifile_internal));
278 memset(v, 0, sizeof(videoreader_t));
279 v->getsamples = videoreader_avifile_getsamples;
280 v->getinfo = videoreader_avifile_getinfo;
281 v->close = videoreader_avifile_close;
282 v->eof = videoreader_avifile_eof;
283 v->getimage = videoreader_avifile_getimage;
284 v->getsamples = videoreader_avifile_getsamples;
285 v->setparameter = videoreader_avifile_setparameter;
291 i->player = CreateIAviReadFile(filename);
293 printf("%d streams (%d video, %d audio)\n",
294 i->player->StreamCount(),
295 i->player->VideoStreamCount(),
296 i->player->AudioStreamCount());
298 i->astream = i->player->GetStream(0, AviStream::Audio);
299 i->vstream = i->player->GetStream(0, AviStream::Video);
301 printf("Couldn't open video stream\n");
305 printf("Couldn't open video stream\n");
309 if(!i->do_video && !i->do_audio) {
310 printf("File has neither audio nor video streams.(?)\n");
316 int dwMicroSecPerFrame = 0;
317 player->GetFileHeader(&head);
318 printf("fps: %d\n", 1000000/head.dwMicroSecPerFrame);
319 printf("frames: %d\n", head.dwTotalFrames);
320 printf("streams: %d\n", head.dwStreams);
321 printf("width: %d\n", head.dwWidth);
322 printf("height: %d\n", head.dwHeight);
323 printf("sound: %u samples (%f seconds)\n", i->astream->GetEndPos(), i->astream->GetEndTime());
324 v->width = head.dwWidth;
325 v->height = head.dwHeight;
326 dwMicroSecPerFrame = head.dwMicroSecPerFrame;
327 samplesperframe = astream->GetEndPos()/astream->GetEndTime()*head.dwMicroSecPerFrame/1000000;
328 v->rate = (int)(astream->GetEndPos()/astream->GetEndTime());
329 v->fps = 1000000.0/dwMicroSecPerFrame;
332 StreamInfo*audioinfo;
333 StreamInfo*videoinfo;
336 videoinfo = i->vstream->GetStreamInfo();
337 v->width = videoinfo->GetVideoWidth();
338 v->height = videoinfo->GetVideoHeight();
339 v->fps = (double)(videoinfo->GetFps());
344 i->astream->GetAudioFormatInfo(&wave,0);
345 v->channels = wave.nChannels;
346 i->soundbits = wave.wBitsPerSample;
347 if(wave.wBitsPerSample != 8 && wave.wBitsPerSample != 16) {
348 printf("Can't handle %d bit audio, disabling sound\n", wave.wBitsPerSample);
356 audioinfo = i->astream->GetStreamInfo();
357 v->rate = audioinfo->GetAudioSamplesPerSec();
360 i->vstream -> StartStreaming();
362 i->astream -> StartStreaming();
367 int main (int argc,char ** argv)
374 signal(SIGTERM, sigterm);
375 signal(SIGINT , sigterm);
376 signal(SIGQUIT, sigterm);
377 main_thread = pthread_self();
379 processargs(argc, argv);
383 fi = fopen(outputfilename, "wb");
385 fflush(stdout); fflush(stderr);
386 fprintf(stderr, "Couldn't open %s\n", outputfilename);
390 ret = videoreader_avifile_open(&video, filename);
393 printf("Error opening %s\n", filename);
398 printf("| video framerate: %f\n", video.fps);
399 printf("| video size: %dx%d\n", video.width, video.height);
400 printf("| audio rate: %d\n", video.rate);
401 printf("| audio channels: %d\n", video.channels);
404 ret = v2swf_init(&v2swf, &video);
406 v2swf_setparameter(&v2swf, "verbose", "1");
407 v2swf_setparameter(&v2swf, "quality", itoa(quality));
408 v2swf_setparameter(&v2swf, "blockdiff", "0");
409 v2swf_setparameter(&v2swf, "blockdiff_mode", "exact");
410 v2swf_setparameter(&v2swf, "mp3_bitrate", "128");
411 //v2swf_setparameter(&v2swf, "fixheader", "1");
412 //v2swf_setparameter(&v2swf, "framerate", "15");
413 v2swf_setparameter(&v2swf, "scale", ftoa(scale));
414 v2swf_setparameter(&v2swf, "prescale", "1");
415 v2swf_setparameter(&v2swf, "keyframe_interval", "200");
416 v2swf_setparameter(&v2swf, "flash_version", "6");
418 v2swf_setparameter(&v2swf, "motioncompensation", "1");
425 int l=v2swf_read(&v2swf, buffer, 4096);
426 fwrite(buffer, l, 1, fi);
430 printf("\rConverting frame %d", frameno);fflush(stdout);
436 v2swf_backpatch(&v2swf, outputfilename);