//                              -*- Mode: C++ -*-
// avitype.cc -- Print info about a .AVI file
//
// $Id: avitype.cpp,v 1.4 2001/08/01 10:43:56 kabi Exp $
//
// Copyright (C) 2001  Tom Pavel <pavel@alum.mit.edu>
//
// Creator         : Tom Pavel  <tom>     Sat Feb  3 01:27:20 2001
// Modifier        : Tom Pavel  <tom>     Sun May 13 00:56:10 2001
// Update Count    : 34
// Status          : Unknown, Use with caution!
//



#include <avifile.h>
#include <aviplay.h>
#include <fourcc.h>
#include <except.h>
#include <utils.h>
#include <version.h>

#include <unistd.h>		// for getopt()

#include <iostream>
#include <iomanip>
#include <string>
#include <strstream.h>

using namespace std;

void printFile (const char* fname);
string fccToString (FOURCC fcc);

void Usage (const char* progname)
{
    cerr << "usage: " << progname
	 << " [-h] file1 file2 ..."
	 << endl;
    exit(1);
}

int main (int argc, char* argv[])
try
{
    int debug = 0;

    int ch;
    while ((ch = getopt(argc, argv, "dh:")) != EOF) {
	switch ((char)ch) {
	case 'd':
	    ++debug;
	    break;

	case 'h':
	case '?':
	default:
	    Usage (argv[0]);
	}
    }

    argc -= optind;
    argv += optind;
    if (argc < 1) Usage (argv[0]);


    // Standard AVIlib sanity check:
    if ( GetAvifileVersion() != AVIFILE_VERSION) {
	cout << "This binary was compiled for Avifile ver. "
	    << AVIFILE_VERSION
	    << ", but the library is ver. "
	    << GetAvifileVersion()
	    << ". Aborting."
	    << endl;
	return 0;
    }

    while (argc > 0) {
	printFile (*argv);
	--argc;
	++argv;
    }

}
catch(FatalError& error) {
    error.Print();
}

void printFile (const char* fname)
{
    IAviReadFile* aviFile = CreateIAviReadFile (fname);
    if (aviFile == 0)
	return;

    MainAVIHeader hdr;
    if (aviFile->GetHeader(&hdr, sizeof(hdr)) != 0)
	return;

    cout << endl;
    cout << "AVI file:    " << fname << endl;
    cout << "    Frames:  " << hdr.dwTotalFrames
	 << " of " << hdr.dwWidth << "x" << hdr.dwHeight << endl;
    cout << "    Rate:    " << setprecision(4)
	 << 1e6/hdr.dwMicroSecPerFrame << " frame/sec"
	 << " or " << hdr.dwMaxBytesPerSec*1e-3 << " kB/sec" << endl;
    cout << "    Streams: " << hdr.dwStreams << " ("
	 << aviFile->VideoStreamCount() << "V + "
	 << aviFile->AudioStreamCount() << "A)"
	 << endl;

    IAviReadStream* vidStream = aviFile->GetStream (0, AviStream::Video);
    if (vidStream == 0) {
	cout << "Bad Video Stream" << endl;
	return;
    }
    AVIStreamHeader header;
    vidStream->GetHeader(&header, sizeof(header));
    cout << "    Video:   " << fccToString(header.fccType)
	<< " " << fcc_type(header.fccHandler)
	<< endl;

    IAviReadStream* audStream = aviFile->GetStream (0, AviStream::Audio);
    if (audStream == 0) {
	cout << "Bad Audio Stream" << endl;
	return;
    }
    WAVEFORMATEX wvFmt;
    if (audStream->GetAudioFormatInfo(&wvFmt, 0) != 0) {
	cout << "Failed to decode Audio Format" << endl;
	return;
    }
    cout << "    Audio:   " << wave_type(wvFmt.wFormatTag)
	 << " " << wvFmt.wBitsPerSample << "-bit "
	 << wvFmt.nChannels << "-chan "
	 << wvFmt.nSamplesPerSec << " Hz" << endl;
}

string fccToString (fourcc_t fcc)
{
    if (fcc == 0)
	return string("0");

    char buf[32];
    ostrstream os(buf,sizeof(buf));

    for (int i=0; i < 4; ++i) {
	char c = ((fcc >> (i*8)) & 0xff);
	os << c;
    }
    os << ends;
    return string(buf);
}
