Add support for Vorbis setup header

git-svn-id: http://php-reader.googlecode.com/svn/trunk@239 51a70ab9-7547-0410-9469-37e369ee0574
This commit is contained in:
svollbehr
2011-06-04 09:35:48 +00:00
parent 85cee10135
commit 9e17c99318
5 changed files with 133 additions and 20 deletions

View File

@@ -47,7 +47,7 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
private $_pages = array();
/** @var integer */
private $_currentPage = 0;
private $_currentPageNumber = 0;
/** @var integer */
private $_currentPagePosition = 0;
@@ -65,13 +65,15 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
$fileSize = $reader->getSize();
while ($reader->getOffset() < $fileSize) {
$this->_pages[] = array(
'page' => $page = new Zend_Media_Ogg_Page($reader),
'offset' => $reader->getOffset()
'offset' => $reader->getOffset(),
'page' => $page = new Zend_Media_Ogg_Page($reader)
);
$this->_size += $page->getPageSize();
$reader->skip($page->getPageSize());
}
$reader->setOffset($this->_pages[$this->_currentPage]['offset']);
$reader->setOffset
($this->_pages[$this->_currentPageNumber]['offset'] +
$this->_pages[$this->_currentPageNumber]['page']->getHeaderSize());
$this->_fd = $reader->getFileDescriptor();
}
@@ -84,7 +86,7 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
public function getOffset()
{
$offset = 0;
for ($i = 0; $i < $this->_currentPage; $i++) {
for ($i = 0; $i < $this->_currentPageNumber; $i++) {
$offset += $this->_pages[$i]['page']->getPageSize();
}
return $offset += $this->_currentPagePosition;
@@ -102,9 +104,11 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
$streamSize = 0;
for ($i = 0, $pageCount = count($this->_pages); $i < $pageCount; $i++) {
if (($streamSize + $this->_pages[$i]['page']->getPageSize()) >= $offset) {
$this->_currentPage = $i;
$this->_currentPageNumber = $i;
$this->_currentPagePosition = $offset - $streamSize;
parent::setOffset($this->_pages[$i]['offset'] + $this->_currentPagePosition);
parent::setOffset
($this->_pages[$i]['offset'] + $this->_pages[$i]['page']->getHeaderSize() +
$this->_currentPagePosition);
break;
}
$streamSize += $this->_pages[$i]['page']->getPageSize();
@@ -120,12 +124,12 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
*/
public function skip($size)
{
$currentPageSize = $this->_pages[$this->_currentPage]['page']->getPageSize();
$currentPageSize = $this->_pages[$this->_currentPageNumber]['page']->getPageSize();
if (($this->_currentPagePosition + $size) >= $currentPageSize) {
parent::skip
(($currentPageSize - $this->_currentPagePosition) +
$this->_pages[++$this->_currentPage]['page']->getHeaderSize() +
($this->_currentPagePosition = ($size - $currentPageSize - $this->_currentPagePosition)));
$this->_pages[++$this->_currentPageNumber]['page']->getHeaderSize() +
($this->_currentPagePosition = ($size - ($currentPageSize - $this->_currentPagePosition))));
} else {
$this->_currentPagePosition += $size;
parent::skip($size);
@@ -141,10 +145,10 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
*/
public function read($length)
{
$currentPageSize = $this->_pages[$this->_currentPage]['page']->getPageSize();
$currentPageSize = $this->_pages[$this->_currentPageNumber]['page']->getPageSize();
if (($this->_currentPagePosition + $length) >= $currentPageSize) {
$buffer = parent::read($currentPageSize - $this->_currentPagePosition);
parent::skip($this->_pages[++$this->_currentPage]['page']->getHeaderSize());
parent::skip($this->_pages[++$this->_currentPageNumber]['page']->getHeaderSize());
return $buffer . parent::read
($this->_currentPagePosition = ($length - ($currentPageSize - $this->_currentPagePosition)));
} else {
@@ -153,4 +157,35 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
return $buffer;
}
}
/**
* Returns the underlying Ogg page at given number.
*
* @param integer $pageNumber The number of the page to return.
* @return Zend_Media_Ogg_Page
*/
public function getPage($pageNumber)
{
return $this->_pages[$pageNumber]['page'];
}
/**
* Returns the underlying Ogg page number.
*
* @return integer
*/
public function getCurrentPageNumber()
{
return $this->_currentPageNumber;
}
/**
* Returns the underlying Ogg page position, in bytes.
*
* @return integer
*/
public function getCurrentPagePosition()
{
return $this->_currentPagePosition;
}
}

View File

@@ -61,11 +61,11 @@ final class Zend_Media_Vorbis
/** @var Zend_Media_Vorbis_Header_Comment */
private $_commentHeader;
// /** @var Zend_Media_Vorbis_Header_Setup */
// private $_setupHeader;
/** @var Zend_Media_Vorbis_Header_Setup */
private $_setupHeader;
/**
* Constructs the .
* Constructs the Zend_Media_Vorbis class with given file.
*
* @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.
@@ -90,7 +90,7 @@ final class Zend_Media_Vorbis
$this->_identificationHeader = new Zend_Media_Vorbis_Header_Identification($this->_reader);
$this->_commentHeader = new Zend_Media_Vorbis_Header_Comment($this->_reader);
// $this->_setupHeader = new Zend_Media_Vorbis_Header_Setup($this->_reader);
$this->_setupHeader = new Zend_Media_Vorbis_Header_Setup($this->_reader);
}
/**
@@ -120,9 +120,7 @@ final class Zend_Media_Vorbis
*/
public function getSetupHeader()
{
require_once 'Zend/Media/Vorbis/Exception.php';
throw new Zend_Media_Vorbis_Exception('Not yet supported');
// return $this->_setupHeader;
return $this->_setupHeader;
}
/**

View File

@@ -53,6 +53,9 @@ abstract class Zend_Media_Vorbis_Header
*/
protected $_packetType;
/** $var integer */
protected $_packetSize = 0;
/**
* Constructs the class with given parameters.
*
@@ -62,7 +65,6 @@ abstract class Zend_Media_Vorbis_Header
public function __construct($reader)
{
$this->_reader = $reader;
if (!in_array($this->_packetType = $this->_reader->readUInt8(), array(1, 3, 5))) {
require_once 'Zend/Media/Vorbis/Exception.php';
throw new Zend_Media_Vorbis_Exception('Unknown header packet type: ' . $this->_packetType);
@@ -71,6 +73,28 @@ abstract class Zend_Media_Vorbis_Header
require_once 'Zend/Media/Vorbis/Exception.php';
throw new Zend_Media_Vorbis_Exception('Unknown header packet: ' . $vorbis);
}
$skipBytes = $this->_reader->getCurrentPagePosition();
for ($page = $this->_reader->getCurrentPageNumber(); /* goes on until we find packet end */; $page++) {
$segments = $this->_reader->getPage($page)->getSegmentTable();
for ($i = 0, $skippedSegments = 0; $i < count($segments); $i++) {
// Skip page segments that are already read in
if ($skipBytes > $segments[$i]) {
$skipBytes -= $segments[$i];
continue;
}
// Skip segments that are full
if ($segments[$i] == 255 && ++$skippedSegments) {
continue;
}
// Record packet size from the first non-255 segment
$this->_packetSize += $i * 255 + $segments[$i];
break 2;
}
$this->_packetSize += $skippedSegments * 255;
}
}
/**

View File

@@ -87,6 +87,7 @@ final class Zend_Media_Vorbis_Header_Comment extends Zend_Media_Vorbis_Header
require_once 'Zend/Media/Vorbis/Exception.php';
throw new Zend_Media_Vorbis_Exception('Undecodable Vorbis stream');
}
$this->_reader->skip($this->_packetSize - $this->_reader->getOffset() + 30 /* header */);
}
/**

View File

@@ -0,0 +1,55 @@
<?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 Vorbis
* @copyright Copyright (c) 2005-2011 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/Vorbis/Header.php';
/**#@-*/
/**
* The setup header contains the bulk of the codec setup information needed for decode. The setup header contains, in
* order, the lists of codebook con gurations, time-domain transform con gurations (placeholders in Vorbis I), oor con
* gurations, residue con gurations, channel mapping con gurations and mode con gurations. It finishes with a framing
* bit of '1'.
*
* @category Zend
* @package Zend_Media
* @subpackage Vorbis
* @author Sven Vollbehr <sven@vollbehr.eu>
* @copyright Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @version $Id$
* @todo Implementation
*/
final class Zend_Media_Vorbis_Header_Setup extends Zend_Media_Vorbis_Header
{
/**
* Constructs the class with given parameters.
*
* @param Zend_Io_Reader $reader The reader object.
*/
public function __construct($reader)
{
parent::__construct($reader);
$this->_reader->skip($this->_packetSize - 7 /* header */);
}
}