Add Zend_Media_Iso14496 class proposal

git-svn-id: http://php-reader.googlecode.com/svn/branches/zend@165 51a70ab9-7547-0410-9469-37e369ee0574
This commit is contained in:
svollbehr
2010-03-04 11:09:03 +00:00
parent 5beeabc96b
commit 9fca42586e
9 changed files with 1841 additions and 12 deletions

405
src/Zend/Media/Iso14496.php Normal file
View File

@@ -0,0 +1,405 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**#@+ @ignore */
require_once 'Zend/Media/Iso14496/Box.php';
/**#@-*/
/**
* This class represents a file in ISO base media file format as described in
* ISO/IEC 14496 Part 12 standard.
*
* The ISO Base Media File Format is designed to contain timed media information
* for a presentation in a flexible, extensible format that facilitates
* interchange, management, editing, and presentation of the media. This
* presentation may be local to the system containing the presentation, or may
* be via a network or other stream delivery mechanism.
*
* The file structure is object-oriented; a file can be decomposed into
* constituent objects very simply, and the structure of the objects inferred
* directly from their type. The file format is designed to be independent of
* any particular network protocol while enabling efficient support for them in
* general.
*
* The ISO Base Media File Format is a base format for media file formats.
*
*
* An overall view of the normal encapsulation structure is provided in the
* following table.
*
* The table shows those boxes that may occur at the top-level in the left-most
* column; indentation is used to show possible containment. Thus, for example,
* a {@link Zend_Media_Iso14496_Box_Tkhd Track Header Box} is found in a
* {@link Zend_Media_Iso14496_Box_Trak Track Box}, which is found in a
* {@link Zend_Media_Iso14496_Box_Moov Movie Box}. Not all boxes need be used
* in all files; the mandatory boxes are marked with bold typeface. See the
* description of the individual boxes for a discussion of what must be assumed
* if the optional boxes are not present.
*
* User data objects shall be placed only in
* {@link Zend_Media_Iso14496_Box_Moov Movie} or
* {@link Zend_Media_Iso14496_Box_Trak Track Boxes}, and objects using an
* extended type may be placed in a wide variety of containers, not just the
* top level.
*
* <ul>
* <li><b>ftyp</b> -- <i>{@link Zend_Media_Iso14496_Box_Ftyp File Type Box}</i>;
* file type and compatibility
* <li>pdin -- <i>{@link Zend_Media_Iso14496_Box_Pdin Progressive Download
* Information Box}</i>
* <li><b>moov</b> -- <i>{@link Zend_Media_Iso14496_Box_Moov Movie Box}</i>;
* container for all the metadata
* <ul>
* <li><b>mvhd</b> -- <i>{@link Zend_Media_Iso14496_Box_Mvhd Movie Header
* Box}</i>; overall declarations
* <li><b>trak</b> -- <i>{@link Zend_Media_Iso14496_Box_Trak Track Box}</i>;
* container for an individual track or stream
* <ul>
* <li><b>tkhd</b> -- <i>{@link Zend_Media_Iso14496_Box_Tkhd Track Header
* Box}</i>; overall information about the track
* <li>tref -- <i>{@link Zend_Media_Iso14496_Box_Tref Track Reference
* Box}</i>
* <li>edts -- <i>{@link Zend_Media_Iso14496_Box_Edts Edit Box}</i>
* <ul>
* <li>elst -- <i>{@link Zend_Media_Iso14496_Box_Elst Edit List Box}</i>
* </ul>
* <li><b>mdia</b> -- <i>{@link Zend_Media_Iso14496_Box_Mdia Media Box}</i>
* <ul>
* <li><b>mdhd</b> -- <i>{@link Zend_Media_Iso14496_Box_Mdhd Media Header
* Box}</i>; overall information about the media
* <li><b>hdlr</b> -- <i>{@link Zend_Media_Iso14496_Box_Hdlr Handler
* Reference Box}</i>; declares the media type
* <li><b>minf</b> -- <i>{@link Zend_Media_Iso14496_Box_Minf Media
* Information Box}</i>
* <ul>
* <li>vmhd -- <i>{@link Zend_Media_Iso14496_Box_Vmhd Video Media Header
* Box}</i>; overall information (video track only)
* <li>smhd -- <i>{@link Zend_Media_Iso14496_Box_Smhd Sound Media Header
* Box}</i>; overall information (sound track only)
* <li>hmhd -- <i>{@link Zend_Media_Iso14496_Box_Hmhd Hint Media Header
* Box}</i>; overall information (hint track only)
* <li>nmhd -- <i>{@link Zend_Media_Iso14496_Box_Nmhd Null Media Header
* Box}</i>; overall information (some tracks only)
* <li><b>dinf</b> -- <i>{@link Zend_Media_Iso14496_Box_Dinf Data
* Information Box}</i>
* <ul>
* <li><b>dref</b> -- <i>{@link Zend_Media_Iso14496_Box_Dref Data
* Reference Box}</i>
* </ul>
* <li><b>stbl</b> -- <i>{@link Zend_Media_Iso14496_Box_Stbl Sample
* Table Box}</i>
* <ul>
* <li><b>stsd</b> -- <i>{@link Zend_Media_Iso14496_Box_Stsd Sample
* Descriptions Box}</i>
* <li><b>stts</b> -- <i>{@link Zend_Media_Iso14496_Box_Stts Decoding
* Time To Sample Box}</i>
* <li>ctts -- <i>{@link Zend_Media_Iso14496_Box_Ctts Composition Time
* To Sample Box}</i>
* <li><b>stsc</b> -- <i>{@link Zend_Media_Iso14496_Box_Stsc Sample To
* Chunk Box}</i>
* <li>stsz -- <i>{@link Zend_Media_Iso14496_Box_Stsz Sample Size
* Box}</i>
* <li>stz2 -- <i>{@link Zend_Media_Iso14496_Box_Stz2 Compact Sample
* Size Box}</i>
* <li><b>stco</b> -- <i>{@link Zend_Media_Iso14496_Box_Stco Chunk
* Offset Box}</i>; 32-bit
* <li>co64 -- <i>{@link Zend_Media_Iso14496_Box_Co64 Chunk Ooffset
* Box}</i>; 64-bit
* <li>stss -- <i>{@link Zend_Media_Iso14496_Box_Stss Sync Sample
* Table Box}</i>
* <li>stsh -- <i>{@link Zend_Media_Iso14496_Box_Stsh Shadow Sync
* Sample Table Box}</i>
* <li>padb -- <i>{@link Zend_Media_Iso14496_Box_Padb Padding Bits
* Box}</i>
* <li>stdp -- <i>{@link Zend_Media_Iso14496_Box_Stdp Sample
* Degradation Priority Box}</i>
* <li>sdtp -- <i>{@link Zend_Media_Iso14496_Box_Sdtp Independent and
* Disposable Samples Box}</i>
* <li>sbgp -- <i>{@link Zend_Media_Iso14496_Box_Sbgp Sample To Group
* Box}</i>
* <li>sgpd -- <i>{@link Zend_Media_Iso14496_Box_Sgpd Sample Group
* Description}</i>
* <li>subs -- <i>{@link Zend_Media_Iso14496_Box_Subs Sub-Sample
* Information Box}</i>
* </ul>
* </ul>
* </ul>
* </ul>
* <li>mvex -- <i>{@link Zend_Media_Iso14496_Box_Mvex Movie Extends Box}</i>
* <ul>
* <li>mehd -- <i>{@link Zend_Media_Iso14496_Box_Mehd Movie Extends Header
* Box}</i>
* <li><b>trex</b> -- <i>{@link Zend_Media_Iso14496_Box_Trex Track Extends
* Box}</i>
* </ul>
* <li>ipmc -- <i>{@link Zend_Media_Iso14496_Box_Ipmc IPMP Control Box}</i>
* </ul>
* <li>moof -- <i>{@link Zend_Media_Iso14496_Box_Moof Movie Fragment Box}</i>
* <ul>
* <li><b>mfhd</b> -- <i>{@link Zend_Media_Iso14496_Box_Mfhd Movie Fragment
* Header Box}</i>
* <li>traf -- <i>{@link Zend_Media_Iso14496_Box_Traf Track Fragment Box}</i>
* <ul>
* <li><b>tfhd</b> -- <i>{@link Zend_Media_Iso14496_Box_Tfhd Track Fragment
* Header Box}</i>
* <li>trun -- <i>{@link Zend_Media_Iso14496_Box_Trun Track Fragment
* Run}</i>
* <li>sdtp -- <i>{@link Zend_Media_Iso14496_Box_Sdtp Independent and
* Disposable Samples}</i>
* <li>sbgp -- <i>{@link Zend_Media_Iso14496_Box_Sbgp !SampleToGroup
* Box}</i>
* <li>subs -- <i>{@link Zend_Media_Iso14496_Box_Subs Sub-Sample Information
* Box}</i>
* </ul>
* </ul>
* <li>mfra -- <i>{@link Zend_Media_Iso14496_Box_Mfra Movie Fragment Random
* Access Box}</i>
* <ul>
* <li>tfra -- <i>{@link Zend_Media_Iso14496_Box_Tfra Track Fragment Random
* Access Box}</i>
* <li><b>mfro</b> -- <i>{@link Zend_Media_Iso14496_Box_Mfro Movie Fragment
* Random Access Offset Box}</i>
* </ul>
* <li>mdat -- <i>{@link Zend_Media_Iso14496_Box_Mdat Media Data Box}</i>
* <li>free -- <i>{@link Zend_Media_Iso14496_Box_Free Free Space Box}</i>
* <li>skip -- <i>{@link Zend_Media_Iso14496_Box_Skip Free Space Box}</i>
* <ul>
* <li>udta -- <i>{@link Zend_Media_Iso14496_Box_Udta User Data Box}</i>
* <ul>
* <li>cprt -- <i>{@link Zend_Media_Iso14496_Box_Cprt Copyright Box}</i>
* </ul>
* </ul>
* <li>meta -- <i>{@link Zend_Media_Iso14496_Box_Meta The Meta Box}</i>
* <ul>
* <li><b>hdlr</b> -- <i>{@link Zend_Media_Iso14496_Box_Hdlr Handler Reference
* Box}</i>; declares the metadata type
* <li>dinf -- <i>{@link Zend_Media_Iso14496_Box_Dinf Data Information
* Box}</i>
* <ul>
* <li>dref -- <i>{@link Zend_Media_Iso14496_Box_Dref Data Reference
* Box}</i>; declares source(s) of metadata items
* </ul>
* <li>ipmc -- <i>{@link Zend_Media_Iso14496_Box_Ipmc IPMP Control Box}</i>
* <li>iloc -- <i>{@link Zend_Media_Iso14496_Box_Iloc Item Location Box}</i>
* <li>ipro -- <i>{@link Zend_Media_Iso14496_Box_Ipro Item Protection Box}</i>
* <ul>
* <li>sinf -- <i>{@link Zend_Media_Iso14496_Box_Sinf Protection Scheme
* Information Box}</i>
* <ul>
* <li>frma -- <i>{@link Zend_Media_Iso14496_Box_Frma Original Format
* Box}</i>
* <li>imif -- <i>{@link Zend_Media_Iso14496_Box_Imif IPMP Information
* Box}</i>
* <li>schm -- <i>{@link Zend_Media_Iso14496_Box_Schm Scheme Type Box}</i>
* <li>schi -- <i>{@link Zend_Media_Iso14496_Box_Schi Scheme Information
* Box}</i>
* </ul>
* </ul>
* <li>iinf -- <i>{@link Zend_Media_Iso14496_Box_Iinf Item Information
* Box}</i>
* <ul>
* <li>infe -- <i>{@link Zend_Media_Iso14496_Box_Infe Item Information Entry
* Box}</i>
* </ul>
* <li>xml -- <i>{@link Zend_Media_Iso14496_Box_Xml XML Box}</i>
* <li>bxml -- <i>{@link Zend_Media_Iso14496_Box_Bxml Binary XML Box}</i>
* <li>pitm -- <i>{@link Zend_Media_Iso14496_Box_Pitm Primary Item Reference
* Box}</i>
* </ul>
* </ul>
*
* There are two non-standard extensions to the ISO 14496 standard that add the
* ability to include file meta information. Both the boxes reside under
* moov.udta.meta.
*
* <ul>
* <li><i>moov</i> -- <i>{@link Zend_Media_Iso14496_Box_Moov Movie Box}</i>;
* container for all the metadata
* <li><i>udta</i> -- <i>{@link Zend_Media_Iso14496_Box_Udta User Data Box}</i>
* <li><i>meta</i> -- <i>{@link Zend_Media_Iso14496_Box_Meta The Meta Box}</i>
* <ul>
* <li>ilst -- <i>{@link Zend_Media_Iso14496_Box_Ilst The iTunes/iPod Tag
* Container Box}</i>
* <li>id32 -- <i>{@link Zend_Media_Iso14496_Box_Id32 The ID3v2 Box}</i>
* </ul>
* </ul>
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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 extends Zend_Media_Iso14496_Box
{
/** @var string */
private $_filename;
/**
* Constructs the Zend_Media_Iso14496 class with given file and options.
*
* The following options are currently recognized:
* o base -- Indicates that only boxes with the given base path are parsed
* from the ISO base media file. Parsing all boxes can possibly have a
* significant impact on running time. Base path is a list of nested
* boxes separated by a dot. The use of base option implies readonly
* option.
* o readonly -- Indicates that the file is read from a temporary location
* or another source it cannot be written back to.
*
* @param string|resource|Zend_Io_Reader $filename The path to the file,
* file descriptor of an opened file, or a {@link Zend_Io_Reader} instance.
* @param Array $options The options array.
*/
public function __construct($filename, $options = array())
{
if (isset($options['base'])) {
$options['readonly'] = true;
}
if ($filename instanceof Zend_Io_Reader) {
$this->_reader = &$filename;
} else {
require_once 'Zend/Io/FileReader.php';
try {
$this->_reader = new Zend_Io_FileReader($filename);
} catch (Zend_Io_Exception $e) {
$this->_reader = null;
require_once 'Zend/Media/Id3/Exception.php';
throw new Zend_Media_Iso14496_Exception($e->getMessage());
}
if (is_string($filename) && !isset($options['readonly'])) {
$this->_filename = $filename;
}
}
$this->setOptions($options);
$this->setOffset(0);
$this->setSize($this->_reader->getSize());
$this->setType('file');
$this->setContainer(true);
$this->constructBoxes();
}
/**
* Writes the changes back to the original media file. If the class was
* constructed without a file name, one can be provided here as an argument.
*
* The write operation commits only changes made to the Movie Box. It
* further changes the order of the Movie Box and Media Data Box in a way
* compatible for progressive download from a web page.
*
* All file offsets must be assumed to be invalid after the write operation.
*
* @param string $filename The optional path to the file, use null to save
* to the same file.
*/
public function write($filename)
{
if ($filename === null && ($filename = $this->_filename) === null) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception
('No file given to write the tag to');
} else if ($filename !== null && $this->_filename !== null &&
realpath($filename) != realpath($this->_filename) &&
!copy($this->_filename, $filename)) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception
('Unable to copy source to destination: ' .
realpath($this->_filename) . '->' . realpath($filename));
}
if (($fd = fopen
($filename, file_exists($filename) ? 'r+b' : 'wb')) === false) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception
('Unable to open file for writing: ' . $filename);
}
/* Calculate file size */
fseek($fd, 0, SEEK_END);
$oldFileSize = ftell($fd);
$oldMoovSize = $this->moov->getSize();
$this->moov->udta->meta->free->setSize(8);
$this->moov->udta->meta->hdlr->setHandlerType('mdir');
$newFileSize = $oldFileSize - $oldMoovSize + $this->moov->getHeapSize();
/* Calculate free space size */
if ($oldFileSize < $newFileSize ||
$this->mdat->getOffset() < $this->moov->getOffset()) {
// Add constant 4096 bytes for free space to be used later
$this->moov->udta->meta->free->setSize(8 /* header */ + 4096);
ftruncate($fd, $newFileSize += 4096);
} else {
// Adjust free space to fill up the rest of the space
$this->moov->udta->meta->free->setSize
(8 + $oldFileSize - $newFileSize);
$newFileSize = $oldFileSize;
}
/* Calculate positions */
if ($this->mdat->getOffset() < $this->moov->getOffset()) {
$start = $this->mdat->getOffset();
$until = $this->moov->getOffset();
$where = $newFileSize;
$delta = $this->moov->getHeapSize();
} else {
$start = $this->moov->getOffset();
$until = $oldFileSize;
$where = $newFileSize;
$delta = $newFileSize - $oldFileSize;
}
/* Move data to the end of the file */
if ($newFileSize != $oldFileSize) {
for ($i = 1, $cur = $until; $cur > $start; $cur -= 1024, $i++) {
fseek
($fd, $until - (($i * 1024) +
($excess = $cur - 1024 > $start ?
0 : $cur - $start - 1024)));
$buffer = fread($fd, 1024);
fseek($fd, $where - (($i * 1024) + $excess));
fwrite($fd, $buffer, 1024);
}
}
/* Update stco/co64 to correspond the data move */
foreach ($this->moov->getBoxesByIdentifier('trak') as $trak) {
$chunkOffsetBox =
(isset($trak->mdia->minf->stbl->stco) ?
$trak->mdia->minf->stbl->stco :
$trak->mdia->minf->stbl->co64);
$chunkOffsetTable = $chunkOffsetBox->getChunkOffsetTable();
$chunkOffsetTableCount = count($chunkOffsetTable);
for ($i = 1; $i <= $chunkOffsetTableCount; $i++) {
$chunkOffsetTable[$i] += $delta;
}
$chunkOffsetBox->setChunkOffsetTable($chunkOffsetTable);
}
/* Write moov box */
fseek($fd, $start);
$this->moov->write(new Zend_Io_Writer($fd));
fclose($fd);
}
}

View File

@@ -0,0 +1,663 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**
* A base class for all ISO 14496-12 boxes.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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$
*/
class Zend_Media_Iso14496_Box
{
/**
* The reader object.
*
* @var Reader
*/
protected $_reader;
/** @var Array */
private $_options;
/** @var integer */
private $_offset = -1;
/** @var integer */
private $_size = -1;
/** @var string */
private $_type;
/** @var Zend_Media_Iso14496_Box */
private $_parent = null;
/** @var boolean */
private $_container = false;
/** @var Array */
private $_boxes = array();
/** @var Array */
private static $_path = array();
/**
* Constructs the class with given parameters and options.
*
* @param Zend_Io_Reader $reader The reader object.
* @param Array $options The options array.
*/
public function __construct($reader, &$options = array())
{
if (($this->_reader = $reader) === null) {
$this->_type = strtolower(substr(get_class($this), -4));
} else {
$this->_offset = $this->_reader->getOffset();
$this->_size = $this->_reader->readUInt32BE();
$this->_type = $this->_reader->read(4);
if ($this->_size == 1) {
$this->_size = $this->_reader->readInt64BE();
}
if ($this->_size == 0) {
$this->_size = $this->_reader->getSize() - $this->_offset;
}
if ($this->_type == 'uuid') {
$this->_type = $this->_reader->readGUID();
}
}
$this->_options = &$options;
}
public function __destruct()
{
unset($this->_boxes);
unset($this->_parent);
}
/**
* Returns the options array.
*
* @return Array
*/
public final function &getOptions()
{
return $this->_options;
}
/**
* Returns the given option value, or the default value if the option is not
* defined.
*
* @param string $option The name of the option.
* @param mixed $defaultValue The default value to be returned.
*/
public final function getOption($option, $defaultValue = null)
{
if (isset($this->_options[$option])) {
return $this->_options[$option];
}
return $defaultValue;
}
/**
* Sets the options array. See {@link Zend_Media_Id3v2} class for available
* options.
*
* @param Array $options The options array.
*/
public final function setOptions(&$options)
{
$this->_options = &$options;
}
/**
* Sets the given option the given value.
*
* @param string $option The name of the option.
* @param mixed $value The value to set for the option.
*/
public final function setOption($option, $value)
{
$this->_options[$option] = $value;
}
/**
* Clears the given option value.
*
* @param string $option The name of the option.
*/
public final function clearOption($option)
{
unset($this->_options[$option]);
}
/**
* Returns the file offset to box start, or -1 if the box was created on heap.
*
* @return integer
*/
public final function getOffset()
{
return $this->_offset;
}
/**
* Sets the file offset where the box starts.
*
* @param integer $offset The file offset to box start.
*/
public final function setOffset($offset)
{
$this->_offset = $offset;
}
/**
* Returns the box size in bytes read from the file, including the size and
* type header, fields, and all contained boxes, or -1 if the box was
* created on heap.
*
* @return integer
*/
public final function getSize()
{
return $this->_size;
}
/**
* Sets the box size. The size must include the size and type header,
* fields, and all contained boxes.
*
* The method will propagate size change to box parents.
*
* @param integer $size The box size.
*/
protected final function setSize($size)
{
if ($this->_parent !== null) {
$this->_parent->setSize
(($this->_parent->getSize() > 0 ?
$this->_parent->getSize() : 0) +
$size - ($this->_size > 0 ? $this->_size : 0));
}
$this->_size = $size;
}
/**
* Returns the box type.
*
* @return string
*/
public final function getType()
{
return $this->_type;
}
/**
* Sets the box type.
*
* @param string $type The box type.
*/
public final function setType($type)
{
$this->_type = $type;
}
/**
* Returns the parent box containing this box.
*
* @return Zend_Media_Iso14496_Box
*/
public final function getParent()
{
return $this->_parent;
}
/**
* Sets the parent containing box.
*
* @param Zend_Media_Iso14496_Box $parent The parent box.
*/
public function setParent(&$parent)
{
$this->_parent = $parent;
}
/**
* Returns a boolean value corresponding to whether the box is a container.
*
* @return boolean
*/
public final function isContainer()
{
return $this->_container;
}
/**
* Returns a boolean value corresponding to whether the box is a container.
*
* @return boolean
*/
public final function getContainer()
{
return $this->_container;
}
/**
* Sets whether the box is a container.
*
* @param boolean $container Whether the box is a container.
*/
protected final function setContainer($container)
{
$this->_container = $container;
}
/**
* Reads and constructs the boxes found within this box.
*
* @todo Does not parse iTunes internal ---- boxes.
*/
protected final function constructBoxes
($defaultclassname = 'Zend_Media_Iso14496_Box')
{
$base = $this->getOption('base', '');
if ($this->getType() != 'file') {
self::$_path[] = $this->getType();
}
$path = implode(self::$_path, '.');
while (true) {
$offset = $this->_reader->getOffset();
if ($offset >= $this->_offset + $this->_size) {
break;
}
$size = $this->_reader->readUInt32BE();
$type = rtrim($this->_reader->read(4), ' ');
if ($size == 1) {
$size = $this->_reader->readInt64BE();
}
if ($size == 0) {
$size = $this->_reader->getSize() - $offset;
}
if (preg_match("/^\xa9?[a-z0-9]{3,4}$/i", $type) &&
substr($base, 0, min(strlen($base), strlen
($tmp = $path . ($path ? '.' : '') . $type))) ==
substr($tmp, 0, min(strlen($base), strlen($tmp))))
{
$this->_reader->setOffset($offset);
if (@fopen($filename = 'Zend/Media/Iso14496/Box/' .
ucfirst($type) . '.php', 'r', true) !== false) {
require_once($filename);
}
if (class_exists
($classname = 'Zend_Media_Iso14496_Box_' .
ucfirst($type))) {
$box = new $classname($this->_reader, $this->_options);
} else {
$box =
new $defaultclassname($this->_reader, $this->_options);
}
$box->setParent($this);
if (!isset($this->_boxes[$box->getType()])) {
$this->_boxes[$box->getType()] = array();
}
$this->_boxes[$box->getType()][] = $box;
}
$this->_reader->setOffset($offset + $size);
}
array_pop(self::$_path);
}
/**
* Checks whether the box given as an argument is present in the file. Returns
* <var>true</var> if one or more boxes are present, <var>false</var>
* otherwise.
*
* @param string $identifier The box identifier.
* @return boolean
* @throws Zend_Media_Iso14496_Exception if called on a non-container box
*/
public final function hasBox($identifier)
{
if (!$this->isContainer()) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Box not a container');
}
return isset($this->_boxes[$identifier]);
}
/**
* Returns all the boxes the file contains as an associate array. The box
* identifiers work as keys having an array of boxes as associated value.
*
* @return Array
* @throws Zend_Media_Iso14496_Exception if called on a non-container box
*/
public final function getBoxes()
{
if (!$this->isContainer()) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Box not a container');
}
return $this->_boxes;
}
/**
* Returns an array of boxes matching the given identifier or an empty array
* if no boxes matched the identifier.
*
* The identifier may contain wildcard characters '*' and '?'. The asterisk
* matches against zero or more characters, and the question mark matches
* any single character.
*
* Please note that one may also use the shorthand $obj->identifier to
* access the first box with the identifier given. Wildcards cannot be used
* with the shorthand and they will not work with user defined uuid types.
*
* @param string $identifier The box identifier.
* @return Array
* @throws Zend_Media_Iso14496_Exception if called on a non-container box
*/
public final function getBoxesByIdentifier($identifier)
{
if (!$this->isContainer()) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Box not a container');
}
$matches = array();
$searchPattern = "/^" .
str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i";
foreach ($this->_boxes as $identifier => $boxes) {
if (preg_match($searchPattern, $identifier)) {
foreach ($boxes as $box) {
$matches[] = $box;
}
}
}
return $matches;
}
/**
* Removes any boxes matching the given box identifier.
*
* The identifier may contain wildcard characters '*' and '?'. The asterisk
* matches against zero or more characters, and the question mark matches any
* single character.
*
* One may also use the shorthand unset($obj->identifier) to achieve the same
* result. Wildcards cannot be used with the shorthand method.
*
* @param string $identifier The box identifier.
* @throws Zend_Media_Iso14496_Exception if called on a non-container box
*/
public final function removeBoxesByIdentifier($identifier)
{
if (!$this->isContainer()) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception("Box not a container");
}
$searchPattern = "/^" .
str_replace(array("*", "?"), array(".*", "."), $identifier) . "$/i";
foreach ($this->_objects as $identifier => $objects) {
if (preg_match($searchPattern, $identifier)) {
unset($this->_objects[$identifier]);
}
}
}
/**
* Adds a new box into the current box and returns it.
*
* @param Zend_Media_Iso14496_Box $box The box to add
* @return Zend_Media_Iso14496_Box
* @throws Zend_Media_Iso14496_Exception if called on a non-container box
*/
public final function addBox(&$box)
{
if (!$this->isContainer()) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Box not a container');
}
$box->setParent($this);
$box->setOptions($this->_options);
if (!$this->hasBox($box->getType())) {
$this->_boxes[$box->getType()] = array();
}
return $this->_boxes[$box->getType()][] = $box;
}
/**
* Removes the given box.
*
* @param Zend_Media_Iso14496_Box $box The box to remove
* @throws Zend_Media_Iso14496_Exception if called on a non-container box
*/
public final function removeBox($box)
{
if (!$this->isContainer()) {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Box not a container');
}
if ($this->hasBox($box->getType())) {
foreach ($this->_boxes[$box->getType()] as $key => $value) {
if ($box === $value) {
unset($this->_boxes[$box->getType()][$key]);
}
}
}
}
/**
* Returns the number of boxes this box contains.
*
* @return integer
*/
public final function getBoxCount()
{
if (!$this->isContainer()) {
return 0;
}
return count($this->_boxes);
}
/**
* Magic function so that $obj->value will work. If called on a container box,
* the method will first attempt to return the first contained box that
* matches the identifier, and if not found, invoke a getter method.
*
* If there are no boxes or getter methods with given name, the method
* attempts to create a frame with given identifier.
*
* If none of these work, an exception is thrown.
*
* @param string $name The box or field name.
* @return mixed
*/
public function __get($name)
{
if ($this->isContainer() &&
isset($this->_boxes[str_pad($name, 4, ' ')])) {
return $this->_boxes[str_pad($name, 4, ' ')][0];
}
if (method_exists($this, 'get' . ucfirst($name))) {
return call_user_func(array($this, 'get' . ucfirst($name)));
}
if (@fopen($filename = 'Zend/Media/Iso14496/Box/' .
ucfirst($name) . '.php', 'r', true) !== false) {
require_once($filename);
}
if (class_exists
($classname = 'Zend_Media_Iso14496_Box_' . ucfirst($name))) {
return $this->addBox(new $classname());
}
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Unknown box/field: ' . $name);
}
/**
* Magic function so that assignments with $obj->value will work.
*
* @param string $name The field name.
* @param string $value The field value.
* @return mixed
*/
public function __set($name, $value)
{
if (method_exists($this, 'set' . ucfirst($name))) {
call_user_func(array($this, 'set' . ucfirst($name)), $value);
} else {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception('Unknown field: ' . $name);
}
}
/**
* Magic function so that isset($obj->value) will work. This method checks
* whether the box is a container and contains a box that matches the
* identifier.
*
* @param string $name The box name.
* @return boolean
*/
public function __isset($name)
{
return ($this->isContainer() && isset($this->_boxes[$name]));
}
/**
* Magic function so that unset($obj->value) will work. This method removes
* all the boxes from this container that match the identifier.
*
* @param string $name The box name.
*/
public function __unset($name)
{
if ($this->isContainer()) {
unset($this->_boxes[$name]);
}
}
/**
* Returns the box heap size in bytes, including the size and
* type header, fields, and all contained boxes. The box size is updated to
* reflect that of the heap size upon write. Subclasses should overwrite
* this method and call the parent method to get the calculated header and
* subbox sizes and then add their own bytes to that.
*
* @return integer
*/
public function getHeapSize()
{
$size = 8;
if ($this->isContainer()) {
foreach ($this->getBoxes() as $name => $boxes) {
foreach ($boxes as $box) {
$size += $box->getHeapSize();
}
}
}
if ($size > 0xffffffff) {
$size += 8;
}
if (strlen($this->_type) > 4) {
$size += 16;
}
return $size;
}
/**
* Writes the box header. Subclasses should overwrite this method and call
* the parent method first and then write the box related data.
*
* @param Zend_Io_Writer $writer The writer object.
* @return void
*/
protected function _writeData($writer)
{
if (get_class($this) == "Zend_Media_Iso14496_Box") {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception
('Unknown box \'' . $this->getType() . '\' cannot be written.');
}
$this->_size = $this->getHeapSize();
if ($this->_size > 0xffffffff) {
$writer->writeUInt32BE(1);
} else {
$writer->writeUInt32BE($this->_size);
}
if (strlen($this->_type) > 4) {
$writer->write('uuid');
} else {
$writer->write($this->_type);
}
if ($this->_size > 0xffffffff) {
$writer->writeInt64BE($this->_size);
}
if (strlen($this->_type) > 4) {
$writer->writeGuid($this->_type);
}
}
/**
* Writes the frame data with the header.
*
* @param Zend_Io_Writer $writer The writer object.
* @return void
*/
public function write($writer)
{
if (get_class($this) == "Zend_Media_Iso14496_Box") {
require_once 'Zend/Media/Iso14496/Exception.php';
throw new Zend_Media_Iso14496_Exception
('Unknown box \'' . $this->getType() . '\' cannot be written.');
}
$this->_writeData($writer);
if ($this->isContainer()) {
foreach ($this->getBoxes() as $name => $boxes) {
foreach ($boxes as $box) {
$box->write($writer);
}
}
}
}
}

View File

@@ -67,7 +67,7 @@ final class Zend_Media_Iso14496_Box_Elst extends Zend_Media_Iso14496_FullBox
parent::__construct($reader, $options);
$entryCount = $this->_reader->readUInt32BE();
for ($i = 1; $i <= $entryCount; $i++) {
for ($i = 0; $i < $entryCount; $i++) {
$entry = array();
if ($this->getVersion() == 1) {
$entry['segmentDuration'] = $this->_reader->readInt64BE();
@@ -77,8 +77,8 @@ final class Zend_Media_Iso14496_Box_Elst extends Zend_Media_Iso14496_FullBox
$entry['mediaTime'] = $this->_reader->readInt32BE();
}
$entry['mediaRate'] =
((($tmp = $this->_reader->readUInt32BE()) >> 16) & 0xffff) +
(float)("0." . ((string)($tmp & 0xffff)));
(float)($this->_reader->readInt16BE() . "." .
$this->_reader->readInt16BE());
$this->_entries[] = $entry;
}
}
@@ -152,19 +152,18 @@ final class Zend_Media_Iso14496_Box_Elst extends Zend_Media_Iso14496_FullBox
{
parent::_writeData($writer);
$writer->writeUInt32BE($entryCount = count($this->_entries));
for ($i = 1; $i <= $entryCount; $i++) {
for ($i = 0; $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']);
->writeInt32BE($this->_entries[$i]['mediaTime']);
}
@list(, $mediaRateDecimals) = explode
@list($mediaRateInteger, $mediaRateFraction) = explode
('.', (float)$this->_entries[$i]['mediaRate']);
$writer->writeUInt32BE
(floor($this->_entries[$i]['mediaRate']) << 16 |
$mediaRateDecimals);
$writer->writeInt16BE($mediaRateInteger)
->writeInt16BE($mediaRateFraction);
}
}
}

View File

@@ -70,7 +70,7 @@ final class Zend_Media_Iso14496_Box_Free extends Zend_Media_Iso14496_Box
*/
public function getHeapSize()
{
return parent::getHeapSize() + $this->getSize();
return ($this->getSize() >= 8 ? $this->getSize() : 0);
}
/**
@@ -81,7 +81,9 @@ final class Zend_Media_Iso14496_Box_Free extends Zend_Media_Iso14496_Box
*/
protected function _writeData($writer)
{
parent::_writeData($writer);
$writer->write(str_repeat("\0", $this->getSize()));
if ($this->getSize() >= 8) {
parent::_writeData($writer);
$writer->write(str_repeat("\0", $this->getSize() - 8));
}
}
}

View File

@@ -0,0 +1,197 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**#@+ @ignore */
require_once 'Zend/Media/Iso14496/FullBox.php';
/**#@-*/
/**
* The <i>Sample To Group Box</i> table can be used to find the group that a
* sample belongs to and the associated description of that sample group. The
* table is compactly coded with each entry giving the index of the first sample
* of a run of samples with the same sample group descriptor. The sample group
* description ID is an index that refers to a
* {@link Zend_Media_Iso14496_Box_Sgpd Sample Group Description Box}, which
* contains entries describing the characteristics of each sample group.
*
* There may be multiple instances of this box if there is more than one sample
* grouping for the samples in a track. Each instance of the Sample To Group Box
* has a type code that distinguishes different sample groupings. Within a
* track, there shall be at most one instance of this box with a particular
* grouping type. The associated Sample Group Description shall indicate the
* same value for the grouping type.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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_Sbgp extends Zend_Media_Iso14496_FullBox
{
/** @var integer */
private $_groupingType;
/** @var Array */
private $_sampleToGroupTable = 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);
$groupingType = $this->_reader->readUInt32BE();
$entryCount = $this->_reader->readUInt32BE();
for ($i = 1; $i <= $entryCount; $i++) {
$this->_sampleToGroupTable[$i] = array
('sampleCount' => $this->_reader->readUInt32BE(),
'groupDescriptionIndex' => $this->_reader->readUInt32BE());
}
}
/**
* Returns the grouping type that identifies the type (i.e. criterion used
* to form the sample groups) of the sample grouping and links it to its
* sample group description table with the same value for grouping type. At
* most one occurrence of this box with the same value for groupingType
* shall exist for a track.
*
* @return integer
*/
public function getGroupingType()
{
return $this->_groupingType;
}
/**
* Sets the grouping type that identifies the type (i.e. criterion used
* to form the sample groups) of the sample grouping and links it to its
* sample group description table with the same value for grouping type. At
* most one occurrence of this box with the same value for groupingType
* shall exist for a track.
*
* @param integer $groupingType The grouping type.
*/
public function setGroupingType($groupingType)
{
$this->_groupingType = $groupingType;
}
/**
* Returns an array of values. Each entry is an array containing the
* following keys.
* o sampleCount -- an integer that gives the number of consecutive
* samples with the same sample group descriptor. If the sum of the
* sample count in this box is less than the total sample count, then
* the reader should effectively extend it with an entry that associates
* the remaining samples with no group. It is an error for the total in
* this box to be greater than the sample_count documented elsewhere,
* and the reader behavior would then be undefined.
* o groupDescriptionIndex -- an integer that gives the index of the
* sample group entry which describes the samples in this group. The
* index ranges from 1 to the number of sample group entries in the
* {@link Zend_Media_Iso14496_Box_Sgpd Sample Group Description Box},
* or takes the value 0 to indicate that this sample is a member of no
* group of this type.
*
* @return Array
*/
public function getSampleToGroupTable()
{
return $this->_sampleToGroupTable;
}
/**
* Sets the array of values. Each entry must be an array containing the
* following keys.
* o sampleCount -- an integer that gives the number of consecutive
* samples with the same sample group descriptor. If the sum of the
* sample count in this box is less than the total sample count, then
* the reader should effectively extend it with an entry that associates
* the remaining samples with no group. It is an error for the total in
* this box to be greater than the sample_count documented elsewhere,
* and the reader behavior would then be undefined.
* o groupDescriptionIndex -- an integer that gives the index of the
* sample group entry which describes the samples in this group. The
* index ranges from 1 to the number of sample group entries in the
* {@link Zend_Media_Iso14496_Box_Sgpd Sample Group Description Box},
* or takes the value 0 to indicate that this sample is a member of no
* group of this type.
*
* @param Array $sampleToGroupTable The array of entries
*/
public function setSampleToGroupTable($sampleToGroupTable)
{
$this->_sampleToGroupTable = $sampleToGroupTable;
}
/**
* Returns the box heap size in bytes.
*
* @return integer
*/
public function getHeapSize()
{
return parent::getHeapSize() + 8 +
count($this->_sampleToGroupTable) * 8;
}
/**
* Writes the box data.
*
* @param Zend_Io_Writer $writer The writer object.
* @return void
*/
protected function _writeData($writer)
{
parent::_writeData($writer);
$writer->writeUInt32BE($this->_groupingType);
$writer->writeUInt32BE($entryCount = count($this->_sampleToGroupTable));
for ($i = 1; $i <= $entryCount; $i++) {
$writer->writeUInt32BE
($this->_sampleToGroupTable[$i]['sampleCount'])
->writeUInt32BE
($this->_sampleToGroupTable[$i]
['groupDescriptionIndex']);
}
}
}

View File

@@ -0,0 +1,177 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**#@+ @ignore */
require_once 'Zend/Media/Iso14496/FullBox.php';
/**#@-*/
/**
* The <i>Scheme Type Box</i> identifies the protection scheme.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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_Schm extends Zend_Media_Iso14496_FullBox
{
/** @var string */
private $_schemeType;
/** @var integer */
private $_schemeVersion;
/** @var string */
private $_schemeUri;
/**
* 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->_schemeType = $this->_reader->read(4);
$this->_schemeVersion = $this->_reader->readUInt32BE();
if ($this->hasFlag(1)) {
$this->_schemeUri = preg_split
("/\\x00/", $this->_reader->read
($this->getOffset() + $this->getSize() -
$this->_reader->getOffset()));
}
}
/**
* Returns the code defining the protection scheme.
*
* @return string
*/
public function getSchemeType()
{
return $this->_schemeType;
}
/**
* Sets the code defining the protection scheme.
*
* @param string $schemeType The scheme type.
*/
public function setSchemeType($schemeType)
{
$this->_schemeType = $schemeType;
}
/**
* Returns the version of the scheme used to create the content.
*
* @return integer
*/
public function getSchemeVersion()
{
return $this->_schemeVersion;
}
/**
* Sets the version of the scheme used to create the content.
*
* @param integer $schemeVersion The scheme version.
*/
public function setSchemeVersion($schemeVersion)
{
$this->_schemeVersion = $schemeVersion;
}
/**
* Returns the optional scheme address to allow for the option of directing
* the user to a web-page if they do not have the scheme installed on their
* system. It is an absolute URI.
*
* @return string
*/
public function getSchemeUri()
{
return $this->_schemeUri;
}
/**
* Sets the optional scheme address to allow for the option of directing
* the user to a web-page if they do not have the scheme installed on their
* system. It is an absolute URI.
*
* @param string $schemeUri The scheme URI.
*/
public function setSchemeUri($schemeUri)
{
$this->_schemeUri = $schemeUri;
if ($schemeUri === null) {
$this->setFlags(0);
} else {
$this->setFlags(1);
}
}
/**
* Returns the box heap size in bytes.
*
* @return integer
*/
public function getHeapSize()
{
return parent::getHeapSize() + 8 +
($this->hasFlag(1) ? strlen($this->_schemeUri) + 1 : 0);
}
/**
* Writes the box data.
*
* @param Zend_Io_Writer $writer The writer object.
* @return void
*/
protected function _writeData($writer)
{
parent::_writeData($writer);
$writer->write($this->_schemeType);
$writer->writeUInt32BE($this->_schemeVersion);
if ($this->hasFlag(1)) {
$writer->writeString8($this->_schemeUri, 1);
}
}
}

View File

@@ -0,0 +1,187 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**#@+ @ignore */
require_once 'Zend/Media/Iso14496/FullBox.php';
/**#@-*/
/**
* The <i>Independent and Disposable Samples Box</i> optional table answers
* three questions about sample dependency:
* 1) does this sample depend on others (is it an I-picture)?
* 2) do no other samples depend on this one?
* 3) does this sample contain multiple (redundant) encodings of the data at
* this time-instant (possibly with different dependencies)?
*
* In the absence of this table:
* 1) the sync sample table answers the first question; in most video codecs,
* I-pictures are also sync points,
* 2) the dependency of other samples on this one is unknown.
* 3) the existence of redundant coding is unknown.
*
* When performing trick modes, such as fast-forward, it is possible to use the
* first piece of information to locate independently decodable samples.
* Similarly, when performing random access, it may be necessary to locate the
* previous sync point or random access recovery point, and roll-forward from
* the sync point or the pre-roll starting point of the random access recovery
* point to the desired point. While rolling forward, samples on which no others
* depend need not be retrieved or decoded.
*
* The value of sampleIsDependedOn is independent of the existence of redundant
* codings. However, a redundant coding may have different dependencies from the
* primary coding; if redundant codings are available, the value of
* sampleDependsOn documents only the primary coding.
*
* A sample dependency Box may also occur in the
* {@link Zend_Media_Iso14496_Box_Traf Track Fragment Box}.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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_Sdtp extends Zend_Media_Iso14496_FullBox
{
/** @var Array */
private $_sampleDependencyTypeTable = 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);
$data = $this->_reader->read
($this->getOffset() + $this->getSize() -
$this->_reader->getOffset());
$dataSize = strlen($data);
for ($i = 1; $i <= $dataSize; $i++) {
$this->_sampleDependencyTypeTable[$i] = array
('sampleDependsOn' => (($tmp = ord($data[$i - 1])) >> 4) & 0x3,
'sampleIsDependedOn' => ($tmp >> 2) & 0x3,
'sampleHasRedundancy' => $tmp & 0x3);
}
}
/**
* Returns an array of values. Each entry is an array containing the
* following keys.
* o sampleDependsOn -- takes one of the following four values:
* 0: the dependency of this sample is unknown;
* 1: this sample does depend on others (not an I picture);
* 2: this sample does not depend on others (I picture);
* 3: reserved
* o sampleIsDependedOn -- takes one of the following four values:
* 0: the dependency of other samples on this sample is unknown;
* 1: other samples depend on this one (not disposable);
* 2: no other sample depends on this one (disposable);
* 3: reserved
* o sampleHasRedundancy -- takes one of the following four values:
* 0: it is unknown whether there is redundant coding in this sample;
* 1: there is redundant coding in this sample;
* 2: there is no redundant coding in this sample;
* 3: reserved
*
* @return Array
*/
public function getSampleDependencyTypeTable()
{
return $this->_sampleDependencyTypeTable;
}
/**
* Sets the array of values. Each entry must be an array containing the
* following keys.
* o sampleDependsOn -- takes one of the following four values:
* 0: the dependency of this sample is unknown;
* 1: this sample does depend on others (not an I picture);
* 2: this sample does not depend on others (I picture);
* 3: reserved
* o sampleIsDependedOn -- takes one of the following four values:
* 0: the dependency of other samples on this sample is unknown;
* 1: other samples depend on this one (not disposable);
* 2: no other sample depends on this one (disposable);
* 3: reserved
* o sampleHasRedundancy -- takes one of the following four values:
* 0: it is unknown whether there is redundant coding in this sample;
* 1: there is redundant coding in this sample;
* 2: there is no redundant coding in this sample;
* 3: reserved
*
* @param Array $sampleDependencyTypeTable The array of values
*/
public function setSampleDependencyTypeTable($sampleDependencyTypeTable)
{
$this->_sampleDependencyTypeTable = $sampleDependencyTypeTable;
}
/**
* Returns the box heap size in bytes.
*
* @return integer
*/
public function getHeapSize()
{
return parent::getHeapSize() + count($this->_sampleDependencyTypeTable);
}
/**
* Writes the box data.
*
* @param Zend_Io_Writer $writer The writer object.
* @return void
*/
protected function _writeData($writer)
{
parent::_writeData($writer);
for ($i = 1; $i <= count($this->_sampleDependencyTypeTable); $i++) {
$writer->write(chr(
(($this->_sampleDependencyTypeTable[$i]
['sampleDependsOn'] & 0x3) << 4) |
(($this->_sampleDependencyTypeTable[$i]
['sampleIsDependedOn'] & 0x3) << 2) |
(($this->_sampleDependencyTypeTable[$i]
['sampleHasRedundancy'] & 0x3))));
}
}
}

View File

@@ -0,0 +1,49 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**
* The Zend_Media_Iso14496_Exception is thrown whenever an error occurs within
* the {@link Zend_Media_Iso14496} class or a related class.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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$
*/
class Zend_Media_Iso14496_Exception extends Exception
{
}

View File

@@ -0,0 +1,150 @@
<?php
/**
* Zend Framework
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://framework.zend.com/license/new-bsd
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@zend.com so we can send you a copy immediately.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @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$
*/
/**#@+ @ignore */
require_once 'Zend/Media/Iso14496/Box.php';
/**#@-*/
/**
* A base class for objects that also contain a version number and flags field.
*
* @category Zend
* @package Zend_Media
* @subpackage ISO 14496
* @author Sven Vollbehr <sven@vollbehr.eu>
* @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$
*/
abstract class Zend_Media_Iso14496_FullBox extends Zend_Media_Iso14496_Box
{
/** @var integer */
protected $_version = 0;
/** @var integer */
protected $_flags = 0;
/**
* 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.
*/
public function __construct($reader = null, &$options = array())
{
parent::__construct($reader, $options);
if ($reader === null) {
return;
}
$this->_version =
(($field = $this->_reader->readUInt32BE()) >> 24) & 0xff;
$this->_flags = $field & 0xffffff;
}
/**
* Returns the version of this format of the box.
*
* @return integer
*/
public function getVersion()
{
return $this->_version;
}
/**
* Sets the version of this format of the box.
*
* @param integer $version The version.
*/
public function setVersion($version)
{
$this->_version = $version;
}
/**
* Checks whether or not the flag is set. Returns <var>true</var> if the
* flag is set, <var>false</var> otherwise.
*
* @param integer $flag The flag to query.
* @return boolean
*/
public function hasFlag($flag)
{
return ($this->_flags & $flag) == $flag;
}
/**
* Returns the map of flags.
*
* @return integer
*/
public function getFlags()
{
return $this->_flags;
}
/**
* Sets the map of flags.
*
* @param string $flags The map of flags.
*/
public function setFlags($flags)
{
$this->_flags = $flags;
}
/**
* Returns the box heap size in bytes.
*
* @return integer
*/
public function getHeapSize()
{
return parent::getHeapSize() + 4;
}
/**
* Writes the box data without the header.
*
* @param Zend_Io_Writer $writer The writer object.
* @return void
*/
protected function _writeData($writer)
{
parent::_writeData($writer);
$writer->writeUInt32BE($this->_version << 24 | $this->_flags);
}
}