new parameter addspacechars
[swftools.git] / avi2swf / videoreader_avifile.cc
index 825d12a..371835d 100644 (file)
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <memory.h>
 #include "../config.h"
+#include "videoreader.h"
 
-extern "C" {
-#include "../lib/args.h"
-}
-#include "v2swf.h"
-#include "../lib/q.h"
+#ifdef HAVE_AVIFILE
 
 #undef HAVE_CONFIG_H
 
@@ -39,8 +39,8 @@ extern "C" {
 #if (AVIFILE_MAJOR_VERSION == 0) && (AVIFILE_MINOR_VERSION>=6) 
    #include <avifile.h>
    #include <aviplay.h>
-   #include <fourcc.h>
-   #include <creators.h>
+   #include <avm_fourcc.h>
+   #include <avm_creators.h>
    #include <StreamInfo.h>
    #define VERSION6
 #else
@@ -53,7 +53,17 @@ extern "C" {
    #define Bpp bpp
 #endif
 
-#include "videoreader.h"
+#ifdef HAVE_SIGNAL_H
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#include <signal.h>
+#define DO_SIGNALS
+#endif
+#endif
+
+#include "../lib/q.h"
+
+static int verbose = 0;
 
 typedef struct _videoreader_avifile_internal
 {
@@ -62,44 +72,69 @@ typedef struct _videoreader_avifile_internal
     IAviReadStream* vstream;
     int do_audio;
     int do_video;
-    int eof;
+    int video_eof;
+    int audio_eof;
+    int flip;
     int frame;
     int soundbits;
     ringbuffer_t audio_buffer;
 } videoreader_avifile_internal;
 
-static void readSamples(videoreader_avifile_internal*i, void*buffer, int buffer_size, int numsamples)
+static int readSamples(videoreader_avifile_internal*i, void*buffer, int buffer_size, int numsamples)
 {
     int ret;
     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;
+       if(ret!=0) {
+           if(verbose) {
+               printf("ReadFrames() returns %d\n", ret);fflush(stdout);
+           }
+       }
+       if(samples_read<=0) {
+           int l = i->audio_buffer.available; 
+           ringbuffer_read(&i->audio_buffer, buffer, l);
+           return l;
+       }
        ringbuffer_put(&i->audio_buffer, buffer, bytes_read);
     }
     ringbuffer_read(&i->audio_buffer, buffer, buffer_size);
+    return buffer_size;
 }
 static int videoreader_avifile_getsamples(videoreader_t* v, void*buffer, int num)
 {
+    videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
     if(verbose) {
        printf("videoreader_getsamples(%d)\n", num);fflush(stdout);
     }
-    videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
+    if(i->audio_eof)
+       return 0;
     if(i->soundbits == 8) {
-       readSamples(i, buffer, num/2, num/(v->channels*2));
+       int num_read = readSamples(i, buffer, num/2, num/(v->channels*2))*2;
        unsigned char*b = (unsigned char*)buffer;
        int t;
-       for(t=num-2;t>=0;t-=2) {
+       for(t=num_read-2;t>=0;t-=2) {
            unsigned char x = b[t/2];
            b[t] = 0;
            b[t+1] = x-128;
        }
-       return num;
+       if(!num_read) {
+           if(verbose) {
+               printf("end of audio\n");fflush(stdout);
+           }
+           i->audio_eof=1;
+       }
+       return num_read;
     }
     if(i->soundbits == 16) {
-       readSamples(i, buffer, num, num/(v->channels*2));
-       return num;
+       int num_read = readSamples(i, buffer, num, num/(v->channels*2));
+       if(!num_read)  {
+           if(verbose) {
+               printf("end of audio\n");fflush(stdout);
+           }
+           i->audio_eof=1;
+       }
+       return num_read;
     }
     return 0;
 }
@@ -110,22 +145,19 @@ static int videoreader_avifile_getimage(videoreader_t* v, void*buffer)
        printf("videoreader_getimage()\n");fflush(stdout);
     }
 
-    if(shutdown_avi2swf)
-       i->eof = 1;
-    
-    if(i->eof)
+    if(i->video_eof)
        return 0;
 
     if(i->vstream->ReadFrame() < 0) {
        if(verbose) printf("vstream->ReadFrame() returned value < 0, shutting down...\n");
-       i->eof = 1;
+       i->video_eof = 1;
        return 0;
     }
     CImage*img2 = 0;
     CImage*img = i->vstream->GetFrame();
     if(!img) {
        if(verbose) printf("vstream->GetFrame() returned NULL, shutting down...\n");
-       i->eof = 1;
+       i->video_eof = 1;
        return 0;
     }
     /* we convert the image to YUV first, because we can convert to RGB from YUV only */
@@ -138,8 +170,7 @@ static int videoreader_avifile_getimage(videoreader_t* v, void*buffer)
        img = img2;
     }
 
-
-    frameno++;
+    v->frame++;
     i->frame++;
     unsigned char*data = img->Data();
     int bpp = img->Bpp();
@@ -148,7 +179,7 @@ static int videoreader_avifile_getimage(videoreader_t* v, void*buffer)
        for(y=0;y<v->height;y++) {
            unsigned char*from,*to;
            to = &((unsigned char*)buffer)[y*v->width*4];
-           if(flip)
+           if(i->flip)
                from = img->At(v->height-y-1);
            else
                from = img->At(y);
@@ -164,17 +195,10 @@ static int videoreader_avifile_getimage(videoreader_t* v, void*buffer)
     } else {
        if(img2) delete img2;
        if(verbose) printf("Can't handle bpp %d, shutting down...\n", bpp);
+       i->video_eof = 1;
        return 0;
     }
 }
-static 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;
-}
 static void videoreader_avifile_close(videoreader_t* v)
 {
     videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
@@ -187,6 +211,13 @@ static void videoreader_avifile_close(videoreader_t* v)
 }
 static void videoreader_avifile_setparameter(videoreader_t*v, char*name, char*value)
 {
+    videoreader_avifile_internal*i = (videoreader_avifile_internal*)v->internal;
+    if(!strcmp(name, "verbose")) {
+       verbose = atoi(value);
+    }
+    if(!strcmp(name, "flip")) {
+       i->flip = atoi(value);
+    }
     if(verbose) {
        printf("videoreader_setparameter(%s, %s)\n", name, value);fflush(stdout);
     }
@@ -194,18 +225,21 @@ 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));
     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;
+    v->frame = 0;
     
     i->do_video = 1;
     i->do_audio = 1;
@@ -236,7 +270,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
@@ -246,14 +280,14 @@ int videoreader_avifile_open(videoreader_t* v, char* filename)
     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("width: %d\n", abs(head.dwWidth));
+    printf("height: %d\n", abs(head.dwHeight));
     printf("sound: %u samples (%f seconds)\n", i->astream->GetEndPos(), i->astream->GetEndTime());
-    v->width = head.dwWidth;
-    v->height = head.dwHeight;
+    v->width = abs(head.dwWidth);
+    v->height = abs(head.dwHeight);
     dwMicroSecPerFrame = head.dwMicroSecPerFrame;
     samplesperframe = astream->GetEndPos()/astream->GetEndTime()*head.dwMicroSecPerFrame/1000000;
-    v->rate = (int)(astream->GetEndPos()/astream->GetEndTime());
+    v->samplerate = (int)(astream->GetEndPos()/astream->GetEndTime());
     v->fps = 1000000.0/dwMicroSecPerFrame;
     i->soundbits = 16;
 #else
@@ -261,8 +295,8 @@ int videoreader_avifile_open(videoreader_t* v, char* filename)
     {
        StreamInfo*videoinfo;
        videoinfo = i->vstream->GetStreamInfo();
-       v->width = videoinfo->GetVideoWidth();
-       v->height = videoinfo->GetVideoHeight();
+       v->width = abs(videoinfo->GetVideoWidth());
+       v->height = abs(videoinfo->GetVideoHeight());
        v->fps = (double)(videoinfo->GetFps());
     }
     if(i->do_audio)
@@ -274,11 +308,11 @@ int videoreader_avifile_open(videoreader_t* v, char* filename)
        audioinfo = i->astream->GetStreamInfo();
 
        v->channels = wave.nChannels;
-       v->rate = wave.nSamplesPerSec;
+       v->samplerate = wave.nSamplesPerSec;
        i->soundbits = wave.wBitsPerSample;
 
-       if(v->channels==0 || v->rate==0 || i->soundbits==0 || wave.wFormatTag!=1) {
-           v->rate = audioinfo->GetAudioSamplesPerSec();
+       if(v->channels==0 || v->samplerate==0 || i->soundbits==0 || wave.wFormatTag!=1) {
+           v->samplerate = audioinfo->GetAudioSamplesPerSec();
            v->channels = audioinfo->GetAudioChannels();
            i->soundbits = audioinfo->GetAudioBitsPerSample();
        }
@@ -292,7 +326,7 @@ int videoreader_avifile_open(videoreader_t* v, char* filename)
            i->do_audio = 0;
            i->soundbits = 0;
            v->channels = 0;
-           v->rate = 0;
+           v->samplerate = 0;
        }
     }
 #endif
@@ -307,6 +341,14 @@ 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