File_Ogg
[ class tree: File_Ogg ] [ index: File_Ogg ] [ all elements ]

Source for file Theora.php

Documentation is available at Theora.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------------+
  4. // | File_Ogg PEAR Package for Accessing Ogg Bitstreams                         |
  5. // | Copyright (c) 2005-2007                                                    |
  6. // | David Grant <david@grant.org.uk>                                           |
  7. // | Tim Starling <tstarling@wikimedia.org>                                     |
  8. // +----------------------------------------------------------------------------+
  9. // | This library is free software; you can redistribute it and/or              |
  10. // | modify it under the terms of the GNU Lesser General Public                 |
  11. // | License as published by the Free Software Foundation; either               |
  12. // | version 2.1 of the License, or (at your option) any later version.         |
  13. // |                                                                            |
  14. // | This library is distributed in the hope that it will be useful,            |
  15. // | but WITHOUT ANY WARRANTY; without even the implied warranty of             |
  16. // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU          |
  17. // | Lesser General Public License for more details.                            |
  18. // |                                                                            |
  19. // | You should have received a copy of the GNU Lesser General Public           |
  20. // | License along with this library; if not, write to the Free Software        |
  21. // | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA |
  22. // +----------------------------------------------------------------------------+
  23.  
  24. require_once('File/Ogg/Bitstream.php');
  25.  
  26. define'OGG_THEORA_IDENTIFICATION_HEADER'0x80 );
  27. define'OGG_THEORA_COMMENTS_HEADER'0x81 );
  28. define'OGG_THEORA_IDENTIFICATION_PAGE_OFFSET');
  29. define'OGG_THEORA_COMMENTS_PAGE_OFFSET');
  30.  
  31.  
  32. /**
  33.  * @author      David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org>
  34.  * @category    File
  35.  * @copyright   David Grant <david@grant.org.uk>, Tim Starling <tstarling@wikimedia.org>
  36.  * @license     http://www.gnu.org/copyleft/lesser.html GNU LGPL
  37.  * @link        http://pear.php.net/package/File_Ogg
  38.  * @link        http://www.xiph.org/theora/
  39.  * @package     File_Ogg
  40.  * @version     CVS: $Id: Theora.php 302834 2010-08-27 02:16:20Z tstarling $
  41.  */
  42. {
  43.     /**
  44.      * @access  private
  45.      */
  46.     function __construct($streamSerial$streamData$filePointer)
  47.     {
  48.         parent::__construct($streamSerial$streamData$filePointer);
  49.         $this->_decodeIdentificationHeader();
  50.         $this->_decodeCommentsHeader();
  51.           $endSec $this->getSecondsFromGranulePos$this->_lastGranulePos );
  52.  
  53.         $startSec =  $this->getSecondsFromGranulePos$this->_firstGranulePos );
  54.  
  55.         //make sure the offset is worth taking into account oggz_chop related hack
  56.         if$startSec > 1){
  57.             $this->_streamLength $endSec $startSec;
  58.             $this->_startOffset $startSec;
  59.         }else{
  60.             $this->_streamLength $endSec;
  61.         }
  62.  
  63.         $this->_avgBitrate $this->_streamLength ($this->_streamSize * 8$this->_streamLength : 0;
  64.     }
  65.     function getSecondsFromGranulePos($granulePos){
  66.         // Calculate GranulePos seconds
  67.         // First make some "numeric strings"
  68.         // These might not fit into PHP's integer type, but they will fit into
  69.         // the 53-bit mantissa of a double-precision number
  70.         $topWord floatvalbase_convertsubstr$granulePos0)1610 ) );
  71.         $bottomWord floatvalbase_convertsubstr$granulePos8)1610 ) );
  72.         // Calculate the keyframe position by shifting right by KFGSHIFT
  73.         // We don't use PHP's shift operators because they're terribly broken
  74.         // This is made slightly simpler by the fact that KFGSHIFT < 32
  75.         $keyFramePos $topWord pow(2$this->_kfgShift - 32+
  76.             floor$bottomWord pow(2$this->_kfgShift) );
  77.         // Calculate the frame offset by masking off the top 64-KFGSHIFT bits
  78.         // This requires a bit of floating point trickery
  79.         $offset fmod$bottomWordpow(2$this->_kfgShift) );
  80.         // They didn't teach you that one at school did they?
  81.         // Now put it together with the frame rate to calculate time in seconds
  82.            return  $keyFramePos $offset $this->_frameRate;
  83.     }
  84.     /**
  85.      * Get the 6-byte identification string expected in the common header
  86.      */
  87.     function getIdentificationString()
  88.     {
  89.         return OGG_STREAM_CAPTURE_THEORA;
  90.     }
  91.  
  92.     /**
  93.      * Parse the identification header in a Theora stream.
  94.      * @access  private
  95.      */
  96.     function _decodeIdentificationHeader()
  97.     {
  98.         $this->_decodeCommonHeader(OGG_THEORA_IDENTIFICATION_HEADEROGG_THEORA_IDENTIFICATION_PAGE_OFFSET);
  99.         $h File_Ogg::_readBigEndian$this->_filePointerarray(
  100.             'VMAJ' => 8,
  101.             'VMIN' => 8,
  102.             'VREV' => 8,
  103.             'FMBW' => 16,
  104.             'FMBH' => 16,
  105.             'PICW' => 24,
  106.             'PICH' => 24,
  107.             'PICX' => 8,
  108.             'PICY' => 8,
  109.             'FRN'  => 32,
  110.             'FRD'  => 32,
  111.             'PARN' => 24,
  112.             'PARD' => 24,
  113.             'CS'   => 8,
  114.             'NOMBR' => 24,
  115.             'QUAL' => 6,
  116.             'KFGSHIFT' => 5,
  117.             'PF' => 2));
  118.         if !$h {
  119.             throw new PEAR_Exception("Stream is undecodable due to a truncated header."OGG_ERROR_UNDECODABLE);
  120.         }
  121.  
  122.         // Theora version
  123.         // Seems overly strict but this is what the spec says
  124.         // VREV is for backwards-compatible changes, apparently
  125.         if $h['VMAJ'!= 3 || $h['VMIN'!= 2 {
  126.             throw new PEAR_Exception("Stream is undecodable due to an invalid theora version."OGG_ERROR_UNDECODABLE);
  127.         }
  128.         $this->_theoraVersion = "{$h['VMAJ']}.{$h['VMIN']}.{$h['VREV']}";
  129.  
  130.         // Frame height/width
  131.         if !$h['FMBW'|| !$h['FMBH'{
  132.             throw new PEAR_Exception("Stream is undecodable because it has frame size of zero."OGG_ERROR_UNDECODABLE);
  133.         }
  134.         $this->_frameWidth $h['FMBW'* 16;
  135.         $this->_frameHeight $h['FMBH'* 16;
  136.  
  137.         // Picture height/width
  138.         if $h['PICW'$this->_frameWidth || $h['PICH'$this->_frameHeight {
  139.             throw new PEAR_Exception("Stream is undecodable because the picture width is greater than the frame width."OGG_ERROR_UNDECODABLE);
  140.         }
  141.         $this->_pictureWidth $h['PICW'];
  142.         $this->_pictureHeight $h['PICH'];
  143.  
  144.         // Picture offset
  145.         $this->_offsetX $h['PICX'];
  146.         $this->_offsetY $h['PICY'];
  147.         // Frame rate
  148.         $this->_frameRate $h['FRD'== 0 ? 0 : $h['FRN'$h['FRD'];
  149.         // Physical aspect ratio
  150.         if !$h['PARN'|| !$h['PARD'{
  151.             $this->_physicalAspectRatio = 1;
  152.         else {
  153.             $this->_physicalAspectRatio $h['PARN'$h['PARD'];
  154.         }
  155.  
  156.         // Color space
  157.         $colorSpaces = array(
  158.             0 => 'Undefined',
  159.             1 => 'Rec. 470M',
  160.             2 => 'Rec. 470BG',
  161.         );
  162.         if isset$colorSpaces[$h['CS']] ) ) {
  163.             $this->_colorSpace $colorSpaces[$h['CS']];
  164.         else {
  165.             $this->_colorSpace 'Unknown (reserved)';
  166.         }
  167.  
  168.         $this->_nomBitrate $h['NOMBR'];
  169.  
  170.         $this->_quality $h['QUAL'];
  171.         $this->_kfgShift $h['KFGSHIFT'];
  172.  
  173.         $pixelFormats = array(
  174.             0 => '4:2:0',
  175.             1 => 'Unknown (reserved)',
  176.             2 => '4:2:2',
  177.             3 => '4:4:4',
  178.         );
  179.         $this->_pixelFormat $pixelFormats[$h['PF']];
  180.  
  181.         switch $h['PF'{
  182.             case 0:
  183.                 $h['NSBS'=
  184.                     floor( ($h['FMBW'+ 1/ 2 *
  185.                     floor( ($h['FMBH'+ 1/ 2 + 2 *
  186.                     floor( ($h['FMBW'+ 3/ 4 *
  187.                     floor( ($h['FMBH'+ 3/ 4 );
  188.                 $h['NBS'= 6 * $h['FMBW'$h['FMBH'];
  189.                 break;
  190.             case 2:
  191.                 $h['NSBS'=
  192.                     floor( ($h['FMBW'+ 1/ 2 *
  193.                     floor( ($h['FMBH'+ 1/ 2 + 2 *
  194.                     floor( ($h['FMBW'+ 3/ 4 *
  195.                     floor( ($h['FMBH'+ 1/ 2 );
  196.                 $h['NBS'= 8 * $h['FMBW'$h['FMBH'];
  197.                 break;
  198.             case 3:
  199.                 $h['NSBS'=
  200.                     3 * floor( ($h['FMBW'+ 1/ 2 *
  201.                         floor( ($h['FMBH'+ 1/ 2 );
  202.                 $h['NBS'= 12 * $h['FMBW'$h['FMBH'];
  203.                 break;
  204.             default:
  205.                 $h['NSBS'$h['NBS'= 0;
  206.         }
  207.         $h['NMBS'$h['FMBW'$h['FMBH'];
  208.  
  209.         $this->_idHeader $h;
  210.     }
  211.  
  212.     /**
  213.      * Get an associative array containing header information about the stream
  214.      * @access  public
  215.      * @return  array 
  216.      */
  217.     function getHeader({
  218.         return $this->_idHeader;
  219.     }
  220.  
  221.     /**
  222.      * Get a short string describing the type of the stream
  223.      * @return string 
  224.      */
  225.     function getType({
  226.         return 'Theora';
  227.     }
  228.  
  229.     /**
  230.      * Decode the comments header
  231.      * @access private
  232.      */
  233.     function _decodeCommentsHeader()
  234.     {
  235.         $this->_decodeCommonHeader(OGG_THEORA_COMMENTS_HEADEROGG_THEORA_COMMENTS_PAGE_OFFSET);
  236.         $this->_decodeBareCommentsHeader();
  237.     }
  238.  
  239. }
  240. ?>

Documentation generated on Mon, 11 Mar 2019 15:38:25 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.