Linux Game Programming for PC & Embedded Systems using SDL
Presented by
Fore June
Author of Windows Fan, Linux Fan

Sample program of extracting raw video from an AVI file.

avi_to_raw.cpp
mpeg4ip.h
avilib.h
avilib.c



avi_to_raw.cpp:
/*
  avi_to_raw.cpp
  Need to compile together with MPEG4IP avilib.c
  Compile: g++ -o avi_to_raw avi_to_raw.cpp avilib.c
  Execute: ./avi_to_raw infile [video_output_file audio_output_file]

  http://www.webkinesia.com/games/index.php
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "avilib.h"

using namespace std;

int main( int argc, char *argv[] )
{
  FILE *fpo = NULL;
  avi_t *avi = NULL;		//points to opened avi file
  char infilename[30], outfilename[30], *pc;
  double videoFrameRate;
  unsigned  numVideoFrames; 
  unsigned long fileDuration;
  long numBytes = 0, totalBytes = 0;
  unsigned long videoFramesRead = 0;
  unsigned long emptyFramesRead = 0;
  unsigned long short_frames_len = 4;

  if ( argc < 2 ) {
    printf("\nUsage: avi_to_raw infile [outfile1 outfile2]\n");
    exit ( 1 );
  } 
  strcpy ( infilename, argv[1] );

  avi = AVI_open_input_file( infilename, 1 );
  if (avi == NULL) {
    fprintf(stderr, "error %s: %s\n", infilename, AVI_strerror());
    exit( 2 );
  }
 
  videoFrameRate = AVI_video_frame_rate( avi );	//frame per second
  numVideoFrames = AVI_video_frames( avi );
  fileDuration = ( unsigned long ) ceil( numVideoFrames / videoFrameRate);

  printf("\n---------------------------------------------------------");
  printf("\nVideo Frame Rate:\t%5.0f \tfps", videoFrameRate );
  printf("\nNumber of Frames:\t%5d", numVideoFrames );
  printf("\nFile Duration:   \t%5ld \tsec", fileDuration );
  printf("\nVideo width:     \t%5d \tpixels", avi->width );
  printf("\nVideo height:     \t%5d \tpixels", avi->height );
  printf("\nCompressor type: \t%5s", avi->compressor );
  printf("\nAudio channels:  \t%5d", avi->a_chans );
  printf("\nAudio sample rate:\t%5d \tHz", avi->a_rate  );
  printf("\nBits per audio sample:\t%5d", avi->a_bits );

  printf("\nVideo starts at:  \t%5ld ( 0x%lx )", avi->movi_start, avi->movi_start );
  printf("\n---------------------------------------------------------\n");
 
  //extract video 
  if ( argc < 3 ) {				//construct raw video output file name
    strcpy ( outfilename, infilename );
    pc = strrchr ( outfilename, '.' );          //pc points to '.'
    if ( pc != NULL ) *pc = 0;
    strcat ( outfilename, ".rawv" );             //extenstion .rawv
  } else
    strcpy ( outfilename, argv[2] ); 
  if ( ( fpo = fopen ( outfilename, "wb" ) ) == NULL ) {
    fprintf(stderr, "error opening file %s for output\n", outfilename );
    exit ( 3 );
  }
  // get a buffer large enough to handle a frame of raw SDTV 
  u_char *buf = ( u_char * ) malloc ( 768 * 576 * 4 );
  if ( buf == NULL ) {
    fprintf(stderr, "Error allocating memory\n");
    exit ( 4 );
  }
  //move file pointer pointing to beginning of video data
  if (AVI_seek_start( avi )) {
     fprintf(stderr, "bad seek 0: %s\n", AVI_strerror());
     exit( 5 );
  }
  if (AVI_set_video_position( avi, 0, NULL)) {
     fprintf(stderr, "bad seek 1: %s\n", AVI_strerror());
     exit( 6 );
  }

  videoFramesRead = 0;
  while ( ( numBytes = AVI_read_frame( avi, (char *)buf ) ) > -1 ) {
    totalBytes += numBytes;
    videoFramesRead++;
    printf("frame %d - length %u total %u\r", videoFramesRead, numBytes, totalBytes);
    //eliminate short frames
    if ( numBytes > short_frames_len ) {
      if (  fwrite ( buf, 1, numBytes, fpo ) != numBytes ) {
        fprintf ( stderr, "Error writing %s\n", outfilename );    
        break;
      }
    } else {
      emptyFramesRead++;
    }
    if ( videoFramesRead >= numVideoFrames ) break;
  } //while
  // read error
  if (numBytes < 0) 
    fprintf(stderr, "read error\n" );
  if (emptyFramesRead) {
    fprintf(stderr, "warning: %u zero length frames ignored\n", emptyFramesRead);
  }

  fclose ( fpo );			//done with video

  if ( avi->a_chans == 0 ) {
    printf("\nno audio channel\n" );
    exit ( 7 );
  }
  //extract audio
  if ( argc < 4 ) {                             //construct raw audio output file name
    strcpy ( outfilename, infilename );
    pc = strrchr ( outfilename, '.' );          //pc points to '.'
    if ( pc != NULL ) *pc = 0;
    strcat ( outfilename, ".rawa" );       	//extenstion .rawa
  } else
    strcpy ( outfilename, argv[3] );
  if ( ( fpo = fopen ( outfilename, "wb" ) ) == NULL ) {
    fprintf(stderr, "error opening file %s for output\n", outfilename );
    exit ( 9 );
  }

  unsigned audioFrames = 0;
  totalBytes = 0;
  if (AVI_seek_start( avi )) {
    fprintf(stderr, "Audio bad seek 2: %s\n", AVI_strerror());
    exit( 10 );
  }
  if (AVI_set_audio_position( avi, 0)) {
    fprintf(stderr, "Audio bad seek 3: %s\n", AVI_strerror());
    exit( 11 );
  }
  while ((numBytes = AVI_read_audio( avi, (char *)buf, 8192)) > 0) {
    totalBytes += numBytes;
    if (fwrite ( buf, 1, numBytes, fpo ) != numBytes) {
      fprintf(stderr, "error writing %s\n", outfilename );
      break;
    }
    audioFrames++;
    printf("frame %d - length %u total %u\r", audioFrames, numBytes, totalBytes);
  }
 
  printf("\n");
  fclose ( fpo );	

  return 0;
}