: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
public function peekByte() {
$val = $this->readByte();
public function peekInt() {
public function peekLong() {
$val = $this->readLong();
public function peekDouble() {
$val = $this->readDouble();
public function peekUTF() {
public function peekLongUTF() {
$val = $this->readLongUTF();
* @param AMFStream $stream
public function __construct(AMFStream $stream) {
public function readData() {
$type = $this->stream->readByte();
$value = $this->readDouble();
$value = $this->readBoolean();
$value = $this->readString();
$value = $this->readObject();
$value = $this->readMixedArray();
$value = $this->readArray();
$value = $this->readDate();
$value = $this->readLongString();
// XML (handled as string)
$value = $this->readXML();
// Typed object (handled as object)
$value = $this->readTypedObject();
$value = '(unknown or unsupported data type)';
public function readDouble() {
return $this->stream->readDouble();
public function readBoolean() {
return $this->stream->readByte() == 1;
public function readString() {
return $this->stream->readUTF();
public function readObject() {
// Get highest numerical index - ignored
// $highestIndex = $this->stream->readLong();
while ($key = $this->stream->readUTF()) {
$data[$key] = $this->readData();
// Mixed array record ends with empty string (0x00 0x00) and 0x09
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
$this->stream->readByte();
public function readMixedArray() {
// Get highest numerical index - ignored
$highestIndex = $this->stream->readLong();
while ($key = $this->stream->readUTF()) {
$data[$key] = $this->readData();
// Mixed array record ends with empty string (0x00 0x00) and 0x09
if (($key == '') && ($this->stream->peekByte() == 0x09)) {
$this->stream->readByte();
public function readArray() {
$length = $this->stream->readLong();
for ($i = 0; $i < $length; $i++) {
$data[] = $this->readData();
public function readDate() {
$timestamp = $this->stream->readDouble();
$timezone = $this->stream->readInt();
public function readLongString() {
return $this->stream->readLongUTF();
public function readXML() {
return $this->stream->readLongUTF();
public function readTypedObject() {
$className = $this->stream->readUTF();
return $this->readObject();
class AVCSequenceParameterSetReader
public $currentBytes = 0;
public function __construct($sps) {
public function readData() {
$profile = $this->getBits(8); // read profile
$level_idc = $this->getBits(8); // level_idc
$this->expGolombUe(); // seq_parameter_set_id // sps
$this->expGolombUe(); // log2_max_frame_num_minus4
$picOrderType = $this->expGolombUe(); // pic_order_cnt_type
if ($picOrderType == 0) {
$this->expGolombUe(); // log2_max_pic_order_cnt_lsb_minus4
} elseif ($picOrderType == 1) {
$this->skipBits(1); // delta_pic_order_always_zero_flag
$this->expGolombSe(); // offset_for_non_ref_pic
$this->expGolombSe(); // offset_for_top_to_bottom_field
$num_ref_frames_in_pic_order_cnt_cycle = $this->expGolombUe(); // num_ref_frames_in_pic_order_cnt_cycle
for ($i = 0; $i < $num_ref_frames_in_pic_order_cnt_cycle; $i++) {
$this->expGolombSe(); // offset_for_ref_frame[ i ]
$this->expGolombUe(); // num_ref_frames
$this->skipBits(1); // gaps_in_frame_num_value_allowed_flag
$pic_width_in_mbs_minus1 = $this->expGolombUe(); // pic_width_in_mbs_minus1
$pic_height_in_map_units_minus1 = $this->expGolombUe(); // pic_height_in_map_units_minus1
$frame_mbs_only_flag = $this->getBits(1); // frame_mbs_only_flag
if ($frame_mbs_only_flag == 0) {
$this->skipBits(1); // mb_adaptive_frame_field_flag
$this->skipBits(1); // direct_8x8_inference_flag
$frame_cropping_flag = $this->getBits(1); // frame_cropping_flag
$frame_crop_left_offset = 0;
$frame_crop_right_offset = 0;
$frame_crop_top_offset = 0;
$frame_crop_bottom_offset = 0;
if ($frame_cropping_flag) {
$frame_crop_left_offset = $this->expGolombUe(); // frame_crop_left_offset
$frame_crop_right_offset = $this->expGolombUe(); // frame_crop_right_offset
$frame_crop_top_offset = $this->expGolombUe(); // frame_crop_top_offset
$frame_crop_bottom_offset = $this->expGolombUe(); // frame_crop_bottom_offset
$this->skipBits(1); // vui_parameters_present_flag
$this->width = (($pic_width_in_mbs_minus1 + 1) * 16) - ($frame_crop_left_offset * 2) - ($frame_crop_right_offset * 2);
$this->height = ((2 - $frame_mbs_only_flag) * ($pic_height_in_map_units_minus1 + 1) * 16) - ($frame_crop_top_offset * 2) - ($frame_crop_bottom_offset * 2);
public function skipBits($bits) {
$newBits = $this->currentBits + $bits;
$this->currentBytes += (int)floor($newBits / 8);
$this->currentBits = $newBits % 8;
public function getBit() {
$result = (getid3_lib::BigEndian2Int(substr($this->sps, $this->currentBytes, 1)) >> (7 - $this->currentBits)) & 0x01;
public function getBits($bits) {
for ($i = 0; $i < $bits; $i++) {
$result = ($result << 1) + $this->getBit();
public function expGolombUe() {
if ($significantBits > 31) {
// something is broken, this is an emergency escape to prevent infinite loops
return (1 << $significantBits) + $this->getBits($significantBits) - 1;
public function expGolombSe() {
$result = $this->expGolombUe();
if (($result & 0x01) == 0) {
return ($result + 1) >> 1;
public function getWidth() {
public function getHeight() {