diff --git a/src/Zend/Media/Iso14496/Box/Cdsc.php b/src/Zend/Media/Iso14496/Box/Cdsc.php new file mode 100644 index 0000000..a8b4d12 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Cdsc.php @@ -0,0 +1,119 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Cdsc extends Zend_Media_Iso14496_Box +{ + /** @var Array */ + private $_trackId = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + while ($this->_reader->getOffset <= $this->getSize()) { + $this->_trackId[] = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @return integer + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Sets an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @param Array $trackId The array of values. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + count($this->_trackId) * 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 0; $i < count($this->_trackId); $i++) { + $writer->writeUInt32BE($this->_trackId[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Co64.php b/src/Zend/Media/Iso14496/Box/Co64.php new file mode 100644 index 0000000..7034da6 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Co64.php @@ -0,0 +1,133 @@ +Chunk Offset Box table gives the index of each chunk into the + * containing file. There are two variants, permitting the use of 32-bit or + * 64-bit offsets. The latter is useful when managing very large presentations. + * At most one of these variants will occur in any single instance of a sample + * table. + * + * Offsets are file offsets, not the offset into any box within the file (e.g. + * {@link Zend_Media_Iso14496_Box_Mdat Media Data Box}). This permits referring + * to media data in files without any box structure. It does also mean that care + * must be taken when constructing a self-contained ISO file with its metadata + * ({@link Zend_Media_Iso14496_Box_Moov Movie Box}) at the front, as the size of + * the {@link Zend_Media_Iso14496_Box_Moov Movie Box} will affect the chunk + * offsets to the media data. + * + * This box variant contains 64-bit offsets. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Co64 extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_chunkOffsetTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_chunkOffsetTable[$i] = $this->_reader->readInt64BE(); + } + } + + /** + * Returns an array of values. Each entry has the entry number as its index + * and a 64 bit integer that gives the offset of the start of a chunk into + * its containing media file as its value. + * + * @return Array + */ + public function getChunkOffsetTable() + { + return $this->_chunkOffsetTable; + } + + /** + * Sets an array of chunk offsets. Each entry must have the entry number as + * its index and a 64 bit integer that gives the offset of the start of a + * chunk into its containing media file as its value. + * + * @param Array $chunkOffsetTable The chunk offset array. + */ + public function setChunkOffsetTable($chunkOffsetTable) + { + $this->_chunkOffsetTable = $chunkOffsetTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_chunkOffsetTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + $writer->writeUInt32BE($entryCount = count($this->_chunkOffsetTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeInt64BE($this->_chunkOffsetTable[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Cprt.php b/src/Zend/Media/Iso14496/Box/Cprt.php new file mode 100644 index 0000000..96a2272 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Cprt.php @@ -0,0 +1,150 @@ +Copyright Box contains a copyright declaration which applies to + * the entire presentation, when contained within the + * {@link Zend_Media_Iso14496_Box_Moov Movie Box}, or, when contained in a + * track, to that entire track. There may be multiple copyright boxes using + * different language codes. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Cprt extends Zend_Media_Iso14496_FullBox +{ + /** @var string */ + private $_language; + + /** @var string */ + private $_notice; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + * @todo Distinguish UTF-16? + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_language = chr + (((($tmp = $this->_reader->readUInt16BE()) >> 10) & 0x1f) + 0x60) . + chr((($tmp >> 5) & 0x1f) + 0x60) . chr(($tmp & 0x1f) + 0x60); + $this->_notice = $this->_reader->readString8 + ($this->getOffset() + $this->getSize() - + $this->_reader->getOffset()); + } + + /** + * Returns the three byte language code to describe the language of the + * notice, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @return string + */ + public function getLanguage() + { + return $this->_language; + } + + /** + * Sets the three byte language code to describe the language of this + * media, according to {@link http://www.loc.gov/standards/iso639-2/ + * ISO 639-2/T}. + * + * @param string $language The language code. + */ + public function setLanguage($language) + { + $this->_language = $language; + } + + /** + * Returns the copyright notice. + * + * @return string + */ + public function getNotice() + { + return $this->_notice; + } + + /** + * Returns the copyright notice. + * + * @param string $notice The copyright notice. + */ + public function setNotice($notice) + { + $this->_notice = $notice; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 3 + strlen($this->_notice); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt16BE((ord($this->_language[0]) - 0x60) << 10 | + (ord($this->_language[1])- 0x60) << 5 | + (ord($this->_language[2])- 0x60)) + ->writeString8($this->_notice, 1); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Ctts.php b/src/Zend/Media/Iso14496/Box/Ctts.php new file mode 100644 index 0000000..640ca2a --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Ctts.php @@ -0,0 +1,139 @@ +Composition Time to Sample Box provides the offset between + * decoding time and composition time. Since decoding time must be less than the + * composition time, the offsets are expressed as unsigned numbers such that + * CT(n) = DT(n) + CTTS(n) where CTTS(n) is the (uncompressed) table entry for + * sample n. + * + * The composition time to sample table is optional and must only be present if + * DT and CT differ for any samples. Hint tracks do not use this box. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Ctts extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_compositionOffsetTable = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_compositionOffsetTable[$i] = array + ('sampleCount' => $this->_reader->readUInt32BE(), + 'sampleOffset' => $this->_reader->readUInt32BE()); + } + } + + /** + * Returns an array of values. Each entry is an array containing the + * following keys. + * o sampleCount -- an integer that counts the number of consecutive + * samples that have the given offset. + * o sampleOffset -- a non-negative integer that gives the offset between + * CT and DT, such that CT(n) = DT(n) + CTTS(n). + * + * @return Array + */ + public function getCompositionOffsetTable() + { + return $this->_compositionOffsetTable; + } + + /** + * Sets an array of values. Each entry must have an array containing the + * following keys. + * o sampleCount -- an integer that counts the number of consecutive + * samples that have the given offset. + * o sampleOffset -- a non-negative integer that gives the offset between + * CT and DT, such that CT(n) = DT(n) + CTTS(n). + * + * @param Array $compositionOffsetTable The array of values. + */ + public function setCompositionOffsetTable($compositionOffsetTable) + { + $this->_compositionOffsetTable = $compositionOffsetTable; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + + count($this->_compositionOffsetTable) * 8; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_compositionOffsetTable)); + for ($i = 1; $i <= $entryCount; $i++) { + $writer->writeUInt32BE + ($this->_compositionOffsetTable[$i]['sampleCount']) + ->writeUInt32BE + ($this->_compositionOffsetTable[$i]['sampleOffset']); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Elst.php b/src/Zend/Media/Iso14496/Box/Elst.php new file mode 100644 index 0000000..2d0aff1 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Elst.php @@ -0,0 +1,170 @@ +Edit List Box contains an explicit timeline map. Each entry + * defines part of the track time-line: by mapping part of the media time-line, + * or by indicating empty time, or by defining a dwell, where a single + * time-point in the media is held for a period. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Elst extends Zend_Media_Iso14496_FullBox +{ + /** @var Array */ + private $_entries = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $entryCount = $this->_reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $entry = array(); + if ($this->getVersion() == 1) { + $entry['segmentDuration'] = $this->_reader->readInt64BE(); + $entry['mediaTime'] = $this->_reader->readInt64BE(); + } else { + $entry['segmentDuration'] = $this->_reader->readUInt32BE(); + $entry['mediaTime'] = $this->_reader->readInt32BE(); + } + $entry['mediaRate'] = + ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + + (float)("0." . ((string)($tmp & 0xffff))); + $this->_entries[] = $entry; + } + } + + /** + * Returns an array of entries. Each entry is an array containing the + * following keys. + * o segmentDuration: specifies the duration of this edit segment in units + * of the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. + * o mediaTime: the starting time within the media of this edit segment + * (in media time scale units, in composition time). If this field is + * set to –1, it is an empty edit. The last edit in a track shall never + * be an empty edit. Any difference between the duration in the + * {@link Zend_Media_Iso14496_Box_MVHD Movie Header Box}, and the + * track's duration is expressed as an implicit empty edit at the end. + * o mediaRate: the relative rate at which to play the media corresponding + * to this edit segment. If this value is 0, then the edit is specifying + * a dwell: the media at media-time is presented for the + * segment-duration. Otherwise this field shall contain the value 1. + * + * @return Array + */ + public function getEntries() + { + return $this->_entries; + } + + /** + * Sets the array of entries. Each entry must be an array containing the + * following keys. + * o segmentDuration: specifies the duration of this edit segment in units + * of the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. + * o mediaTime: the starting time within the media of this edit segment + * (in media time scale units, in composition time). If this field is + * set to –1, it is an empty edit. The last edit in a track shall never + * be an empty edit. Any difference between the duration in the + * {@link Zend_Media_Iso14496_Box_MVHD Movie Header Box}, and the + * track's duration is expressed as an implicit empty edit at the end. + * o mediaRate: the relative rate at which to play the media corresponding + * to this edit segment. If this value is 0, then the edit is specifying + * a dwell: the media at media-time is presented for the + * segment-duration. Otherwise this field shall contain the value 1. + * + * @param Array $entries The array of entries; + */ + public function setEntries($entries) + { + $this->_entries = $entries; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4 + count($this->_entries) * + ($this->getVersion() == 1 ? 20 : 12); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->writeUInt32BE($entryCount = count($this->_entries)); + for ($i = 1; $i <= $entryCount; $i++) { + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_entries[$i]['segmentDuration']) + ->writeInt64BE($this->_entries[$i]['mediaTime']); + } else { + $writer->writeUInt32BE($this->_entries[$i]['segmentDuration']) + ->writeUInt32BE($this->_entries[$i]['mediaTime']); + } + @list(, $mediaRateDecimals) = explode + ('.', (float)$this->_entries[$i]['mediaRate']); + $writer->writeUInt32BE + (floor($this->_entries[$i]['mediaRate']) << 16 | + $mediaRateDecimals); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Free.php b/src/Zend/Media/Iso14496/Box/Free.php new file mode 100644 index 0000000..83cc148 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Free.php @@ -0,0 +1,87 @@ +Free Space Box are irrelevant and may be ignored, or + * the object deleted, without affecting the presentation. (Care should be + * exercised when deleting the object, as this may invalidate the offsets used + * in the sample table, unless this object is after all the media data). + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Free extends Zend_Media_Iso14496_Box +{ + /** + * Constructs the class with given parameters. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader = null, &$options = array()) + { + parent::__construct($reader, $options); + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + $this->getSize(); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + $writer->write(str_repeat("\0", $this->getSize())); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Frma.php b/src/Zend/Media/Iso14496/Box/Frma.php new file mode 100644 index 0000000..a6644ed --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Frma.php @@ -0,0 +1,116 @@ +Original Format Box contains the four-character-code of the + * original un-transformed sample description. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Frma extends Zend_Media_Iso14496_Box +{ + /** @var string */ + private $_dataFormat; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_dataFormat = $this->_reader->read(4); + } + + /** + * Returns the four-character-code of the original un-transformed sample + * entry (e.g. mp4v if the stream contains protected MPEG-4 visual + * material). + * + * @return string + */ + public function getDataFormat() + { + return $this->_dataFormat; + } + + /** + * Sets the four-character-code of the original un-transformed sample + * entry (e.g. mp4v if the stream contains protected MPEG-4 visual + * material). + * + * @param string $dataFormat The data format. + */ + public function setDataFormat($dataFormat) + { + $this->_dataFormat = $dataFormat; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $writer->write(substr($this->_dataFormat, 0, 4)); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Ftyp.php b/src/Zend/Media/Iso14496/Box/Ftyp.php new file mode 100644 index 0000000..a81df3a --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Ftyp.php @@ -0,0 +1,210 @@ +File Type Box is placed as early as possible in the file (e.g. + * after any obligatory signature, but before any significant variable-size + * boxes such as a {@link Zend_Media_Iso14496_Box_Moov Movie Box}, + * {@link Zend_Media_Iso14496_Box_Mdat Media Data Box}, or + * {@link Zend_Media_Iso14496_Box_Free Free Space}). It identifies which + * specification is the best use of the file, and a minor version of + * that specification; and also a set of others specifications to which the + * file complies. + * + * The minor version is informative only. It does not appear for + * compatible-brands, and must not be used to determine the conformance of a + * file to a standard. It may allow more precise identification of the major + * specification, for inspection, debugging, or improved decoding. + * + * The type isom (ISO Base Media file) is defined as identifying files + * that conform to the first version of the ISO Base Media File Format. More + * specific identifiers can be used to identify precise versions of + * specifications providing more detail. This brand is not be used as the major + * brand; this base file format should be derived into another specification to + * be used. There is therefore no defined normal file extension, or mime type + * assigned to this brand, nor definition of the minor version when isom + * is the major brand. + * + * Files would normally be externally identified (e.g. with a file extension or + * mime type) that identifies the best use (major brand), or the brand + * that the author believes will provide the greatest compatibility. + * + * The brand iso2 shall be used to indicate compatibility with the + * amended version of the ISO Base Media File Format; it may be used in addition + * to or instead of the isom brand and the same usage rules apply. If + * used without the brand isom identifying the first version of the + * specification, it indicates that support for some or all of the technology + * introduced by the amended version of the ISO Base Media File Format is + * required. + * + * The brand avc1 shall be used to indicate that the file is conformant + * with the AVC Extensions. If used without other brands, this implies + * that support for those extensions is required. The use of avc1 as a + * major-brand may be permitted by specifications; in that case, that + * specification defines the file extension and required behavior. + * + * If a Meta-box with an MPEG-7 handler type is used at the file level, then the + * brand mp71 is a member of the compatible-brands list in the file-type + * box. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Ftyp extends Zend_Media_Iso14496_Box +{ + /** @var integer */ + private $_majorBrand; + + /** @var integer */ + private $_minorVersion; + + /** @var integer */ + private $_compatibleBrands = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_majorBrand = $this->_reader->readString8(4); + $this->_minorVersion = $this->_reader->readUInt32BE(); + while ($this->_reader->getOffset() < $this->getSize()) { + if (($brand = $this->_reader->readString8(4)) != '') { + $this->_compatibleBrands[] = $brand; + } + } + } + + /** + * Returns the major version brand. + * + * @return string + */ + public function getMajorBrand() + { + return $this->_majorBrand; + } + + /** + * Sets the major version brand. + * + * @param string $majorBrand The major version brand. + */ + public function setMajorBrand($majorBrand) + { + $this->_majorBrand = $majorBrand; + } + + /** + * Returns the minor version number. + * + * @return integer + */ + public function getMinorVersion() + { + return $this->_minorVersion; + } + + /** + * Sets the minor version number. + * + * @param integer $minorVersion The minor version number. + */ + public function setMinorVersion($minorVersion) + { + $this->_minorVersion = $minorVersion; + } + + /** + * Returns the array of compatible version brands. + * + * @return Array + */ + public function getCompatibleBrands() + { + return $this->_compatibleBrands; + } + + /** + * Sets the array of compatible version brands. + * + * @param Array $compatibleBrands The array of compatible version brands. + */ + public function setCompatibleBrands($compatibleBrands) + { + $this->_compatibleBrands = $compatibleBrands; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 8 + 4 * count($this->_compatibleBrands); + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $writer->writeString8(substr($this->_majorBrand, 0, 4)) + ->writeUInt32BE($this->_minorVersion); + for ($i = 0; $i < count($this->_compatibleBrands); $i++) { + $writer->writeString8(substr($this->_compatibleBrands[$i], 0, 4)); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Hdlr.php b/src/Zend/Media/Iso14496/Box/Hdlr.php index 58fc43e..9c001d4 100644 --- a/src/Zend/Media/Iso14496/Box/Hdlr.php +++ b/src/Zend/Media/Iso14496/Box/Hdlr.php @@ -152,7 +152,7 @@ final class Zend_Media_Iso14496_Box_Hdlr extends Zend_Media_Iso14496_FullBox */ public function getHeapSize() { - return parent::getHeapSize() + 20 + strlen($this->_name); + return parent::getHeapSize() + 21 + strlen($this->_name); } /** @@ -169,6 +169,6 @@ final class Zend_Media_Iso14496_Box_Hdlr extends Zend_Media_Iso14496_FullBox ->writeUInt32BE(0) ->writeUInt32BE(0) ->writeUInt32BE(0) - ->writeString8($this->_name); + ->writeString8($this->_name, 1); } } diff --git a/src/Zend/Media/Iso14496/Box/Hint.php b/src/Zend/Media/Iso14496/Box/Hint.php new file mode 100644 index 0000000..af84ccc --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Hint.php @@ -0,0 +1,120 @@ + + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Hint extends Zend_Media_Iso14496_Box +{ + /** @var Array */ + private $_trackId = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + while ($this->_reader->getOffset <= $this->getSize()) { + $this->_trackId[] = $this->_reader->readUInt32BE(); + } + } + + /** + * Returns an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @return Array + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Sets an array of integer references from the containing track to + * another track in the presentation. Track IDs are never re-used and cannot + * be equal to zero. + * + * @param Array $trackId The array of values. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + count($this->_trackId) * 4; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + for ($i = 0; $i < count($this->_trackId); $i++) { + $writer->writeUInt32BE($this->_trackId[$i]); + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Hmhd.php b/src/Zend/Media/Iso14496/Box/Hmhd.php new file mode 100644 index 0000000..1b17cd5 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Hmhd.php @@ -0,0 +1,187 @@ +Hint Media Header Box header contains general information, + * independent of the protocol, for hint tracks. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Hmhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_maxPDUSize; + + /** @var integer */ + private $_avgPDUSize; + + /** @var integer */ + private $_maxBitrate; + + /** @var integer */ + private $_avgBitrate; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $this->_maxPDUSize = $this->_reader->readUInt16BE(); + $this->_avgPDUSize = $this->_reader->readUInt16BE(); + $this->_maxBitrate = $this->_reader->readUInt32BE(); + $this->_avgBitrate = $this->_reader->readUInt32BE(); + } + + /** + * Returns the size in bytes of the largest PDU in this (hint) stream. + * + * @return integer + */ + public function getMaxPDUSize() + { + return $this->_maxPDUSize; + } + + /** + * Returns the size in bytes of the largest PDU in this (hint) stream. + * + * @param integer $maxPDUSize The maximum size. + */ + public function setMaxPDUSize($maxPDUSize) + { + $this->_maxPDUSize = $maxPDUSize; + } + + /** + * Returns the average size of a PDU over the entire presentation. + * + * @return integer + */ + public function getAvgPDUSize() + { + return $this->_avgPDUSize; + } + + /** + * Sets the average size of a PDU over the entire presentation. + * + * @param integer $avgPDUSize The average size. + */ + public function setAvgPDUSize() + { + $this->_avgPDUSize = $avgPDUSize; + } + + /** + * Returns the maximum rate in bits/second over any window of one second. + * + * @return integer + */ + public function getMaxBitrate() + { + return $this->_maxBitrate; + } + + /** + * Sets the maximum rate in bits/second over any window of one second. + * + * @param integer $maxBitrate The maximum bitrate. + */ + public function setMaxBitrate($maxBitrate) + { + $this->_maxBitrate = $maxBitrate; + } + + /** + * Returns the average rate in bits/second over the entire presentation. + * + * @return integer + */ + public function getAvgBitrate() + { + return $this->_avgBitrate; + } + + /** + * Sets the average rate in bits/second over the entire presentation. + * + * @param integer $maxbitrate The agerage bitrate. + */ + public function setAvgBitrate($avgBitrate) + { + $this->_avgBitrate = $avgBitrate; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + 2; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $writer->writeUInt16BE($this->_maxPDUSize) + ->writeUInt16BE($this->_avgPDUSize) + ->writeUInt16BE($this->_maxBitrate) + ->writeUInt16BE($this->_avgBitrate); + } +} diff --git a/src/Zend/Media/Iso14496/Box/Iloc.php b/src/Zend/Media/Iso14496/Box/Iloc.php new file mode 100644 index 0000000..497db8c --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Iloc.php @@ -0,0 +1,245 @@ +The Item Location Box provides a directory of resources in this or + * other files, by locating their containing file, their offset within that + * file, and their length. Placing this in binary format enables common handling + * of this data, even by systems which do not understand the particular metadata + * system (handler) used. For example, a system might integrate all the + * externally referenced metadata resources into one file, re-adjusting file + * offsets and file references accordingly. + * + * Items may be stored fragmented into extents, e.g. to enable interleaving. An + * extent is a contiguous subset of the bytes of the resource; the resource is + * formed by concatenating the extents. If only one extent is used then either + * or both of the offset and length may be implied: + * + * o If the offset is not identified (the field has a length of zero), then + * the beginning of the file (offset 0) is implied. + * o If the length is not specified, or specified as zero, then the entire + * file length is implied. References into the same file as this metadata, + * or items divided into more than one extent, should have an explicit + * offset and length, or use a MIME type requiring a different + * interpretation of the file, to avoid infinite recursion. + * + * The size of the item is the sum of the extentLengths. Note: extents may be + * interleaved with the chunks defined by the sample tables of tracks. + * + * The dataReferenceIndex may take the value 0, indicating a reference into the + * same file as this metadata, or an index into the dataReference table. + * + * Some referenced data may itself use offset/length techniques to address + * resources within it (e.g. an MP4 file might be included in this way). + * Normally such offsets are relative to the beginning of the containing file. + * The field base offset provides an additional offset for offset calculations + * within that contained data. For example, if an MP4 file is included within a + * file formatted to this specification, then normally data-offsets within that + * MP4 section are relative to the beginning of file; baseOffset adds to those + * offsets. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Iloc extends Zend_Media_Iso14496_Box +{ + /** @var Array */ + private $_items = array(); + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + $offsetSize = (($tmp = $this->_reader->readUInt16BE()) >> 12) & 0xf; + $lengthSize = ($tmp >> 8) & 0xf; + $baseOffsetSize = ($tmp >> 4) & 0xf; + $itemCount = $this->_reader->readUInt16BE(); + for ($i = 0; $i < $itemCount; $i++) { + $item = array(); + $item['itemId'] = $this->_reader->readUInt16BE(); + $item['dataReferenceIndex'] = $this->_reader->readUInt16BE(); + $item['baseOffset'] = + ($baseOffsetSize == 4 ? $this->_reader->readUInt32BE() : + ($baseOffsetSize == 8 ? $this->_reader->readInt64BE() : 0)); + $extentCount = $this->_reader->readUInt16BE(); + $item['extents'] = array(); + for ($j = 0; $j < $extentCount; $j++) { + $extent = array(); + $extent['offset'] = + ($offsetSize == 4 ? $this->_reader->readUInt32BE() : + ($offsetSize == 8 ? $this->_reader->readInt64BE() : 0)); + $extent['length'] = + ($lengthSize == 4 ? $this->_reader->readUInt32BE() : + ($lengthSize == 8 ? $this->_reader->readInt64BE() : 0)); + $item['extents'][] = $extent; + } + $this->_items[] = $item; + } + } + + /** + * Returns the array of items. Each entry has the following keys set: + * itemId, dataReferenceIndex, baseOffset, and extents. + * + * @return Array + */ + public function getItems() + { + return $this->_items; + } + + /** + * Sets the array of items. Each entry must have the following keys set: + * itemId, dataReferenceIndex, baseOffset, and extents. + * + * @return Array + */ + public function setItems($items) + { + $this->_items = $items; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + $totalSize = 4; + for ($i = 0; $i < count($this->_itemId); $i++) { + $totalSize += 6; + if ($this->_itemId[$i]['baseOffset'] > 0xffffffff) { + $totalSize += 8; + } else { + $totalSize += 4; + } + $extentCount = count($this->_itemId[$i]['extents']); + for ($j = 0; $j < $extentCount; $j++) { + if ($this->_itemId[$i]['extents'][$j]['offset'] > 0xffffffff) { + $totalSize += 8 * $extentCount; + } else { + $totalSize += 4 * $extentCount; + } + if ($this->_itemId[$i]['extents'][$j]['length'] > 0xffffffff) { + $totalSize += 8 * $extentCount; + } else { + $totalSize += 4 * $extentCount; + } + } + } + return parent::getHeapSize() + $totalSize; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + + $offsetSize = 4; + $lengthSize = 4; + $baseOffsetSize = 4; + + $itemCount = count($this->_itemId); + for ($i = 0; $i < $itemCount; $i++) { + if ($this->_itemId[$i]['baseOffset'] > 0xffffffff) { + $baseOffsetSize = 8; + } + for ($j = 0; $j < count($this->_itemId[$i]['extents']); $j++) { + if ($this->_itemId[$i]['extents'][$j]['offset'] > 0xffffffff) { + $offsetSize = 8; + } + if ($this->_itemId[$i]['extents'][$j]['length'] > 0xffffffff) { + $lengthSize = 8; + } + } + } + + $writer->writeUInt16BE + ((($offsetSize & 0xf) << 12) | (($lengthSize & 0xf) << 8) | + (($baseOffsetSize & 0xf) << 4)) + ->writeUInt16BE($itemCount); + for ($i = 0; $i < $itemCount; $i++) { + $writer->writeUInt16BE($this->_itemId[$i]['itemId']) + ->writeUInt16BE($this->_itemId[$i]['dataReferenceIndex']); + if ($baseOffsetSize == 4) { + $writer->writeUInt32BE($this->_itemId[$i]['baseOffset']); + } + if ($baseOffsetSize == 8) { + $writer->writeInt64BE($this->_itemId[$i]['baseOffset']); + } + $writer->writeUInt16BE + ($extentCount = count($this->_itemId[$i]['extents'])); + for ($j = 0; $j < $extentCount; $j++) { + if ($offsetSize == 4) { + $writer->writeUInt32BE + ($this->_itemId[$i]['extents'][$j]['offset']); + } + if ($offsetSize == 8) { + $writer->writeInt64BE + ($this->_itemId[$i]['extents'][$j]['offset']); + } + if ($offsetSize == 4) { + $writer->writeUInt32BE + ($this->_itemId[$i]['extents'][$j]['length']); + } + if ($offsetSize == 8) { + $writer->writeInt64BE + ($this->_itemId[$i]['extents'][$j]['length']); + } + } + } + } +} diff --git a/src/Zend/Media/Iso14496/Box/Pdin.php b/src/Zend/Media/Iso14496/Box/Pdin.php index 78a4941..a2aa936 100644 --- a/src/Zend/Media/Iso14496/Box/Pdin.php +++ b/src/Zend/Media/Iso14496/Box/Pdin.php @@ -133,7 +133,7 @@ final class Zend_Media_Iso14496_Box_Pdin extends Zend_Media_Iso14496_FullBox protected function _writeData($writer) { parent::_writeData($writer); - for ($i = 1; $i <= count($this->_timeToSampleTable); $i++) { + for ($i = 0; $i < count($this->_timeToSampleTable); $i++) { $writer->writeUInt32BE ($this->_progressiveDownloadInfo[$i]['rate']) ->writeUInt32BE diff --git a/src/Zend/Media/Iso14496/Box/Stco.php b/src/Zend/Media/Iso14496/Box/Stco.php index d1402dc..83e1796 100644 --- a/src/Zend/Media/Iso14496/Box/Stco.php +++ b/src/Zend/Media/Iso14496/Box/Stco.php @@ -78,8 +78,8 @@ final class Zend_Media_Iso14496_Box_Stco extends Zend_Media_Iso14496_FullBox parent::__construct($reader, $options); $entryCount = $this->_reader->readUInt32BE(); - for ($i = 0; $i < $entryCount; $i++) { - $this->_chunkOffsetTable[$i + 1] = $reader->readUInt32BE(); + for ($i = 1; $i <= $entryCount; $i++) { + $this->_chunkOffsetTable[$i] = $reader->readUInt32BE(); } } diff --git a/src/Zend/Media/Iso14496/Box/Tkhd.php b/src/Zend/Media/Iso14496/Box/Tkhd.php new file mode 100644 index 0000000..8a5fcf2 --- /dev/null +++ b/src/Zend/Media/Iso14496/Box/Tkhd.php @@ -0,0 +1,432 @@ +Track Header Box specifies the characteristics of a single track. + * Exactly one Track Header Box is contained in a track. + * + * In the absence of an edit list, the presentation of a track starts at the + * beginning of the overall presentation. An empty edit is used to offset the + * start time of a track. + * + * @category Zend + * @package Zend_Media + * @subpackage ISO 14496 + * @author Sven Vollbehr + * @copyright Copyright (c) 2005-2009 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + * @version $Id$ + */ +final class Zend_Media_Iso14496_Box_Tkhd extends Zend_Media_Iso14496_FullBox +{ + /** @var integer */ + private $_creationTime; + + /** @var integer */ + private $_modificationTime; + + /** @var integer */ + private $_trackId; + + /** @var integer */ + private $_duration; + + /** @var integer */ + private $_layer = 0; + + /** @var integer */ + private $_alternateGroup = 0; + + /** @var integer */ + private $_volume = 0; + + /** @var Array */ + private $_matrix = array + (0x00010000, 0, 0, 0, 0x00010000, 0, 0, 0, 0x40000000); + + /** @var integer */ + private $_width; + + /** @var integer */ + private $_height; + + /** + * Indicates that the track is enabled. A disabled track is treated as if it + * were not present. + */ + const TRACK_ENABLED = 1; + + /** Indicates that the track is used in the presentation. */ + const TRACK_IN_MOVIE = 2; + + /** Indicates that the track is used when previewing the presentation. */ + const TRACK_IN_PREVIEW = 4; + + /** + * Constructs the class with given parameters and reads box related data + * from the ISO Base Media file. + * + * @param Zend_Io_Reader $reader The reader object. + * @param Array $options The options array. + */ + public function __construct($reader, &$options = array()) + { + parent::__construct($reader, $options); + + if ($this->getVersion() == 1) { + $this->_creationTime = $this->_reader->readInt64BE(); + $this->_modificationTime = $this->_reader->readInt64BE(); + $this->_trackId = $this->_reader->readUInt32BE(); + $this->_reader->skip(4); + $this->_duration = $this->_reader->readInt64BE(); + } else { + $this->_creationTime = $this->_reader->readUInt32BE(); + $this->_modificationTime = $this->_reader->readUInt32BE(); + $this->_trackId = $this->_reader->readUInt32BE(); + $this->_reader->skip(4); + $this->_duration = $this->_reader->readUInt32BE(); + } + $this->_reader->skip(8); + $this->_layer = $this->_reader->readInt16BE(); + $this->_alternateGroup = $this->_reader->readInt16BE(); + $this->_volume = + ((($tmp = $this->_reader->readUInt16BE()) >> 8) & 0xff) + + (float)("0." . ((string)($tmp & 0xff))); + $this->_reader->skip(2); + for ($i = 0; $i < 9; $i++) { + $this->_matrix[$i] = $this->_reader->readUInt32BE(); + } + $this->_width = + ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + + (float)("0." . ((string)($tmp & 0xffff))); + $this->_height = + ((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) + + (float)("0." . ((string)($tmp & 0xffff))); + } + + /** + * Returns the creation time of this track in seconds since midnight, Jan. 1, + * 1904, in UTC time. + * + * @return integer + */ + public function getCreationTime() + { + return $this->_creationTime; + } + + /** + * Sets the creation time of this track in seconds since midnight, Jan. 1, + * 1904, in UTC time. + * + * @param integer $creationTime The creation time. + */ + public function setCreationTime() + { + $this->_creationTime = $creationTime; + } + + /** + * Returns the most recent time the track was modified in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @return integer + */ + public function getModificationTime() + { + return $this->_modificationTime; + } + + /** + * Sets the most recent time the track was modified in seconds since + * midnight, Jan. 1, 1904, in UTC time. + * + * @param integer $modificationTime The modification time. + */ + public function setModificationTime($modificationTime) + { + $this->_modificationTime = $modificationTime; + } + + /** + * Returns a number that uniquely identifies this track over the entire + * life-time of this presentation. Track IDs are never re-used and cannot be + * zero. + * + * @return integer + */ + public function getTrackId() + { + return $this->_trackId; + } + + /** + * Returns a number that uniquely identifies this track over the entire + * life-time of this presentation. Track IDs are never re-used and cannot be + * zero. + * + * @param integer $trackId The track identification. + */ + public function setTrackId($trackId) + { + $this->_trackId = $trackId; + } + + /** + * Returns the duration of this track (in the timescale indicated in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}). The value of this + * field is equal to the sum of the durations of all of the track's edits. + * If there is no edit list, then the duration is the sum of the sample + * durations, converted into the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. If the duration + * of this track cannot be determined then duration is set to all 32-bit + * maxint. + * + * @return integer + */ + public function getDuration() + { + return $this->_duration; + } + + /** + * Sets the duration of this track (in the timescale indicated in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}). The value of this + * field must be equal to the sum of the durations of all of the track's + * edits. If there is no edit list, then the duration must be the sum of the + * sample durations, converted into the timescale in the + * {@link Zend_Media_Iso14496_Box_Mvhd Movie Header Box}. If the duration + * of this track cannot be determined then duration is set to all 32-bit + * maxint. + * + * @param integer $duration The duration of this track. + */ + public function setDuration($duration) + { + $this->_duration = $duration; + } + + /** + * Returns the front-to-back ordering of video tracks; tracks with lower + * numbers are closer to the viewer. 0 is the normal value, and -1 would be + * in front of track 0, and so on. + * + * @return integer + */ + public function getLayer() + { + return $this->_layer; + } + + /** + * Sets the front-to-back ordering of video tracks; tracks with lower + * numbers are closer to the viewer. 0 is the normal value, and -1 would be + * in front of track 0, and so on. + * + * @param integer $layer The layer. + */ + public function setLayer($layer) + { + $this->_layer = $layer; + } + + /** + * Returns an integer that specifies a group or collection of tracks. If + * this field is 0 there is no information on possible relations to other + * tracks. If this field is not 0, it should be the same for tracks that + * contain alternate data for one another and different for tracks belonging + * to different such groups. Only one track within an alternate group + * should be played or streamed at any one time, and must be distinguishable + * from other tracks in the group via attributes such as bitrate, codec, + * language, packet size etc. A group may have only one member. + * + * @return integer + */ + public function getAlternateGroup() + { + return $this->_alternateGroup; + } + + /** + * Returns an integer that specifies a group or collection of tracks. If + * this field is 0 there is no information on possible relations to other + * tracks. If this field is not 0, it should be the same for tracks that + * contain alternate data for one another and different for tracks belonging + * to different such groups. Only one track within an alternate group + * should be played or streamed at any one time, and must be distinguishable + * from other tracks in the group via attributes such as bitrate, codec, + * language, packet size etc. A group may have only one member. + * + * @param integer $alternateGroup The alternate group. + */ + public function setAlternateGroup($alternateGroup) + { + $this->_alternateGroup = $alternateGroup; + } + + /** + * Returns track's relative audio volume. Full volume is 1.0 (0x0100) and + * is the normal value. Its value is irrelevant for a purely visual track. + * Tracks may be composed by combining them according to their volume, and + * then using the overall Movie Header Box volume setting; or more complex + * audio composition (e.g. MPEG-4 BIFS) may be used. + * + * @return integer + */ + public function getVolume() + { + return $this->_volume; + } + + /** + * Sets track's relative audio volume. Full volume is 1.0 (0x0100) and + * is the normal value. Its value is irrelevant for a purely visual track. + * Tracks may be composed by combining them according to their volume, and + * then using the overall Movie Header Box volume setting; or more complex + * audio composition (e.g. MPEG-4 BIFS) may be used. + * + * @param integer $volume The volume. + */ + public function setVolume($volume) + { + $this->_volume = $volume; + } + + /** + * Returns the track's visual presentation width. This needs not be the same + * as the pixel width of the images; all images in the sequence are scaled + * to this width, before any overall transformation of the track represented + * by the matrix. The pixel width of the images is the default value. + * + * @return integer + */ + public function getWidth() + { + return $this->_width; + } + + /** + * Set the track's visual presentation width. This needs not be the same + * as the pixel width of the images; all images in the sequence are scaled + * to this width, before any overall transformation of the track represented + * by the matrix. The pixel width of the images should be the default value. + * + * @param integer $width The width. + */ + public function setWidth($width) + { + $this->_width = $width; + } + + /** + * Returns the track's visual presentation height. This needs not be the + * same as the pixel height of the images; all images in the sequence are + * scaled to this height, before any overall transformation of the track + * represented by the matrix. The pixel height of the images is the default + * value. + * + * @return integer + */ + public function getHeight() + { + return $this->_height; + } + + /** + * Sets the track's visual presentation height. This needs not be the + * same as the pixel height of the images; all images in the sequence are + * scaled to this height, before any overall transformation of the track + * represented by the matrix. The pixel height of the images should be the + * default value. + * + * @param integer $height The height. + */ + public function setHeight($height) + { + $this->_height = $height; + } + + /** + * Returns the box heap size in bytes. + * + * @return integer + */ + public function getHeapSize() + { + return parent::getHeapSize() + + ($this->getVersion() == 1 ? 32 : 20) + 60; + } + + /** + * Writes the box data. + * + * @param Zend_Io_Writer $writer The writer object. + * @return void + */ + protected function _writeData($writer) + { + parent::_writeData($writer); + if ($this->getVersion() == 1) { + $writer->writeInt64BE($this->_creationTime) + ->writeInt64BE($this->_modificationTime) + ->writeUInt32BE($this->_trackId) + ->writeUInt32BE(0) + ->writeInt64BE($this->_duration); + } else { + $writer->writeUInt32BE($this->_creationTime) + ->writeUInt32BE($this->_modificationTime) + ->writeUInt32BE($this->_trackId) + ->writeUInt32BE(0) + ->writeUInt32BE($this->_duration); + } + + @list(, $volumeDecimals) = explode('.', (float)$this->_volume); + $writer->write(str_pad('', 8, "\0")) + ->writeInt16BE($this->_layer) + ->writeInt16BE($this->_alternateGroup) + ->writeUInt16BE(floor($this->_volume) << 8 | $volumeDecimals) + ->write(str_pad('', 2, "\0")); + for ($i = 0; $i < 9; $i++) { + $writer->writeUInt32BE($this->_matrix[$i]); + } + @list(, $widthDecimals) = explode('.', (float)$this->_width); + @list(, $heightDecimals) = explode('.', (float)$this->_height); + $writer->writeUInt32BE(floor($this->_width) << 16 | $widthDecimals) + ->writeUInt32BE(floor($this->_height) << 16 | $heightDecimals); + } +}