Part of the swftools package.
- Copyright (c) 2001 Matthias Kramm <kramm@quiss.org>
+ Copyright (c) 2001,2002,2003 Matthias Kramm <kramm@quiss.org>
This file is distributed under the GPL, see file COPYING for details */
#include "../lib/args.h"
}
#include "v2swf.h"
+#include "../lib/q.h"
#undef HAVE_CONFIG_H
#include <avifile/version.h>
static double scale = 1.0;
static int flip = 0;
static int expensive = 0;
+static int flashversion = 6;
+static int keyframe_interval = -1;
+static int skip = 0;
+static float audio_adjust = 0;
struct options_t options[] =
{
{"v","verbose"},
+ {"A","adjust"},
{"o","output"},
{"p","flip"},
{"q","quality"},
- {"d","scale"},
+ {"s","scale"},
+ {"S","skip"},
{"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")) {
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, "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");
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-A , --adjust seconds\t Audio adjust: Shift sound -seconds to the future or +seconds into the past.\n");
printf("\t-n , --num frames\t Number of frames to encode\n");
printf("\t-d , --scale <val>\t Scale down to factor <val>. (in %, e.g. 100 = original size)\n");
printf("\t-p , --flip\t\t Turn movie upside down\n");
printf("\t-q , --quality <val>\t Set the quality to <val>. (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-T , --flashversion <n>\t Set output flash version to <n>. Notice: H.263 compression will only be\n");
+ printf("\t \t used for n >= 6.\n");
printf("\t-V , --version\t\t Print program version and exit\n");
exit(0);
}
int eof;
int frame;
int soundbits;
+ ringbuffer_t audio_buffer;
} videoreader_avifile_internal;
static int shutdown_avi2swf = 0;
}
#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) {
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;
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) {
+ /* TODO: this doesn't work yet */
+ if(verbose) printf("Can't handle Bpp %d, shutting down...\n", img->Bpp());
+ return 0;
+ BitmapInfo tmp(v->width, v->height, 24);
+ img2 = new CImage(img, &tmp);
+ img = img2;
+ }
+
+
frameno++;
i->frame++;
unsigned char*data = img->Data();
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;
}
}
void videoreader_avifile_close(videoreader_t* v)
{
videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
+ ringbuffer_clear(&i->audio_buffer);
if(verbose) {
printf("videoreader_close()\n");fflush(stdout);
}
v->getsamples = videoreader_avifile_getsamples;
v->setparameter = videoreader_avifile_setparameter;
v->internal = i;
-
+
i->do_video = 1;
i->do_audio = 1;
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();
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;
}
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) {
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", "32");
//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<num;t++) {
+ video.getimage(&video, buf);
+ }
+ free(buf);
+ }
+
+ if(skip) {
+ int t;
+ void*buf = malloc(video.width*video.height*4);
+ for(t=0;t<skip;t++) {
+ video.getimage(&video, buf);
+ video.getsamples(&video, buf, (int)((video.rate/video.fps)*video.channels*2));
+ if(!verbose) {
+ printf("\rSkipping frame %d", frameno);fflush(stdout);
+ }
+ }
+ free(buf);
+ }
+
+ char buffer[4096];
while(1) {
int l=v2swf_read(&v2swf, buffer, 4096);
fwrite(buffer, l, 1, fi);