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:
@@ -47,7 +47,7 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
private $_pages = array();
|
private $_pages = array();
|
||||||
|
|
||||||
/** @var integer */
|
/** @var integer */
|
||||||
private $_currentPage = 0;
|
private $_currentPageNumber = 0;
|
||||||
|
|
||||||
/** @var integer */
|
/** @var integer */
|
||||||
private $_currentPagePosition = 0;
|
private $_currentPagePosition = 0;
|
||||||
@@ -65,13 +65,15 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
$fileSize = $reader->getSize();
|
$fileSize = $reader->getSize();
|
||||||
while ($reader->getOffset() < $fileSize) {
|
while ($reader->getOffset() < $fileSize) {
|
||||||
$this->_pages[] = array(
|
$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();
|
$this->_size += $page->getPageSize();
|
||||||
$reader->skip($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();
|
$this->_fd = $reader->getFileDescriptor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +86,7 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
public function getOffset()
|
public function getOffset()
|
||||||
{
|
{
|
||||||
$offset = 0;
|
$offset = 0;
|
||||||
for ($i = 0; $i < $this->_currentPage; $i++) {
|
for ($i = 0; $i < $this->_currentPageNumber; $i++) {
|
||||||
$offset += $this->_pages[$i]['page']->getPageSize();
|
$offset += $this->_pages[$i]['page']->getPageSize();
|
||||||
}
|
}
|
||||||
return $offset += $this->_currentPagePosition;
|
return $offset += $this->_currentPagePosition;
|
||||||
@@ -102,9 +104,11 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
$streamSize = 0;
|
$streamSize = 0;
|
||||||
for ($i = 0, $pageCount = count($this->_pages); $i < $pageCount; $i++) {
|
for ($i = 0, $pageCount = count($this->_pages); $i < $pageCount; $i++) {
|
||||||
if (($streamSize + $this->_pages[$i]['page']->getPageSize()) >= $offset) {
|
if (($streamSize + $this->_pages[$i]['page']->getPageSize()) >= $offset) {
|
||||||
$this->_currentPage = $i;
|
$this->_currentPageNumber = $i;
|
||||||
$this->_currentPagePosition = $offset - $streamSize;
|
$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;
|
break;
|
||||||
}
|
}
|
||||||
$streamSize += $this->_pages[$i]['page']->getPageSize();
|
$streamSize += $this->_pages[$i]['page']->getPageSize();
|
||||||
@@ -120,12 +124,12 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
*/
|
*/
|
||||||
public function skip($size)
|
public function skip($size)
|
||||||
{
|
{
|
||||||
$currentPageSize = $this->_pages[$this->_currentPage]['page']->getPageSize();
|
$currentPageSize = $this->_pages[$this->_currentPageNumber]['page']->getPageSize();
|
||||||
if (($this->_currentPagePosition + $size) >= $currentPageSize) {
|
if (($this->_currentPagePosition + $size) >= $currentPageSize) {
|
||||||
parent::skip
|
parent::skip
|
||||||
(($currentPageSize - $this->_currentPagePosition) +
|
(($currentPageSize - $this->_currentPagePosition) +
|
||||||
$this->_pages[++$this->_currentPage]['page']->getHeaderSize() +
|
$this->_pages[++$this->_currentPageNumber]['page']->getHeaderSize() +
|
||||||
($this->_currentPagePosition = ($size - $currentPageSize - $this->_currentPagePosition)));
|
($this->_currentPagePosition = ($size - ($currentPageSize - $this->_currentPagePosition))));
|
||||||
} else {
|
} else {
|
||||||
$this->_currentPagePosition += $size;
|
$this->_currentPagePosition += $size;
|
||||||
parent::skip($size);
|
parent::skip($size);
|
||||||
@@ -141,10 +145,10 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
*/
|
*/
|
||||||
public function read($length)
|
public function read($length)
|
||||||
{
|
{
|
||||||
$currentPageSize = $this->_pages[$this->_currentPage]['page']->getPageSize();
|
$currentPageSize = $this->_pages[$this->_currentPageNumber]['page']->getPageSize();
|
||||||
if (($this->_currentPagePosition + $length) >= $currentPageSize) {
|
if (($this->_currentPagePosition + $length) >= $currentPageSize) {
|
||||||
$buffer = parent::read($currentPageSize - $this->_currentPagePosition);
|
$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
|
return $buffer . parent::read
|
||||||
($this->_currentPagePosition = ($length - ($currentPageSize - $this->_currentPagePosition)));
|
($this->_currentPagePosition = ($length - ($currentPageSize - $this->_currentPagePosition)));
|
||||||
} else {
|
} else {
|
||||||
@@ -153,4 +157,35 @@ final class Zend_Media_Ogg_Reader extends Zend_Io_Reader
|
|||||||
return $buffer;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,11 +61,11 @@ final class Zend_Media_Vorbis
|
|||||||
/** @var Zend_Media_Vorbis_Header_Comment */
|
/** @var Zend_Media_Vorbis_Header_Comment */
|
||||||
private $_commentHeader;
|
private $_commentHeader;
|
||||||
|
|
||||||
// /** @var Zend_Media_Vorbis_Header_Setup */
|
/** @var Zend_Media_Vorbis_Header_Setup */
|
||||||
// private $_setupHeader;
|
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,
|
* @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.
|
* 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->_identificationHeader = new Zend_Media_Vorbis_Header_Identification($this->_reader);
|
||||||
$this->_commentHeader = new Zend_Media_Vorbis_Header_Comment($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()
|
public function getSetupHeader()
|
||||||
{
|
{
|
||||||
require_once 'Zend/Media/Vorbis/Exception.php';
|
return $this->_setupHeader;
|
||||||
throw new Zend_Media_Vorbis_Exception('Not yet supported');
|
|
||||||
// return $this->_setupHeader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -53,6 +53,9 @@ abstract class Zend_Media_Vorbis_Header
|
|||||||
*/
|
*/
|
||||||
protected $_packetType;
|
protected $_packetType;
|
||||||
|
|
||||||
|
/** $var integer */
|
||||||
|
protected $_packetSize = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the class with given parameters.
|
* Constructs the class with given parameters.
|
||||||
*
|
*
|
||||||
@@ -62,7 +65,6 @@ abstract class Zend_Media_Vorbis_Header
|
|||||||
public function __construct($reader)
|
public function __construct($reader)
|
||||||
{
|
{
|
||||||
$this->_reader = $reader;
|
$this->_reader = $reader;
|
||||||
|
|
||||||
if (!in_array($this->_packetType = $this->_reader->readUInt8(), array(1, 3, 5))) {
|
if (!in_array($this->_packetType = $this->_reader->readUInt8(), array(1, 3, 5))) {
|
||||||
require_once 'Zend/Media/Vorbis/Exception.php';
|
require_once 'Zend/Media/Vorbis/Exception.php';
|
||||||
throw new Zend_Media_Vorbis_Exception('Unknown header packet type: ' . $this->_packetType);
|
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';
|
require_once 'Zend/Media/Vorbis/Exception.php';
|
||||||
throw new Zend_Media_Vorbis_Exception('Unknown header packet: ' . $vorbis);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ final class Zend_Media_Vorbis_Header_Comment extends Zend_Media_Vorbis_Header
|
|||||||
require_once 'Zend/Media/Vorbis/Exception.php';
|
require_once 'Zend/Media/Vorbis/Exception.php';
|
||||||
throw new Zend_Media_Vorbis_Exception('Undecodable Vorbis stream');
|
throw new Zend_Media_Vorbis_Exception('Undecodable Vorbis stream');
|
||||||
}
|
}
|
||||||
|
$this->_reader->skip($this->_packetSize - $this->_reader->getOffset() + 30 /* header */);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
55
src/Zend/Media/Vorbis/Header/Setup.php
Normal file
55
src/Zend/Media/Vorbis/Header/Setup.php
Normal 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 congurations, time-domain transform congurations (placeholders in Vorbis I), oor con
|
||||||
|
* gurations, residue congurations, channel mapping congurations and mode congurations. 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 */);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user