/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)

This library 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 Lesser General Public License for
more details.

You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc.  All rights reserved.
// A sink that generates an AVI file from a composite media session
// Implementation

#include "AVIFileSink.hh"
#include "InputFile.hh"
#include "OutputFile.hh"
#include "GroupsockHelper.hh"

#define fourChar(x,y,z,w) ( ((w)<<24)|((z)<<16)|((y)<<8)|(x) )/*little-endian*/

#define AVIIF_LIST		0x00000001
#define AVIIF_KEYFRAME		0x00000010
#define AVIIF_NO_TIME		0x00000100
#define AVIIF_COMPRESSOR	0x0FFF0000

////////// AVISubsessionIOState ///////////
// A structure used to represent the I/O state of each input 'subsession':

class SubsessionBuffer {
public:
  SubsessionBuffer(unsigned bufferSize)
    : fBufferSize(bufferSize) {
    reset();
    fData = new unsigned char[bufferSize];
  }
  virtual ~SubsessionBuffer() { delete[] fData; }
  void reset() { fBytesInUse = 0; }
  void addBytes(unsigned numBytes) { fBytesInUse += numBytes; }

  unsigned char* dataStart() { return &fData[0]; }
  unsigned char* dataEnd() { return &fData[fBytesInUse]; }
  unsigned bytesInUse() const { return fBytesInUse; }
  unsigned bytesAvailable() const { return fBufferSize - fBytesInUse; }

  void setPresentationTime(struct timeval const& presentationTime) {
    fPresentationTime = presentationTime;
  }
  struct timeval const& presentationTime() const {return fPresentationTime;}

private:
  unsigned fBufferSize;
  struct timeval fPresentationTime;
  unsigned char* fData;
  unsigned fBytesInUse;
};

class AVISubsessionIOState {
public:
  AVISubsessionIOState(AVIFileSink& sink, MediaSubsession& subsession);
  virtual ~AVISubsessionIOState();

  void setAVIstate(unsigned subsessionIndex);
  void setFinalAVIstate();

  void afterGettingFrame(unsigned packetDataSize,
			 struct timeval presentationTime);
  void onSourceClosure();

  UsageEnvironment& envir() const { return fOurSink.envir(); }

public:
  SubsessionBuffer *fBuffer, *fPrevBuffer;
  AVIFileSink& fOurSink;
  MediaSubsession& fOurSubsession;

  unsigned short fLastPacketRTPSeqNum;
  Boolean fOurSourceIsActive;
  struct timeval fPrevPresentationTime;
  unsigned fMaxBytesPerSecond;
  Boolean fIsVideo, fIsAudio, fIsByteSwappedAudio;
  unsigned fAVISubsessionTag;
  unsigned fAVICodecHandlerType;
  unsigned fAVISamplingFrequency; // for audio
  u_int16_t fWAVCodecTag; // for audio
  unsigned fAVIScale;
  unsigned fAVIRate;
  unsigned fAVISize;
  unsigned fNumFrames;
  unsigned fSTRHFrameCountPosition;

private:
  void useFrame(SubsessionBuffer& buffer);
};


///////// AVIIndexRecord definition & implementation //////////

class AVIIndexRecord {
public:
  AVIIndexRecord(unsigned chunkId, unsigned flags, unsigned offset, unsigned size)
    : fNext(NULL), fChunkId(chunkId), fFlags(flags), fOffset(offset), fSize(size) {
  }

  AVIIndexRecord*& next() { return fNext; }
  unsigned chunkId() const { return fChunkId; }
  unsigned flags() const { return fFlags; }
  unsigned offset() const { return fOffset; }
  unsigned size() const { return fSize; }

private:
  AVIIndexRecord* fNext;
  unsigned fChunkId;
  unsigned fFlags;
  unsigned fOffset;
  unsigned fSize;
};


////////// AVIFileSink implementation //////////

AVIFileSink::AVIFileSink(UsageEnvironment& env,
			 MediaSession& inputSession,
			 char const* outputFileName,
			 unsigned bufferSize,
			 unsigned short movieWidth, unsigned short movieHeight,
			 unsigned movieFPS, Boolean packetLossCompensate)
  : Medium(env), fInputSession(inputSession),
    fIndexRecordsHead(NULL), fIndexRecordsTail(NULL), fNumIndexRecords(0),
    fBufferSize(bufferSize), fPacketLossCompensate(packetLossCompensate),
    fAreCurrentlyBeingPlayed(False), fNumSubsessions(0), fNumBytesWritten(0),
    fHaveCompletedOutputFile(False),
    fMovieWidth(movieWidth), fMovieHeight(movieHeight), fMovieFPS(movieFPS) {
  fOutFid = OpenOutputFile(env, outputFileName);
  if (fOutFid == NULL) return;

  // Set up I/O state for each input subsession:
  MediaSubsessionIterator iter(fInputSession);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    // Ignore subsessions without a data source:
    FramedSource* subsessionSource = subsession->readSource();
    if (subsessionSource == NULL) continue;

    // If "subsession's" SDP description specified screen dimension
    // or frame rate parameters, then use these.
    if (subsession->videoWidth() != 0) {
      fMovieWidth = subsession->videoWidth();
    }
    if (subsession->videoHeight() != 0) {
      fMovieHeight = subsession->videoHeight();
    }
    if (subsession->videoFPS() != 0) {
      fMovieFPS = subsession->videoFPS();
    }

    AVISubsessionIOState* ioState
      = new AVISubsessionIOState(*this, *subsession);
    subsession->miscPtr = (void*)ioState;

    // Also set a 'BYE' handler for this subsession's RTCP instance:
    if (subsession->rtcpInstance() != NULL) {
      subsession->rtcpInstance()->setByeHandler(onRTCPBye, ioState);
    }

    ++fNumSubsessions;
  }

  // Begin by writing an AVI header:
  addFileHeader_AVI();
}

AVIFileSink::~AVIFileSink() {
  completeOutputFile();

  // Then, stop streaming and delete each active "AVISubsessionIOState":
  MediaSubsessionIterator iter(fInputSession);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    if (subsession->readSource() != NULL) subsession->readSource()->stopGettingFrames();

    AVISubsessionIOState* ioState
      = (AVISubsessionIOState*)(subsession->miscPtr);
    if (ioState == NULL) continue;

    delete ioState;
  }

  // Then, delete the index records:
  AVIIndexRecord* cur = fIndexRecordsHead;
  while (cur != NULL) {
    AVIIndexRecord* next = cur->next();
    delete cur;
    cur = next;
  }

  // Finally, close our output file:
  CloseOutputFile(fOutFid);
}

AVIFileSink* AVIFileSink
::createNew(UsageEnvironment& env, MediaSession& inputSession,
	    char const* outputFileName,
	    unsigned bufferSize,
	    unsigned short movieWidth, unsigned short movieHeight,
	    unsigned movieFPS, Boolean packetLossCompensate) {
  AVIFileSink* newSink =
    new AVIFileSink(env, inputSession, outputFileName, bufferSize,
		    movieWidth, movieHeight, movieFPS, packetLossCompensate);
  if (newSink == NULL || newSink->fOutFid == NULL) {
    Medium::close(newSink);
    return NULL;
  }

  return newSink;
}

Boolean AVIFileSink::startPlaying(afterPlayingFunc* afterFunc,
				  void* afterClientData) {
  // Make sure we're not already being played:
  if (fAreCurrentlyBeingPlayed) {
    envir().setResultMsg("This sink has already been played");
    return False;
  }

  fAreCurrentlyBeingPlayed = True;
  fAfterFunc = afterFunc;
  fAfterClientData = afterClientData;

  return continuePlaying();
}

Boolean AVIFileSink::continuePlaying() {
  // Run through each of our input session's 'subsessions',
  // asking for a frame from each one:
  Boolean haveActiveSubsessions = False;
  MediaSubsessionIterator iter(fInputSession);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    FramedSource* subsessionSource = subsession->readSource();
    if (subsessionSource == NULL) continue;

    if (subsessionSource->isCurrentlyAwaitingData()) continue;

    AVISubsessionIOState* ioState
      = (AVISubsessionIOState*)(subsession->miscPtr);
    if (ioState == NULL) continue;

    haveActiveSubsessions = True;
    unsigned char* toPtr = ioState->fBuffer->dataEnd();
    unsigned toSize = ioState->fBuffer->bytesAvailable();
    subsessionSource->getNextFrame(toPtr, toSize,
				   afterGettingFrame, ioState,
				   onSourceClosure, ioState);
  }
  if (!haveActiveSubsessions) {
    envir().setResultMsg("No subsessions are currently active");
    return False;
  }

  return True;
}

void AVIFileSink
::afterGettingFrame(void* clientData, unsigned packetDataSize,
		    unsigned numTruncatedBytes,
		    struct timeval presentationTime,
		    unsigned /*durationInMicroseconds*/) {
  AVISubsessionIOState* ioState = (AVISubsessionIOState*)clientData;
  if (numTruncatedBytes > 0) {
    ioState->envir() << "AVIFileSink::afterGettingFrame(): The input frame data was too large for our buffer.  "
		     << numTruncatedBytes
		     << " bytes of trailing data was dropped!  Correct this by increasing the \"bufferSize\" parameter in the \"createNew()\" call.\n";
  }
  ioState->afterGettingFrame(packetDataSize, presentationTime);
}

void AVIFileSink::onSourceClosure(void* clientData) {
  AVISubsessionIOState* ioState = (AVISubsessionIOState*)clientData;
  ioState->onSourceClosure();
}

void AVIFileSink::onSourceClosure1() {
  // Check whether *all* of the subsession sources have closed.
  // If not, do nothing for now:
  MediaSubsessionIterator iter(fInputSession);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    AVISubsessionIOState* ioState
      = (AVISubsessionIOState*)(subsession->miscPtr);
    if (ioState == NULL) continue;

    if (ioState->fOurSourceIsActive) return; // this source hasn't closed
  }

  completeOutputFile();

  // Call our specified 'after' function:
  if (fAfterFunc != NULL) {
    (*fAfterFunc)(fAfterClientData);
  }
}

void AVIFileSink::onRTCPBye(void* clientData) {
  AVISubsessionIOState* ioState = (AVISubsessionIOState*)clientData;

  struct timeval timeNow;
  gettimeofday(&timeNow, NULL);
  unsigned secsDiff
    = timeNow.tv_sec - ioState->fOurSink.fStartTime.tv_sec;

  MediaSubsession& subsession = ioState->fOurSubsession;
  ioState->envir() << "Received RTCP \"BYE\" on \""
		   << subsession.mediumName()
		   << "/" << subsession.codecName()
		   << "\" subsession (after "
		   << secsDiff << " seconds)\n";

  // Handle the reception of a RTCP "BYE" as if the source had closed:
  ioState->onSourceClosure();
}

void AVIFileSink::addIndexRecord(AVIIndexRecord* newIndexRecord) {
  if (fIndexRecordsHead == NULL) {
    fIndexRecordsHead = newIndexRecord;
  } else {
    fIndexRecordsTail->next() = newIndexRecord;
  }
  fIndexRecordsTail = newIndexRecord;
  ++fNumIndexRecords;
}

void AVIFileSink::completeOutputFile() {
  if (fHaveCompletedOutputFile || fOutFid == NULL) return;

  // Update various AVI 'size' fields to take account of the codec data that
  // we've now written to the file:
  unsigned maxBytesPerSecond = 0;
  unsigned numVideoFrames = 0;
  unsigned numAudioFrames = 0;

  //// Subsession-specific fields:
  MediaSubsessionIterator iter(fInputSession);
  MediaSubsession* subsession;
  while ((subsession = iter.next()) != NULL) {
    AVISubsessionIOState* ioState
      = (AVISubsessionIOState*)(subsession->miscPtr);
    if (ioState == NULL) continue;

    maxBytesPerSecond += ioState->fMaxBytesPerSecond;

    setWord(ioState->fSTRHFrameCountPosition, ioState->fNumFrames);
    if (ioState->fIsVideo) numVideoFrames = ioState->fNumFrames;
    else if (ioState->fIsAudio) numAudioFrames = ioState->fNumFrames;
  }

  //// Global fields:
  add4ByteString("idx1");
  addWord(fNumIndexRecords*4*4); // the size of all of the index records, which come next:
  for (AVIIndexRecord* indexRecord = fIndexRecordsHead; indexRecord != NULL; indexRecord = indexRecord->next()) {
    addWord(indexRecord->chunkId());
    addWord(indexRecord->flags());
    addWord(indexRecord->offset());
    addWord(indexRecord->size());
  }

  fRIFFSizeValue += fNumBytesWritten + fNumIndexRecords*4*4 - 4;
  setWord(fRIFFSizePosition, fRIFFSizeValue);

  setWord(fAVIHMaxBytesPerSecondPosition, maxBytesPerSecond);
  setWord(fAVIHFrameCountPosition,
	  numVideoFrames > 0 ? numVideoFrames : numAudioFrames);

  fMoviSizeValue += fNumBytesWritten;
  setWord(fMoviSizePosition, fMoviSizeValue);

  // We're done:
  fHaveCompletedOutputFile = True;
}


////////// AVISubsessionIOState implementation ///////////

AVISubsessionIOState::AVISubsessionIOState(AVIFileSink& sink,
				     MediaSubsession& subsession)
  : fOurSink(sink), fOurSubsession(subsession),
    fMaxBytesPerSecond(0), fIsVideo(False), fIsAudio(False), fIsByteSwappedAudio(False), fNumFrames(0) {
  fBuffer = new SubsessionBuffer(fOurSink.fBufferSize);
  fPrevBuffer = sink.fPacketLossCompensate
    ? new SubsessionBuffer(fOurSink.fBufferSize) : NULL;

  FramedSource* subsessionSource = subsession.readSource();
  fOurSourceIsActive = subsessionSource != NULL;

  fPrevPresentationTime.tv_sec = 0;
  fPrevPresentationTime.tv_usec = 0;
}

AVISubsessionIOState::~AVISubsessionIOState() {
  delete fBuffer; delete fPrevBuffer;
}

void AVISubsessionIOState::setAVIstate(unsigned subsessionIndex) {
  fIsVideo = strcmp(fOurSubsession.mediumName(), "video") == 0;
  fIsAudio = strcmp(fOurSubsession.mediumName(), "audio") == 0;

  if (fIsVideo) {
    fAVISubsessionTag
      = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'d','c');
    if (strcmp(fOurSubsession.codecName(), "JPEG") == 0) {
      fAVICodecHandlerType = fourChar('m','j','p','g');
    } else if (strcmp(fOurSubsession.codecName(), "MP4V-ES") == 0) {
      fAVICodecHandlerType = fourChar('D','I','V','X');
    } else if (strcmp(fOurSubsession.codecName(), "MPV") == 0) {
      fAVICodecHandlerType = fourChar('m','p','g','1'); // what about MPEG-2?
    } else if (strcmp(fOurSubsession.codecName(), "H263-1998") == 0 ||
	       strcmp(fOurSubsession.codecName(), "H263-2000") == 0) {
      fAVICodecHandlerType = fourChar('H','2','6','3');
    } else if (strcmp(fOurSubsession.codecName(), "H264") == 0) {
      fAVICodecHandlerType = fourChar('H','2','6','4');
    } else {
      fAVICodecHandlerType = fourChar('?','?','?','?');
    }
    fAVIScale = 1; // ??? #####
    fAVIRate = fOurSink.fMovieFPS; // ??? #####
    fAVISize = fOurSink.fMovieWidth*fOurSink.fMovieHeight*3; // ??? #####
  } else if (fIsAudio) {
    fIsByteSwappedAudio = False; // by default
    fAVISubsessionTag
      = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'w','b');
    fAVICodecHandlerType = 1; // ??? ####
    unsigned numChannels = fOurSubsession.numChannels();
    fAVISamplingFrequency = fOurSubsession.rtpTimestampFrequency(); // default
    if (strcmp(fOurSubsession.codecName(), "L16") == 0) {
      fIsByteSwappedAudio = True; // need to byte-swap data before writing it
      fWAVCodecTag = 0x0001;
      fAVIScale = fAVISize = 2*numChannels; // 2 bytes/sample
      fAVIRate = fAVISize*fAVISamplingFrequency;
    } else if (strcmp(fOurSubsession.codecName(), "L8") == 0) {
      fWAVCodecTag = 0x0001;
      fAVIScale = fAVISize = numChannels; // 1 byte/sample
      fAVIRate = fAVISize*fAVISamplingFrequency;
    } else if (strcmp(fOurSubsession.codecName(), "PCMA") == 0) {
      fWAVCodecTag = 0x0006;
      fAVIScale = fAVISize = numChannels; // 1 byte/sample
      fAVIRate = fAVISize*fAVISamplingFrequency;
    } else if (strcmp(fOurSubsession.codecName(), "PCMU") == 0) {
      fWAVCodecTag = 0x0007;
      fAVIScale = fAVISize = numChannels; // 1 byte/sample
      fAVIRate = fAVISize*fAVISamplingFrequency;
    } else if (strcmp(fOurSubsession.codecName(), "MPA") == 0) {
      fWAVCodecTag = 0x0050;
      fAVIScale = fAVISize = 1;
      fAVIRate = 0; // ??? #####
    } else {
      fWAVCodecTag = 0x0001; // ??? #####
      fAVIScale = fAVISize = 1;
      fAVIRate = 0; // ??? #####
    }
  } else { // unknown medium
    fAVISubsessionTag
      = fourChar('0'+subsessionIndex/10,'0'+subsessionIndex%10,'?','?');
    fAVICodecHandlerType = 0;
    fAVIScale = fAVISize = 1;
    fAVIRate = 0; // ??? #####
  }
}

void AVISubsessionIOState::afterGettingFrame(unsigned packetDataSize,
					  struct timeval presentationTime) {
  // Begin by checking whether there was a gap in the RTP stream.
  // If so, try to compensate for this (if desired):
  unsigned short rtpSeqNum
    = fOurSubsession.rtpSource()->curPacketRTPSeqNum();
  if (fOurSink.fPacketLossCompensate && fPrevBuffer->bytesInUse() > 0) {
    short seqNumGap = rtpSeqNum - fLastPacketRTPSeqNum;
    for (short i = 1; i < seqNumGap; ++i) {
      // Insert a copy of the previous frame, to compensate for the loss:
      useFrame(*fPrevBuffer);
    }
  }
  fLastPacketRTPSeqNum = rtpSeqNum;

  // Now, continue working with the frame that we just got
  if (fBuffer->bytesInUse() == 0) {
    fBuffer->setPresentationTime(presentationTime);
  }
  fBuffer->addBytes(packetDataSize);

  useFrame(*fBuffer);
  if (fOurSink.fPacketLossCompensate) {
    // Save this frame, in case we need it for recovery:
    SubsessionBuffer* tmp = fPrevBuffer; // assert: != NULL
    fPrevBuffer = fBuffer;
    fBuffer = tmp;
  }
  fBuffer->reset(); // for the next input

  // Now, try getting more frames:
  fOurSink.continuePlaying();
}

void AVISubsessionIOState::useFrame(SubsessionBuffer& buffer) {
  unsigned char* const frameSource = buffer.dataStart();
  unsigned const frameSize = buffer.bytesInUse();
  struct timeval const& presentationTime = buffer.presentationTime();
  if (fPrevPresentationTime.tv_usec != 0||fPrevPresentationTime.tv_sec != 0) {
    int uSecondsDiff
      = (presentationTime.tv_sec - fPrevPresentationTime.tv_sec)*1000000
      + (presentationTime.tv_usec - fPrevPresentationTime.tv_usec);
    if (uSecondsDiff > 0) {
      unsigned bytesPerSecond = (unsigned)((frameSize*1000000.0)/uSecondsDiff);
      if (bytesPerSecond > fMaxBytesPerSecond) {
	fMaxBytesPerSecond = bytesPerSecond;
      }
    }
  }
  fPrevPresentationTime = presentationTime;

  if (fIsByteSwappedAudio) {
    // We need to swap the 16-bit audio samples from big-endian
    // to little-endian order, before writing them to a file:
    for (unsigned i = 0; i < frameSize; i += 2) {
      unsigned char tmp = frameSource[i];
      frameSource[i] = frameSource[i+1];
      frameSource[i+1] = tmp;
    }
  }

  // Add an index record for this frame:
  AVIIndexRecord* newIndexRecord
    = new AVIIndexRecord(fAVISubsessionTag, // chunk id
			 AVIIF_KEYFRAME, // flags
			 4 + fOurSink.fNumBytesWritten, // offset (note: 4 == 'movi')
			 frameSize); // size
  fOurSink.addIndexRecord(newIndexRecord);

  // Write the data into the file:
  fOurSink.fNumBytesWritten += fOurSink.addWord(fAVISubsessionTag);
  if (strcmp(fOurSubsession.codecName(), "H264") == 0) {
    // Insert a 'start code' (0x00 0x00 0x00 0x01) in front of the frame:
    fOurSink.fNumBytesWritten += fOurSink.addWord(4+frameSize);
    fOurSink.fNumBytesWritten += fOurSink.addWord(fourChar(0x00, 0x00, 0x00, 0x01));//add start code
  } else {
    fOurSink.fNumBytesWritten += fOurSink.addWord(frameSize);
  }
  fwrite(frameSource, 1, frameSize, fOurSink.fOutFid);
  fOurSink.fNumBytesWritten += frameSize;
  // Pad to an even length:
  if (frameSize%2 != 0) fOurSink.fNumBytesWritten += fOurSink.addByte(0);

  ++fNumFrames;
}

void AVISubsessionIOState::onSourceClosure() {
  fOurSourceIsActive = False;
  fOurSink.onSourceClosure1();
}


////////// AVI-specific implementation //////////

unsigned AVIFileSink::addWord(unsigned word) {
  // Add "word" to the file in little-endian order:
  addByte(word); addByte(word>>8);
  addByte(word>>16); addByte(word>>24);

  return 4;
}

unsigned AVIFileSink::addHalfWord(unsigned short halfWord) {
  // Add "halfWord" to the file in little-endian order:
  addByte((unsigned char)halfWord); addByte((unsigned char)(halfWord>>8));

  return 2;
}

unsigned AVIFileSink::addZeroWords(unsigned numWords) {
  for (unsigned i = 0; i < numWords; ++i) {
    addWord(0);
  }

  return numWords*4;
}

unsigned AVIFileSink::add4ByteString(char const* str) {
  addByte(str[0]); addByte(str[1]); addByte(str[2]);
  addByte(str[3] == '\0' ? ' ' : str[3]); // e.g., for "AVI "

  return 4;
}

void AVIFileSink::setWord(unsigned filePosn, unsigned size) {
  do {
    if (SeekFile64(fOutFid, filePosn, SEEK_SET) < 0) break;
    addWord(size);
    if (SeekFile64(fOutFid, 0, SEEK_END) < 0) break; // go back to where we were

    return;
  } while (0);

  // One of the SeekFile64()s failed, probable because we're not a seekable file
  envir() << "AVIFileSink::setWord(): SeekFile64 failed (err "
	  << envir().getErrno() << ")\n";
}

// Methods for writing particular file headers.  Note the following macros:

#define addFileHeader(tag,name) \
    unsigned AVIFileSink::addFileHeader_##name() { \
        add4ByteString("" #tag ""); \
        unsigned headerSizePosn = (unsigned)TellFile64(fOutFid); addWord(0); \
        add4ByteString("" #name ""); \
        unsigned ignoredSize = 8;/*don't include size of tag or size fields*/ \
        unsigned size = 12

#define addFileHeader1(name) \
    unsigned AVIFileSink::addFileHeader_##name() { \
        add4ByteString("" #name ""); \
        unsigned headerSizePosn = (unsigned)TellFile64(fOutFid); addWord(0); \
        unsigned ignoredSize = 8;/*don't include size of name or size fields*/ \
        unsigned size = 8

#define addFileHeaderEnd \
  setWord(headerSizePosn, size-ignoredSize); \
  return size; \
}

addFileHeader(RIFF,AVI);
    size += addFileHeader_hdrl();
    size += addFileHeader_movi();
    fRIFFSizePosition = headerSizePosn;
    fRIFFSizeValue = size-ignoredSize;
addFileHeaderEnd;

addFileHeader(LIST,hdrl);
    size += addFileHeader_avih();

    // Then, add a "strl" header for each subsession (stream):
    // (Make the video subsession (if any) come before the audio subsession.)
    unsigned subsessionCount = 0;
    MediaSubsessionIterator iter(fInputSession);
    MediaSubsession* subsession;
    while ((subsession = iter.next()) != NULL) {
      fCurrentIOState = (AVISubsessionIOState*)(subsession->miscPtr);
      if (fCurrentIOState == NULL) continue;
      if (strcmp(subsession->mediumName(), "video") != 0) continue;

      fCurrentIOState->setAVIstate(subsessionCount++);
      size += addFileHeader_strl();
    }
    iter.reset();
    while ((subsession = iter.next()) != NULL) {
      fCurrentIOState = (AVISubsessionIOState*)(subsession->miscPtr);
      if (fCurrentIOState == NULL) continue;
      if (strcmp(subsession->mediumName(), "video") == 0) continue;

      fCurrentIOState->setAVIstate(subsessionCount++);
      size += addFileHeader_strl();
    }

    // Then add another JUNK entry
    ++fJunkNumber;
    size += addFileHeader_JUNK();
addFileHeaderEnd;

#define AVIF_HASINDEX           0x00000010 // Index at end of file?
#define AVIF_MUSTUSEINDEX       0x00000020
#define AVIF_ISINTERLEAVED      0x00000100
#define AVIF_TRUSTCKTYPE        0x00000800 // Use CKType to find key frames?
#define AVIF_WASCAPTUREFILE     0x00010000
#define AVIF_COPYRIGHTED        0x00020000

addFileHeader1(avih);
    unsigned usecPerFrame = fMovieFPS == 0 ? 0 : 1000000/fMovieFPS;
    size += addWord(usecPerFrame); // dwMicroSecPerFrame
    fAVIHMaxBytesPerSecondPosition = (unsigned)TellFile64(fOutFid);
    size += addWord(0); // dwMaxBytesPerSec (fill in later)
    size += addWord(0); // dwPaddingGranularity
    size += addWord(AVIF_TRUSTCKTYPE|AVIF_HASINDEX|AVIF_ISINTERLEAVED); // dwFlags
    fAVIHFrameCountPosition = (unsigned)TellFile64(fOutFid);
    size += addWord(0); // dwTotalFrames (fill in later)
    size += addWord(0); // dwInitialFrame
    size += addWord(fNumSubsessions); // dwStreams
    size += addWord(fBufferSize); // dwSuggestedBufferSize
    size += addWord(fMovieWidth); // dwWidth
    size += addWord(fMovieHeight); // dwHeight
    size += addZeroWords(4); // dwReserved
addFileHeaderEnd;

addFileHeader(LIST,strl);
    size += addFileHeader_strh();
    size += addFileHeader_strf();
    fJunkNumber = 0;
    size += addFileHeader_JUNK();
addFileHeaderEnd;

addFileHeader1(strh);
    size += add4ByteString(fCurrentIOState->fIsVideo ? "vids" :
			   fCurrentIOState->fIsAudio ? "auds" :
			   "????"); // fccType
    size += addWord(fCurrentIOState->fAVICodecHandlerType); // fccHandler
    size += addWord(0); // dwFlags
    size += addWord(0); // wPriority + wLanguage
    size += addWord(0); // dwInitialFrames
    size += addWord(fCurrentIOState->fAVIScale); // dwScale
    size += addWord(fCurrentIOState->fAVIRate); // dwRate
    size += addWord(0); // dwStart
    fCurrentIOState->fSTRHFrameCountPosition = (unsigned)TellFile64(fOutFid);
    size += addWord(0); // dwLength (fill in later)
    size += addWord(fBufferSize); // dwSuggestedBufferSize
    size += addWord((unsigned)-1); // dwQuality
    size += addWord(fCurrentIOState->fAVISize); // dwSampleSize
    size += addWord(0); // rcFrame (start)
    if (fCurrentIOState->fIsVideo) {
        size += addHalfWord(fMovieWidth);
        size += addHalfWord(fMovieHeight);
    } else {
        size += addWord(0);
    }
addFileHeaderEnd;

addFileHeader1(strf);
    if (fCurrentIOState->fIsVideo) {
      // Add a BITMAPINFO header:
      unsigned extraDataSize = 0;
      size += addWord(10*4 + extraDataSize); // size
      size += addWord(fMovieWidth);
      size += addWord(fMovieHeight);
      size += addHalfWord(1); // planes
      size += addHalfWord(24); // bits-per-sample #####
      size += addWord(fCurrentIOState->fAVICodecHandlerType); // compr. type
      size += addWord(fCurrentIOState->fAVISize);
      size += addZeroWords(4); // ??? #####
      // Later, add extra data here (if any) #####
    } else if (fCurrentIOState->fIsAudio) {
      // Add a WAVFORMATEX header:
      size += addHalfWord(fCurrentIOState->fWAVCodecTag);
      unsigned numChannels = fCurrentIOState->fOurSubsession.numChannels();
      size += addHalfWord(numChannels);
      size += addWord(fCurrentIOState->fAVISamplingFrequency);
      size += addWord(fCurrentIOState->fAVIRate); // bytes per second
      size += addHalfWord(fCurrentIOState->fAVISize); // block alignment
      unsigned bitsPerSample = (fCurrentIOState->fAVISize*8)/numChannels;
      size += addHalfWord(bitsPerSample);
      if (strcmp(fCurrentIOState->fOurSubsession.codecName(), "MPA") == 0) {
	// Assume MPEG layer II audio (not MP3): #####
	size += addHalfWord(22); // wav_extra_size
	size += addHalfWord(2); // fwHeadLayer
	size += addWord(8*fCurrentIOState->fAVIRate); // dwHeadBitrate #####
	size += addHalfWord(numChannels == 2 ? 1: 8); // fwHeadMode
	size += addHalfWord(0); // fwHeadModeExt
	size += addHalfWord(1); // wHeadEmphasis
	size += addHalfWord(16); // fwHeadFlags
	size += addWord(0); // dwPTSLow
	size += addWord(0); // dwPTSHigh
      }
    }
addFileHeaderEnd;

#define AVI_MASTER_INDEX_SIZE   256

addFileHeader1(JUNK);
    if (fJunkNumber == 0) {
      size += addHalfWord(4); // wLongsPerEntry
      size += addHalfWord(0); // bIndexSubType + bIndexType
      size += addWord(0); // nEntriesInUse #####
      size += addWord(fCurrentIOState->fAVISubsessionTag); // dwChunkId
      size += addZeroWords(2); // dwReserved
      size += addZeroWords(AVI_MASTER_INDEX_SIZE*4);
    } else {
      size += add4ByteString("odml");
      size += add4ByteString("dmlh");
      unsigned wtfCount = 248;
      size += addWord(wtfCount); // ??? #####
      size += addZeroWords(wtfCount/4);
    }
addFileHeaderEnd;

addFileHeader(LIST,movi);
    fMoviSizePosition = headerSizePosn;
    fMoviSizeValue = size-ignoredSize;
addFileHeaderEnd;
