X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=avi2swf%2Favi2swf.cc;h=d231762c67541eea615d3db9d00c30d94d4ecec5;hp=8d887f8a5bcb083a8870f11131c5c2df90ccd34e;hb=f1fe720124d2fdc33defe18f6d1c3feda86980cf;hpb=7caa3b9a0d6328a7d34a10fa4ef6f70e6f6cbde5 diff --git a/avi2swf/avi2swf.cc b/avi2swf/avi2swf.cc index 8d887f8..d231762 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 @@ -26,9 +38,17 @@ extern "C" { #include "../lib/args.h" } #include "v2swf.h" +#include "../lib/q.h" #undef HAVE_CONFIG_H -#include + +#ifdef HAVE_VERSION_H + #include +#endif +#ifdef HAVE_AVIFILE_VERSION_H + #include +#endif + #if (AVIFILE_MAJOR_VERSION == 0) && (AVIFILE_MINOR_VERSION>=6) #include #include @@ -54,23 +74,33 @@ 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 struct options_t options[] = { +{"h", "help"}, +{"o", "output"}, +{"A", "adjust"}, +{"n", "num"}, +{"m", "mp3-bitrate"}, +{"r", "mp3-samplerate"}, +{"d", "scale"}, +{"p", "flip"}, +{"q", "quality"}, +{"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")) { @@ -89,15 +119,46 @@ int args_callback_option(char*name,char*val) flip = 1; return 0; } + 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 0; + } + 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, "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 +173,24 @@ 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 (kbps) Set the mp3 bitrate to encode audio with\n"); + printf("-r , --mp3-samplerate (Hz) Set the mp3 samplerate to encode audio with (default: 11025)\n"); + printf("-d , --scale Scale down to factor . (in %, e.g. 100 = original size)\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("-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) { @@ -158,6 +224,7 @@ typedef struct _videoreader_avifile_internal int eof; int frame; int soundbits; + ringbuffer_t audio_buffer; } videoreader_avifile_internal; static int shutdown_avi2swf = 0; @@ -180,16 +247,26 @@ static void sigterm(int sig) } #endif -int videoreader_avifile_getsamples(videoreader_t* v, void*buffer, int num) +static void readSamples(videoreader_avifile_internal*i, void*buffer, int buffer_size, int numsamples) { int ret; - unsigned int samples_read, bytes_read; + while(i->audio_buffer.available < buffer_size) { + unsigned int samples_read = 0, bytes_read = 0; + ret = i->astream->ReadFrames(buffer, buffer_size, numsamples, samples_read, bytes_read); + if(samples_read<=0) + return; + ringbuffer_put(&i->audio_buffer, buffer, bytes_read); + } + ringbuffer_read(&i->audio_buffer, buffer, buffer_size); +} +int videoreader_avifile_getsamples(videoreader_t* v, void*buffer, int num) +{ 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); + readSamples(i, buffer, num/2, num/(v->channels*2)); unsigned char*b = (unsigned char*)buffer; int t; for(t=num-2;t>=0;t-=2) { @@ -200,7 +277,7 @@ int videoreader_avifile_getsamples(videoreader_t* v, void*buffer, int num) return num; } if(i->soundbits == 16) { - ret = i->astream->ReadFrames(buffer, num, num/(v->channels*2), samples_read, bytes_read); + readSamples(i, buffer, num, num/(v->channels*2)); return num; } return 0; @@ -219,15 +296,28 @@ int videoreader_avifile_getimage(videoreader_t* v, void*buffer) return 0; if(i->vstream->ReadFrame() < 0) { + if(verbose) printf("vstream->ReadFrame() returned value < 0, shutting down...\n"); i->eof = 1; return 0; } - CImage*img = i->vstream->GetFrame(true); + CImage*img2 = 0; + CImage*img = i->vstream->GetFrame(); if(!img) { + if(verbose) printf("vstream->GetFrame() returned NULL, shutting down...\n"); i->eof = 1; return 0; } + /* we convert the image to YUV first, because we can convert to RGB from YUV only */ + img->ToYUV(); img->ToRGB(); + if(img->Bpp() != 3) { + if(verbose) printf("Warning: converthing from bpp %d to bpp 3, this fails on older avifile versions...\n", img->Bpp()); + BitmapInfo tmp(v->width, v->height, 24); + img2 = new CImage(img, &tmp); + img = img2; + } + + frameno++; i->frame++; unsigned char*data = img->Data(); @@ -248,8 +338,11 @@ int videoreader_avifile_getimage(videoreader_t* v, void*buffer) to[x*4+3] = from[x*3+0]; } } + if(img2) delete img2; return v->width*v->height*4; } else { + if(img2) delete img2; + if(verbose) printf("Can't handle bpp %d, shutting down...\n", bpp); return 0; } } @@ -267,6 +360,9 @@ void videoreader_avifile_close(videoreader_t* v) if(verbose) { printf("videoreader_close()\n");fflush(stdout); } + if(i->do_audio) { + ringbuffer_clear(&i->audio_buffer); + } } void* videoreader_avifile_getinfo(videoreader_t* v, char* name) { @@ -293,7 +389,7 @@ int videoreader_avifile_open(videoreader_t* v, char* filename) v->getsamples = videoreader_avifile_getsamples; v->setparameter = videoreader_avifile_setparameter; v->internal = i; - + i->do_video = 1; i->do_audio = 1; @@ -314,6 +410,12 @@ int videoreader_avifile_open(videoreader_t* v, char* filename) printf("Couldn't open video stream\n"); i->do_audio = 0; } +#ifdef NO_MP3 + if(i->do_audio) { + printf(stderr, "MP3 support has been disabled at compile time, not converting soundtrack"); + i->do_audio = 0; + } +#endif if(!i->do_video && !i->do_audio) { printf("File has neither audio nor video streams.(?)\n"); @@ -338,10 +440,9 @@ int videoreader_avifile_open(videoreader_t* v, char* filename) v->fps = 1000000.0/dwMicroSecPerFrame; i->soundbits = 16; #else - StreamInfo*audioinfo; - StreamInfo*videoinfo; if(i->do_video) { + StreamInfo*videoinfo; videoinfo = i->vstream->GetStreamInfo(); v->width = videoinfo->GetVideoWidth(); v->height = videoinfo->GetVideoHeight(); @@ -350,25 +451,44 @@ int videoreader_avifile_open(videoreader_t* v, char* filename) if(i->do_audio) { WAVEFORMATEX wave; + StreamInfo*audioinfo; + i->astream->GetAudioFormatInfo(&wave,0); + audioinfo = i->astream->GetStreamInfo(); + v->channels = wave.nChannels; + v->rate = wave.nSamplesPerSec; i->soundbits = wave.wBitsPerSample; - if(wave.wBitsPerSample != 8 && wave.wBitsPerSample != 16) { + + if(v->channels==0 || v->rate==0 || i->soundbits==0 || wave.wFormatTag!=1) { + v->rate = audioinfo->GetAudioSamplesPerSec(); + v->channels = audioinfo->GetAudioChannels(); + i->soundbits = audioinfo->GetAudioBitsPerSample(); + } + + if(verbose) { + printf("formatinfo: format %d, %d channels, %d bits/sample, rate %d, blockalign %d\n", wave.wFormatTag, wave.nChannels, wave.wBitsPerSample, wave.nSamplesPerSec, wave.nBlockAlign); + printf("audioinfo: %d channels, %d bits/sample, rate %d\n", audioinfo->GetAudioChannels(), audioinfo->GetAudioBitsPerSample(), audioinfo->GetAudioSamplesPerSec()); + } + if(i->soundbits != 8 && i->soundbits != 16) { printf("Can't handle %d bit audio, disabling sound\n", wave.wBitsPerSample); i->do_audio = 0; + i->soundbits = 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) + if(i->do_audio) { i->astream -> StartStreaming(); + ringbuffer_init(&i->audio_buffer); +#ifdef VERSION6 + WAVEFORMATEX wave; + i->astream -> GetOutputFormat(&wave, sizeof(wave)); + printf("formatinfo: format %d, %d channels, %d bits/sample, rate %d, blockalign %d\n", wave.wFormatTag, wave.nChannels, wave.wBitsPerSample, wave.nSamplesPerSec, wave.nBlockAlign); +#endif + } return 1; } @@ -390,6 +510,12 @@ int main (int argc,char ** argv) processargs(argc, argv); if(!filename) exit(0); + if(keyframe_interval<0) { + if(flashversion>=6) + keyframe_interval=200; + else + keyframe_interval=5; + } fi = fopen(outputfilename, "wb"); if(!fi) { @@ -418,20 +544,49 @@ int main (int argc,char ** argv) 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(expensive) v2swf_setparameter(&v2swf, "motioncompensation", "1"); - - char buffer[4096]; if(!verbose) printf("\n"); + + if(audio_adjust>0) { + int num = ((int)(audio_adjust*video.rate))*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