X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=avi2swf%2Fv2swf.c;h=db32c0c762aae0962ed7acdf4336a75c30bbc9df;hb=5f258d914bd49400899ad22d4f043fb2de278b6b;hp=c56ff4b6237219b12badb7b92e35453ff83c68ef;hpb=e5b314a4315a7d7e0b7bda60102c50ad277c2f68;p=swftools.git diff --git a/avi2swf/v2swf.c b/avi2swf/v2swf.c index c56ff4b..db32c0c 100644 --- a/avi2swf/v2swf.c +++ b/avi2swf/v2swf.c @@ -39,10 +39,14 @@ typedef struct _v2swf_internal_t ringbuffer_t r; videoreader_t* video; + double video_fps; int width; int height; + int video_eof; + int audio_eof; + unsigned char* vrbuffer; unsigned char* buffer; unsigned char* lastbitmap; @@ -60,6 +64,7 @@ typedef struct _v2swf_internal_t float fpspos; int bitrate; + int samplerate; int finished; int keyframe; @@ -118,6 +123,12 @@ static void msg(char*format, ...) fflush(stdout); } +extern int swf_mp3_in_samplerate; +extern int swf_mp3_out_samplerate; +extern int swf_mp3_channels; +extern int swf_mp3_bitrate; + + static void writeShape(v2swf_internal_t*i, int id, int gfxid, int width, int height) { RGBA rgb; @@ -158,18 +169,24 @@ static void writeShape(v2swf_internal_t*i, int id, int gfxid, int width, int hei swf_ShapeFree(shape); } +/* returns 0 on partial read */ static int getSamples(videoreader_t*video, S16*data, int len, double speedup) { double pos = 0; - double ratio = video->rate * speedup / 44100.0; + double ratio = (double) video->samplerate * speedup / swf_mp3_in_samplerate; int rlen = (int)(len * ratio); int t; S16 tmp[576*32]; int r = /*resampled len */ rlen * /* s16_le */ 2 * video->channels; - if(videoreader_getsamples(video, tmp, r) < r) + int l; + memset(tmp, 0, sizeof(tmp)); + l = videoreader_getsamples(video, tmp, r); + if(l <= 0) { return 0; + } + msg("%d samples read", l); /* convert to 1 channel */ for(t=0;tchannels; } - /* down/up-sample to 44khz */ + /* down/up-sample to the desired input samplerate (swf_mp3_in_samplerate) */ for(t=0;tvideo->channels<=0 || i->video->rate<=0) + if(i->audio_eof || i->video->channels<=0 || i->video->samplerate<=0) { + i->audio_eof = 1; return; /* no sound in video */ + } - blocksize = 576; /* 11khz samples per mp3 block */ - blockspersecond = 11025.0/blocksize; + blocksize = (i->samplerate > 22050) ? 1152 : 576; + blockspersecond = ((double)i->samplerate)/blocksize; /* notice: for framerates greater than about 35, audio starts getting choppy. */ framespersecond = i->framerate; @@ -221,6 +237,12 @@ static void writeAudioForOneFrame(v2swf_internal_t* i) msg("samplesperblock: %f", samplesperblock); if(!i->soundstreamhead) { + swf_mp3_out_samplerate = i->samplerate; + /* The pre-processing of sound samples in getSamples(..) above + re-samples the sound to swf_mp3_in_samplerate. It is best to + simply make it the original samplerate: */ + swf_mp3_in_samplerate = i->video->samplerate; + /* first run - initialize */ swf_mp3_channels = 1;//i->video->channels; swf_mp3_bitrate = i->bitrate; @@ -257,9 +279,10 @@ static void writeAudioForOneFrame(v2swf_internal_t* i) /* write num frames, max 1 block */ for(pos=0;posvideo, block1, 576*4, speedup)) { /* 4 = 44100/11025 */ - i->video->rate = i->video->channels = 0; //end of soundtrack - return; + if(!getSamples(i->video, block1, blocksize * (double)swf_mp3_in_samplerate/swf_mp3_out_samplerate, speedup)) { + i->audio_eof = 1; i->video->samplerate = i->video->channels = 0; //end of soundtrack + /* fall through, this probably was a partial read. (We did, after all, + come to this point, so i->audio_eof must have been false so far) */ } if(!pos) { swf_ResetTag(i->tag, ST_SOUNDSTREAMBLOCK); @@ -549,6 +572,11 @@ static void scaleimage(v2swf_internal_t*i) int xv,yv; int xm = (i->video->width*65536)/i->width; int ym = (i->video->height*65536)/i->height; + msg("scaling from %dx%d to %dx%d\n", + i->video->width, i->video->height, + i->width, i->height + ); + memset(i->buffer, 255, i->width*i->height*4); for(y=0,yv=0;yheight;y++,yv+=ym) { int*src = &((int*)i->vrbuffer)[(yv>>16)*i->video->width]; @@ -560,6 +588,20 @@ static void scaleimage(v2swf_internal_t*i) //memcpy(i->buffer, i->vrbuffer, i->width*i->height*4); } +static int writeAudioOnly(v2swf_internal_t*i) +{ + if(i->showframe) { + i->fpspos += i->fpsratio; + /* skip frames */ + if(i->fpspos<1.0) { + return 0; + } + writeShowFrame(i); + } + i->showframe = 1; + return 1; +} + static int encodeoneframe(v2swf_internal_t*i) { videoreader_t*video = i->video; @@ -567,27 +609,38 @@ static int encodeoneframe(v2swf_internal_t*i) checkInit(i); - if(videoreader_eof(i->video) || !videoreader_getimage(i->video, i->vrbuffer)) - { - msg("videoreader returned eof\n"); - finish(i); + if(i->video_eof && i->audio_eof) { + if(!i->finished) + finish(i); return 0; } - i->fpspos += i->fpsratio; + if(!i->audio_eof && i->video_eof) { + return writeAudioOnly(i); + } - /* skip frames */ - if(i->fpspos<1.0) { - return 0; + if(!videoreader_getimage(i->video, i->vrbuffer)) + { + i->video_eof = 1; + msg("videoreader returned eof\n"); + if(i->audio_eof) { + finish(i); + return 0; + } else { + return writeAudioOnly(i); + } } - - msg("encoding image for frame %d\n", i->frames); - if(i->showframe) + msg("encoding image for frame %d\n", i->frames); + if(i->showframe) { + i->fpspos += i->fpsratio; + /* skip frames */ + if(i->fpspos<1.0) { + return 0; + } writeShowFrame(i); - - msg("scaling\n"); - + } + scaleimage(i); msg("version is %d\n", i->version); @@ -777,17 +830,19 @@ int v2swf_init(v2swf_t*v2swf, videoreader_t * video) msg("video: %dx%d, fps %f\n", video->width, video->height, video->fps); i->video = video; + i->video_fps = ((int)(video->fps*256))/256.0; i->blockdiff = 64; i->keyframe_interval = 8; i->quality = 20; i->scale = 65536; + i->samplerate = 11025; i->prescale = 0; i->head_done = 0; i->diffmode = DIFFMODE_QMEAN; i->audio_fix = 1.0; i->fixheader = 0; - i->framerate = video->fps; - i->fpsratio = 1.00000000; + i->framerate = i->video_fps; + i->fpsratio = 1.00000000000; i->fpspos = 0.0; i->bitrate = 32; i->version = 6; @@ -875,9 +930,11 @@ void v2swf_setparameter(v2swf_t*v2swf, char*name, char*value) i->blockdiff = atoi(value); } else if(!strcmp(name, "fixheader")) { i->fixheader = atoi(value); + } else if(!strcmp(name, "samplerate")) { + i->samplerate = atoi(value); } else if(!strcmp(name, "framerate")) { i->framerate = atof(value); - i->fpsratio = i->framerate / i->video->fps; + i->fpsratio = i->framerate / i->video_fps; } else if(!strcmp(name, "mp3_bitrate")) { int t=0,o; @@ -959,29 +1016,6 @@ void v2swf_backpatch(v2swf_t*v2swf, char*filename) } } -float v2swf_getprogress(v2swf_t*v2swf) -{ - float* p; - v2swf_internal_t* i; - msg("v2swf_getprogress()"); - if(!v2swf || !v2swf->internal) { - return 0.0; - } - i = (v2swf_internal_t*)v2swf->internal; - - p = (float*)videoreader_getinfo(i->video, "position"); - - if(p) { - return *p; - } else { - float f = i->frames/1500.0; /*fake*/ - if(f>1.0) - return 1.0; - else - return f; - } -} - void v2swf_setvideoparameter(videoreader_t*v, char*name, char*value) { msg("v2swf_setvideoparameter()");