<?php
// $Id$

/**
 *  The function used by the mapi_video module
 */
function _mapi_video_flv($filename) {
    
  /**
   *  Some things borrowed from the getid3 library
   *  Not at all finished, requires metadata information to be loaded.
   */
  
  // Open file
  if (!($handle = @fopen($filename, 'rb'))) {
    return;
  }
  
  // Read FLV header block
  if (($block = @fread($handle, 9)) === FALSE) {
    fclose($handle);
    return;
  }
  
  // process the header block
  $block = unpack('a3magic/Cversion/Cflags/Noffset', $block);
  // Must match magic number
  if ($block['magic'] != 'FLV') {
    fclose($handle);
    return;
  }
  
  // Can only handle version 1
  if (($s['version'] = $block['version']) != 1) {
    fclose($handle);
    return;
  }
  
  // Determine whether audio/video data involved
  $s['audio'] = ($block['flags'] & 0x4 == 0x4);
  $s['video'] = ($block['flags'] & 0x1 == 0x1);
  
  // this should be 9 for FLV 1
  if ($block['offset'] != 9) {
    fclose($handle);
    return;
  }
  
  // Read tags until we run out of them.
  
  $duration = 0;
  while (!feof($handle)) {
    // read beginning tag block
    if (($block = @fread($handle, 16)) === FALSE) {
      break;
    }
    
    // either at end of file, of something wrong with the file.
    // either way we don't want to be here.
    if (strlen($block) < 16) {
      break;
    }
    
    $block = unpack('Nptagsize/Ctype/C3data/C3time/Cextra', $block);
  
    // get the actual details
    $datasize = ($block['data1'] << 16) | ($block['data2'] << 8) | ($block['data3']);
    $timestamp = ($block['time1'] << 16) | ($block['time2'] << 8) | ($block['time3']);
    $extra = $block['extra'];
    
    $offset = ftell($handle) - 1 + $datasize;
  
    switch ($block['type']) {
      case 8: // audio
        if (!isset($s['audio-format'])) {
          $s['audio-format']      = $extra & 0x07;
          $s['audio-rate']        = ($extra & 0x30) / 0x10;
          $s['audio-sample-size'] = ($extra & 0x40) / 0x40;
          $s['audio-type']        = ($extra & 0x80) / 0x80;
        }
        break;
      case 9: // video
        if (!isset($s['video-codec'])) {
          $s['video-codec'] = $extra & 0x07;
  
          // read video header
          if (($block = @fread($handle, 11)) === FALSE) {
            break;
          }
          
          if ($extra != 4) {
            $block = unpack('C*', $block);
            
            // picture size
            $picsize = (($block[4] & 0x3) << 1) | (($block[5] & 0x80) >> 7);
            switch ($picsize) {
              case 0:
                $s['width'] = (($block[5] & 0x7F) << 1) | (($block[6] & 0x80) >> 7);
                $s['height'] = (($block[6] & 0x7F) << 1) | (($block[7] & 0x80) >> 7);
                break;
              case 1:
                $s['width'] = (($block[5] & 0x7F) << 9) | ($block[6] << 1) | (($block[7] & 0x80) >> 7);
                $s['height'] = (($block[7] & 0x7F) << 9) | ($block[8] << 1) | (($block[9] & 0x80) >> 7);
                break;
              case 2:
                $s['width']  = 352;
                $s['height'] = 288;
                break;
              case 3:
                $s['width']  = 176;
                $s['height'] = 144;
                break;
              case 4:
                $s['width']  = 128;
                $s['height'] = 96;
                break;
              case 5:
                $s['width']  = 320;
                $s['height'] = 240;
                break;
              case 6:
                $s['width']  = 160;
                $s['height'] = 120;
                break;
              default:
                $s['width']  = 0;
                $s['height'] = 0;
                break;
            }
          }        
        }      
        break;
    }
  
    if ($timestamp > $duration) {
      $duration = $timestamp;
    }
  
    fseek($handle, $offset, SEEK_SET);  
  }
  
  fclose($handle);
  
  // always in seconds
  $s['duration'] = $duration / 1000;
  
  $dimensions = $s;
  
  return array('dimensions' => $dimensions, 'metadata' => array());
}