From 91848889de64a4efacc5930c2109f96fb6ed1146 Mon Sep 17 00:00:00 2001 From: kramm Date: Mon, 20 Sep 2004 16:14:56 +0000 Subject: [PATCH] added codec query. --- avi2swf/videoreader_avifile.cc | 19 ++- avi2swf/videoreader_vfw.cc | 336 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 353 insertions(+), 2 deletions(-) diff --git a/avi2swf/videoreader_avifile.cc b/avi2swf/videoreader_avifile.cc index 0cd2599..42e6b72 100644 --- a/avi2swf/videoreader_avifile.cc +++ b/avi2swf/videoreader_avifile.cc @@ -24,6 +24,8 @@ #include #include "../config.h" +#ifdef HAVE_AVIFILE + #undef HAVE_CONFIG_H #ifdef HAVE_VERSION_H @@ -210,6 +212,10 @@ static void videoreader_avifile_setparameter(videoreader_t*v, char*name, char*va int videoreader_avifile_open(videoreader_t* v, char* filename) { + if(!filename) { + /* codec query */ + return 0; + } videoreader_avifile_internal* i; i = (videoreader_avifile_internal*)malloc(sizeof(videoreader_avifile_internal)); memset(i, 0, sizeof(videoreader_avifile_internal)); @@ -252,7 +258,7 @@ int videoreader_avifile_open(videoreader_t* v, char* filename) if(!i->do_video && !i->do_audio) { printf("File has neither audio nor video streams.(?)\n"); - return 0; + return -1; } #ifndef VERSION6 @@ -323,6 +329,15 @@ int videoreader_avifile_open(videoreader_t* v, char* filename) #endif } - return 1; + return 0; +} + +#else //HAVE_AVIFILE + + +int videoreader_avifile_open(videoreader_t* v, char* filename) +{ + return -1; } +#endif //HAVE_AVIFILE diff --git a/avi2swf/videoreader_vfw.cc b/avi2swf/videoreader_vfw.cc index e69de29..2c2f809 100644 --- a/avi2swf/videoreader_vfw.cc +++ b/avi2swf/videoreader_vfw.cc @@ -0,0 +1,336 @@ +/* videoreader_vfw.cc + Read avi files using Video For Windows (vfw). + + Part of the swftools package. + + Copyright (c) 2004 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 */ + +#ifdef WIN32 +#include +#include +#include +#include +#include "videoreader.h" + +typedef struct _videoreader_vfw_internal { + //video: + PAVISTREAM vs; + //audio: + PAVISTREAM as; + + PGETFRAME getframe; + IAVIFile* avifile; + BITMAPINFOHEADER bitmap; + WAVEFORMATEX waveformat; + + int video_pos; + int video_end; + + int audio_pos; + int audio_end; + + float fps; + int width,height; + + int samplerate; + int channels; + +} videoreader_vfw_internal_t; + +bool videoreader_vfw_eof(videoreader_t* vr) +{ + videoreader_vfw_internal_t* i = (videoreader_vfw_internal_t*)vr->internal; + return (i->video_pos >= i->video_end); +} + +static int bitmap_to_rgba(BITMAPINFOHEADER*bi, void*buffer, const int dest_width, const int dest_height) +{ + UCHAR*data = (UCHAR*)(bi+1); // actual bitmap data starts after the header + + if(bi->biPlanes!=1 || bi->biCompression!=0 || bi->biBitCount%4!=0) { + /* unsupported format */ + fprintf(stderr, "bitmap_to_rgba: unsupported format: biPlanes=%d, biCompression=%d biBitCount=%d\n", + bi->biPlanes, bi->biCompression, bi->biBitCount); + return 0; + } + + ULONG*dest = (ULONG*)buffer; + + int width = bi->biWidth; + int height = bi->biHeight; + if(dest_width != width || dest_height != height) { + /* TODO: size conversion */ + fprintf(stderr, "size mismatch: %dx%d != %dx%d\n", width, height, dest_width, dest_height); + return 0; + } + + /* convert the various image types to RGBA- + TODO: is there some way to let the Windows API do this? */ + int bytesperpixel = ((bi->biWidth*bi->biBitCount)+7)&~7; + int linex = ((bytesperpixel/8)+3)&~3; + memset(dest, 255, dest_width*dest_height*4);//pre-fill alpha channel + if(bi->biBitCount==1) { + int y; + UCHAR*img = data; + for(y=0;y>(x&7))&1); + } + } + } else if(bi->biBitCount==4) { + int y; + UCHAR*img = &data[bi->biClrUsed*4]; + UCHAR*pal = data; + for(y=0;y>4)<<2|0]<<8|pal[(line[0]>>4)<<2|1]<<16|pal[(line[0]>>4)<<2|2]<<24; + *dest++ = 255|pal[(line[0]&0x0f)<<2|0]<<8|pal[(line[0]&0x0f)<<2|1]<<16|pal[(line[0]&0x0f)<<2|2]<<24; + line++; + } + } + } else if(bi->biBitCount==8) { + int y; + UCHAR*img = &data[bi->biClrUsed*4]; + UCHAR*pal = data; + for(y=0;ybiBitCount==24) { + UCHAR*img = data; + int y; + for(y=0;ybiBitCount==32) { + UCHAR*img = data; + int y; + for(y=0;ybiBitCount); + return 0; + } + return 1; +} + +int videoreader_vfw_getimage(videoreader_t* vr, void*buffer) +{ + videoreader_vfw_internal_t* i = (videoreader_vfw_internal_t*)vr->internal; + + if(videoreader_vfw_eof(vr)) + return 0; + + LPBITMAPINFOHEADER bi; + bi = (LPBITMAPINFOHEADER)AVIStreamGetFrame(i->getframe, i->video_pos); + + i->video_pos++; + + if(!bi) { + fprintf(stderr, "AVIStreamGetFrame failed\n"); + return 0; + } + printf("%dx%d:%d\n", bi->biWidth, bi->biHeight, bi->biBitCount); + + if(!bitmap_to_rgba(bi, buffer, i->width, i->height)) { + fprintf(stderr, "couldn't convert bitmap to RGBA.\n"); + return 0; + } + return i->width*i->height*4; +} + +static int readAudioBlock(videoreader_vfw_internal_t* i, void*buf, int len) +{ + LONG bytes; + LONG samples; + AVIStreamRead(i->as, i->audio_pos, len/(2*i->waveformat.nChannels), buf, len, &bytes, &samples); + i->audio_pos += samples; + return bytes; +} + +int videoreader_vfw_getsamples(videoreader_t* vr, void*buf, int num) +{ + videoreader_vfw_internal_t* i = (videoreader_vfw_internal_t*)vr->internal; + + switch(i->waveformat.wBitsPerSample) { + case 1: { + int len = readAudioBlock(i, buf, num); + int t = len-1; + do { + ((SHORT*)buf)[t] = ((((BYTE*)buf)[t>>3])>>(t&7))<<15; + } while(--t>=0); + return len*8; + } + case 8: { + int len = readAudioBlock(i, buf, num); + int t = len-1; + do { + ((SHORT*)buf)[t] = (((BYTE*)buf)[t]<<8)^0x8000; + } while(--t>=0); + return len*2; + } + case 16: { + return readAudioBlock(i, buf, num); + } + default: { + return 0; + } + } +} + +void videoreader_vfw_close(videoreader_t* vr) +{ + videoreader_vfw_internal_t* i = (videoreader_vfw_internal_t*)vr->internal; + + AVIStreamGetFrameClose(i->getframe); + if(i->vs) { + AVIStreamRelease(i->vs); i->vs = 0; + } + if(i->as) { + AVIStreamRelease(i->as); i->vs = 0; + } + AVIFileRelease(i->avifile); i->avifile = 0; + AVIFileExit(); + + free(vr->internal); vr->internal = 0; +} + +void videoreader_vfw_setparameter(videoreader_t* vr, char*name, char*value) {} + +int videoreader_vfw_open(videoreader_t* vr, char* filename) +{ + memset(vr, 0, sizeof(videoreader_t)); + if(!filename) { + /* codec query */ + return 1; + } + + videoreader_vfw_internal_t* i = (videoreader_vfw_internal_t*)malloc(sizeof(videoreader_vfw_internal_t)); + memset(i, 0, sizeof(videoreader_vfw_internal_t)); + + vr->internal = i; + vr->eof = videoreader_vfw_eof; + vr->getimage = videoreader_vfw_getimage; + vr->getsamples = videoreader_vfw_getsamples; + vr->close = videoreader_vfw_close; + vr->setparameter = videoreader_vfw_setparameter; + + AVIFileInit(); + if(AVIFileOpen(&i->avifile, filename, OF_SHARE_DENY_WRITE, 0)) { + fprintf(stderr, "Couldn't open %s\n", filename); + return -1; + } + AVIFILEINFO info; + AVIFileInfo(i->avifile, &info, sizeof(info)); + + /* calculate framerate */ + i->fps = (double)info.dwRate/(double)info.dwScale; + + unsigned int t; + while(tavifile, &stream, streamtypeANY, t) != AVIERR_OK || !stream) + break; //video_end of (working) streams + + AVISTREAMINFO streaminfo; + AVIStreamInfo(stream, &streaminfo, sizeof(streaminfo)); + + if (streaminfo.fccType == streamtypeVIDEO) { + /* video stream */ + + BITMAPINFOHEADER bitmap; + LONG size = sizeof(i->bitmap); + AVIStreamReadFormat(i->vs, 0, &bitmap, &size); + + if(i->bitmap.biCompression == 0/*RGB*/) { + i->bitmap = bitmap; + i->vs = stream; + i->width = bitmap.biWidth; + i->height = bitmap.biHeight; + } + } + else if (streaminfo.fccType == streamtypeAUDIO) { + /* audio stream */ + + WAVEFORMATEX waveformat; + LONG size = sizeof(i->waveformat); + AVIStreamReadFormat(i->as, 0, &waveformat, &size); + + if(i->waveformat.wBitsPerSample == 16 || i->waveformat.wBitsPerSample == 8) { + i->waveformat = waveformat; + i->as = stream; + i->channels = i->waveformat.nChannels; + i->samplerate = i->waveformat.nSamplesPerSec; + } + } + } + + if(i->vs) { + vr->width = i->width; + vr->height = i->height; + vr->fps = i->fps; + } else { + fprintf(stderr, "AVIReader: Warning: No video stream\n"); + } + if(i->as) { + vr->channels = i->channels; + vr->samplerate = i->samplerate; + } else { + fprintf(stderr, "AVIReader: Warning: No audio stream\n"); + } + + i->getframe = AVIStreamGetFrameOpen(i->vs, 0); + if(!i->getframe) { + return -1; + } + + i->video_pos = AVIStreamStart(i->vs); + i->video_end = AVIStreamEnd(i->vs); + i->audio_pos = 0; + i->audio_end = 0x7fffffff; + + return 0; +} + +#else //WIN32 + +int videoreader_vfw_open(videoreader_t* vr, char* filename) +{ + return -1; +} + +#endif //WIN32 + -- 1.7.10.4