X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=avi2swf%2Favi2swf.cc;h=c68fedbbca3e0566260f60ac8f8d04022df749f2;hp=8d887f8a5bcb083a8870f11131c5c2df90ccd34e;hb=2c719855eac434f01d47ba0717d76de65939d74e;hpb=7caa3b9a0d6328a7d34a10fa4ef6f70e6f6cbde5 diff --git a/avi2swf/avi2swf.cc b/avi2swf/avi2swf.cc index 8d887f8..c68fedb 100644 --- a/avi2swf/avi2swf.cc +++ b/avi2swf/avi2swf.cc @@ -3,9 +3,21 @@ Part of the swftools package. - Copyright (c) 2001 Matthias Kramm - - This file is distributed under the GPL, see file COPYING for details */ + Copyright (c) 2001,2002,2003 Matthias Kramm + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include @@ -14,36 +26,12 @@ #include "../config.h" -#ifdef HAVE_SIGNAL_H -#ifdef HAVE_PTHREAD_H -#include -#include -#define DO_SIGNALS -#endif -#endif - -extern "C" { #include "../lib/args.h" -} #include "v2swf.h" - -#undef HAVE_CONFIG_H -#include -#if (AVIFILE_MAJOR_VERSION == 0) && (AVIFILE_MINOR_VERSION>=6) - #include - #include - #include - #include - #include - #define VERSION6 +#ifdef WIN32 +#include "videoreader_vfw.hh" #else - #include - #include - #include - #define Width width - #define Height height - #define Data data - #define Bpp bpp +#include "videoreader_avifile.hh" #endif static char * filename = 0; @@ -54,29 +42,51 @@ static int quality = 80; static double scale = 1.0; static int flip = 0; static int expensive = 0; - -struct options_t options[] = -{ - {"v","verbose"}, - {"o","output"}, - {"p","flip"}, - {"q","quality"}, - {"d","scale"}, - {"x","extragood"}, - {"V","version"}, - {0,0} +static int flashversion = 6; +static int keyframe_interval = -1; +static int skip = 0; +static float audio_adjust = 0; +static int mp3_bitrate = 32; +static int samplerate = 11025; +static int numframes = 0; +static char* skipframes = 0; + +static struct options_t options[] = { +{"h", "help"}, +{"o", "output"}, +{"A", "adjust"}, +{"n", "num"}, +{"m", "mp3-bitrate"}, +{"r", "mp3-samplerate"}, +{"s", "scale"}, +{"S", "skipframes"}, +{"p", "flip"}, +{"q", "quality"}, +{"k", "keyframe"}, +{"x", "extragood"}, +{"T", "flashversion"}, +{"V", "version"}, +{0,0} }; int args_callback_option(char*name,char*val) { if(!strcmp(name, "V")) { - printf("avi2swf - part of %s %s\n", PACKAGE, VERSION); + printf("avi2swf-ng - part of %s %s\n", PACKAGE, VERSION); exit(0); } else if(!strcmp(name, "o")) { outputfilename = val; return 1; } + else if(!strcmp(name, "n")) { + numframes = atoi(val); + return 1; + } + else if(!strcmp(name, "d")) { + scale = atof(val); + return 1; + } else if(!strcmp(name, "q")) { quality = atoi(val); if(quality<0) @@ -89,15 +99,54 @@ int args_callback_option(char*name,char*val) flip = 1; return 0; } + else if(!strcmp(name, "k")) { + keyframe_interval = atoi(val); + return 1; + } + else if(!strcmp(name, "A")) { + audio_adjust = atof(val); + return 1; + } else if(!strcmp(name, "v")) { verbose = 1; return 0; } + else if(!strcmp(name, "T")) { + flashversion = atoi(val); + return 1; + } else if(!strcmp(name, "x")) { expensive = 1; return 0; } - else if(!strcmp(name, "d")) { + else if(!strcmp(name, "m")) { + mp3_bitrate = atoi(val); + return 1; + } + else if(!strcmp(name, "r")) { + samplerate = atoi(val); + if(samplerate >= 11000 && samplerate <= 12000) + samplerate = 11025; + else if(samplerate >= 22000 && samplerate <= 23000) + samplerate = 22050; + else if(samplerate >= 44000 && samplerate <= 45000) + samplerate = 44100; + else { + fprintf(stderr, "Invalid samplerate: %d\n", samplerate); + fprintf(stderr, "Allowed values: 11025, 22050, 44100\n", samplerate); + exit(1); + } + return 1; + } + else if(!strcmp(name, "S")) { + skip = atoi(val); + return 1; + } + else if(!strcmp(name, "C")) { + skipframes = strdup(val); + return 1; + } + else if(!strcmp(name, "s")) { scale = atoi(val)/100.0; if(scale>1.0 || scale<=0) { fprintf(stderr, "Scale must be in the range 1-100!\n"); @@ -112,19 +161,26 @@ int args_callback_longoption(char*name,char*val) { return args_long2shortoption(options, name, val); } -void args_callback_usage(char*name) -{ - printf("\nUsage: %s file.avi\n", name); - printf("\t-h , --help\t\t Print help and exit\n"); - printf("\t-o , --output filename\t Specify output filename\n"); - printf("\t-n , --num frames\t Number of frames to encode\n"); - printf("\t-d , --scale \t Scale down to factor . (in %, e.g. 100 = original size)\n"); - printf("\t-p , --flip\t\t Turn movie upside down\n"); - printf("\t-q , --quality \t Set the quality to . (0-100, 0=worst, 100=best, default:80)\n"); - printf("\t-x , --extragood\t Enable some *very* expensive compression strategies. You may\n"); - printf("\t \t want to let this run overnight.\n"); - printf("\t-V , --version\t\t Print program version and exit\n"); - exit(0); +void args_callback_usage(char *name) +{ + printf("\n"); + printf("Usage: %s file.avi [-o output.swf]\n", name); + printf("\n"); + printf("-h , --help Print help and exit\n"); + printf("-o , --output filename Specify output filename\n"); + printf("-A , --adjust seconds Audio adjust: Shift sound -seconds to the future or +seconds into the past.\n"); + printf("-n , --num frames Number of frames to encode\n"); + printf("-m , --mp3-bitrate Set the mp3 bitrate to encode audio with\n"); + printf("-r , --mp3-samplerate Set the mp3 samplerate to encode audio with (default: 11025)\n"); + printf("-s , --scale Scale down to factor . (in %, e.g. 100 = original size)\n"); + printf("-S , --skipframes Skip frames before starting the conversion.\n"); + printf("-p , --flip Turn movie upside down\n"); + printf("-q , --quality Set the quality to . (0-100, 0=worst, 100=best, default:80)\n"); + printf("-k , --keyframe Set the number of intermediate frames between keyframes.\n"); + printf("-x , --extragood Enable some *very* expensive compression strategies.\n"); + printf("-T , --flashversion Set output flash version to .\n"); + printf("-V , --version Print program version and exit\n"); + printf("\n"); } int args_callback_command(char*name,char*val) { @@ -148,21 +204,6 @@ static char*itoa(int a) return toabuf; } -typedef struct _videoreader_avifile_internal -{ - IAviReadFile* player; - IAviReadStream* astream; - IAviReadStream* vstream; - int do_audio; - int do_video; - int eof; - int frame; - int soundbits; -} videoreader_avifile_internal; - -static int shutdown_avi2swf = 0; -static int frameno = 0; - #ifdef DO_SIGNALS pthread_t main_thread; static void sigterm(int sig) @@ -180,199 +221,6 @@ static void sigterm(int sig) } #endif -int videoreader_avifile_getsamples(videoreader_t* v, void*buffer, int num) -{ - int ret; - unsigned int samples_read, bytes_read; - if(verbose) { - printf("videoreader_getsamples(%d)\n", num);fflush(stdout); - } - videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal; - if(i->soundbits == 8) { - ret = i->astream->ReadFrames(buffer, num/2, num/(v->channels*2), samples_read, bytes_read); - unsigned char*b = (unsigned char*)buffer; - int t; - for(t=num-2;t>=0;t-=2) { - unsigned char x = b[t/2]; - b[t] = 0; - b[t+1] = x-128; - } - return num; - } - if(i->soundbits == 16) { - ret = i->astream->ReadFrames(buffer, num, num/(v->channels*2), samples_read, bytes_read); - return num; - } - return 0; -} -int videoreader_avifile_getimage(videoreader_t* v, void*buffer) -{ - videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal; - if(verbose) { - printf("videoreader_getimage()\n");fflush(stdout); - } - - if(shutdown_avi2swf) - i->eof = 1; - - if(i->eof) - return 0; - - if(i->vstream->ReadFrame() < 0) { - i->eof = 1; - return 0; - } - CImage*img = i->vstream->GetFrame(true); - if(!img) { - i->eof = 1; - return 0; - } - img->ToRGB(); - frameno++; - i->frame++; - unsigned char*data = img->Data(); - int bpp = img->Bpp(); - if(bpp == 3) { - int x,y; - for(y=0;yheight;y++) { - unsigned char*from,*to; - to = &((unsigned char*)buffer)[y*v->width*4]; - if(flip) - from = img->At(v->height-y-1); - else - from = img->At(y); - for(x=0;xwidth;x++) { - to[x*4+0] = 0; - to[x*4+1] = from[x*3+2]; - to[x*4+2] = from[x*3+1]; - to[x*4+3] = from[x*3+0]; - } - } - return v->width*v->height*4; - } else { - return 0; - } -} -bool videoreader_avifile_eof(videoreader_t* v) -{ - videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal; - if(verbose) { - printf("videoreader_eof()\n");fflush(stdout); - } - return i->eof; -} -void videoreader_avifile_close(videoreader_t* v) -{ - videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal; - if(verbose) { - printf("videoreader_close()\n");fflush(stdout); - } -} -void* videoreader_avifile_getinfo(videoreader_t* v, char* name) -{ - return 0; -} -void videoreader_avifile_setparameter(videoreader_t*v, char*name, char*value) -{ - if(verbose) { - printf("videoreader_setparameter(%s, %s)\n", name, value);fflush(stdout); - } -} - -int videoreader_avifile_open(videoreader_t* v, char* filename) -{ - videoreader_avifile_internal* i; - i = (videoreader_avifile_internal*)malloc(sizeof(videoreader_avifile_internal)); - memset(i, 0, sizeof(videoreader_avifile_internal)); - memset(v, 0, sizeof(videoreader_t)); - v->getsamples = videoreader_avifile_getsamples; - v->getinfo = videoreader_avifile_getinfo; - v->close = videoreader_avifile_close; - v->eof = videoreader_avifile_eof; - v->getimage = videoreader_avifile_getimage; - v->getsamples = videoreader_avifile_getsamples; - v->setparameter = videoreader_avifile_setparameter; - v->internal = i; - - i->do_video = 1; - i->do_audio = 1; - - i->player = CreateIAviReadFile(filename); - if(verbose) { - printf("%d streams (%d video, %d audio)\n", - i->player->StreamCount(), - i->player->VideoStreamCount(), - i->player->AudioStreamCount()); - } - i->astream = i->player->GetStream(0, AviStream::Audio); - i->vstream = i->player->GetStream(0, AviStream::Video); - if(!i->vstream) { - printf("Couldn't open video stream\n"); - i->do_video = 0; - } - if(!i->astream) { - printf("Couldn't open video stream\n"); - i->do_audio = 0; - } - - if(!i->do_video && !i->do_audio) { - printf("File has neither audio nor video streams.(?)\n"); - return 0; - } - -#ifndef VERSION6 - MainAVIHeader head; - int dwMicroSecPerFrame = 0; - player->GetFileHeader(&head); - printf("fps: %d\n", 1000000/head.dwMicroSecPerFrame); - printf("frames: %d\n", head.dwTotalFrames); - printf("streams: %d\n", head.dwStreams); - printf("width: %d\n", head.dwWidth); - printf("height: %d\n", head.dwHeight); - printf("sound: %u samples (%f seconds)\n", i->astream->GetEndPos(), i->astream->GetEndTime()); - v->width = head.dwWidth; - v->height = head.dwHeight; - dwMicroSecPerFrame = head.dwMicroSecPerFrame; - samplesperframe = astream->GetEndPos()/astream->GetEndTime()*head.dwMicroSecPerFrame/1000000; - v->rate = (int)(astream->GetEndPos()/astream->GetEndTime()); - v->fps = 1000000.0/dwMicroSecPerFrame; - i->soundbits = 16; -#else - StreamInfo*audioinfo; - StreamInfo*videoinfo; - if(i->do_video) - { - videoinfo = i->vstream->GetStreamInfo(); - v->width = videoinfo->GetVideoWidth(); - v->height = videoinfo->GetVideoHeight(); - v->fps = (double)(videoinfo->GetFps()); - } - if(i->do_audio) - { - WAVEFORMATEX wave; - i->astream->GetAudioFormatInfo(&wave,0); - v->channels = wave.nChannels; - i->soundbits = wave.wBitsPerSample; - if(wave.wBitsPerSample != 8 && wave.wBitsPerSample != 16) { - printf("Can't handle %d bit audio, disabling sound\n", wave.wBitsPerSample); - i->do_audio = 0; - v->channels = 0; - v->rate = 0; - } - } - if(i->do_audio) - { - audioinfo = i->astream->GetStreamInfo(); - v->rate = audioinfo->GetAudioSamplesPerSec(); - } -#endif - i->vstream -> StartStreaming(); - if(i->do_audio) - i->astream -> StartStreaming(); - - return 1; -} - int main (int argc,char ** argv) { videoreader_t video; @@ -388,8 +236,16 @@ int main (int argc,char ** argv) #endif processargs(argc, argv); - if(!filename) + if(!filename) { + fprintf(stderr, "You must supply a filename"); exit(0); + } + if(keyframe_interval<0) { + if(flashversion>=6) + keyframe_interval=20; + else + keyframe_interval=5; + } fi = fopen(outputfilename, "wb"); if(!fi) { @@ -397,48 +253,89 @@ int main (int argc,char ** argv) fprintf(stderr, "Couldn't open %s\n", outputfilename); exit(1); } - + +#ifdef WIN32 + ret = videoreader_vfw_open(&video, filename); +#else ret = videoreader_avifile_open(&video, filename); +#endif - if(!ret) { - printf("Error opening %s\n", filename); + if(ret<0) { + fprintf(stderr, "Error opening %s\n", filename); exit(1); } if(verbose) { printf("| video framerate: %f\n", video.fps); printf("| video size: %dx%d\n", video.width, video.height); - printf("| audio rate: %d\n", video.rate); + printf("| audio rate: %d\n", video.samplerate); printf("| audio channels: %d\n", video.channels); } ret = v2swf_init(&v2swf, &video); if(verbose) v2swf_setparameter(&v2swf, "verbose", "1"); + if(numframes) + v2swf_setparameter(&v2swf, "numframes", itoa(numframes)); v2swf_setparameter(&v2swf, "quality", itoa(quality)); v2swf_setparameter(&v2swf, "blockdiff", "0"); v2swf_setparameter(&v2swf, "blockdiff_mode", "exact"); - v2swf_setparameter(&v2swf, "mp3_bitrate", "128"); + v2swf_setparameter(&v2swf, "mp3_bitrate", itoa(mp3_bitrate)); + v2swf_setparameter(&v2swf, "samplerate", itoa(samplerate)); //v2swf_setparameter(&v2swf, "fixheader", "1"); //v2swf_setparameter(&v2swf, "framerate", "15"); v2swf_setparameter(&v2swf, "scale", ftoa(scale)); v2swf_setparameter(&v2swf, "prescale", "1"); - v2swf_setparameter(&v2swf, "keyframe_interval", "200"); - v2swf_setparameter(&v2swf, "flash_version", "6"); + v2swf_setparameter(&v2swf, "flash_version", itoa(flashversion)); + v2swf_setparameter(&v2swf, "keyframe_interval", itoa(keyframe_interval)); + if(skipframes) + v2swf_setparameter(&v2swf, "skipframes", skipframes); if(expensive) v2swf_setparameter(&v2swf, "motioncompensation", "1"); + if(flip) + video.setparameter(&video, "flip", "1"); + if(verbose) + video.setparameter(&video, "verbose", "1"); - - char buffer[4096]; if(!verbose) printf("\n"); + + if(audio_adjust>0) { + int num = ((int)(audio_adjust*video.samplerate))*video.channels*2; + void*buf = malloc(num); + video.getsamples(&video, buf, num); + free(buf); + } else if(audio_adjust<0) { + int num = (int)(-audio_adjust*video.fps); + void*buf = malloc(video.width*video.height*4); + int t; + for(t=0;t