function getid3_flv(&$fd, &$ThisFileInfo, $ReturnAllTagData = false)
 {
     //$start_time = microtime(true);
     fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
     $FLVdataLength = $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset'];
     $FLVheader = fread($fd, 5);
     $ThisFileInfo['fileformat'] = 'flv';
     $ThisFileInfo['flv']['header']['signature'] = substr($FLVheader, 0, 3);
     $ThisFileInfo['flv']['header']['version'] = getid3_lib::BigEndian2Int(substr($FLVheader, 3, 1));
     $TypeFlags = getid3_lib::BigEndian2Int(substr($FLVheader, 4, 1));
     if ($ThisFileInfo['flv']['header']['signature'] != 'FLV') {
         $ThisFileInfo['error'][] = 'Expecting "FLV" at offset ' . $ThisFileInfo['avdataoffset'] . ', found "' . $ThisFileInfo['flv']['header']['signature'] . '"';
         unset($ThisFileInfo['flv']);
         unset($ThisFileInfo['fileformat']);
         return false;
     }
     $ThisFileInfo['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 0x4);
     $ThisFileInfo['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 0x1);
     $FrameSizeDataLength = getid3_lib::BigEndian2Int(fread($fd, 4));
     $FLVheaderFrameLength = 9;
     if ($FrameSizeDataLength > $FLVheaderFrameLength) {
         fseek($fd, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
     }
     //echo __LINE__.'='.number_format(microtime(true) - $start_time, 3).'<br>';
     $Duration = 0;
     $found_video = false;
     $found_audio = false;
     $found_meta = false;
     while (ftell($fd) + 16 < $ThisFileInfo['avdataend']) {
         $ThisTagHeader = fread($fd, 16);
         $PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4));
         $TagType = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 4, 1));
         $DataLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 5, 3));
         $Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3));
         $LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1));
         $NextOffset = ftell($fd) - 1 + $DataLength;
         if ($Timestamp > $Duration) {
             $Duration = $Timestamp;
         }
         //echo __LINE__.'['.ftell($fd).']=('.$TagType.')='.number_format(microtime(true) - $start_time, 3).'<br>';
         switch ($TagType) {
             case GETID3_FLV_TAG_AUDIO:
                 if (!$found_audio) {
                     $found_audio = true;
                     $ThisFileInfo['flv']['audio']['audioFormat'] = $LastHeaderByte & 0x7;
                     $ThisFileInfo['flv']['audio']['audioRate'] = ($LastHeaderByte & 0x30) / 0x10;
                     $ThisFileInfo['flv']['audio']['audioSampleSize'] = ($LastHeaderByte & 0x40) / 0x40;
                     $ThisFileInfo['flv']['audio']['audioType'] = ($LastHeaderByte & 0x80) / 0x80;
                 }
                 break;
             case GETID3_FLV_TAG_VIDEO:
                 if (!$found_video) {
                     $found_video = true;
                     $ThisFileInfo['flv']['video']['videoCodec'] = $LastHeaderByte & 0x7;
                     $FLVvideoHeader = fread($fd, 11);
                     if ($ThisFileInfo['flv']['video']['videoCodec'] != GETID3_FLV_VIDEO_VP6) {
                         $PictureSizeType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 3, 2)) >> 7;
                         $PictureSizeType = $PictureSizeType & 0x7;
                         $ThisFileInfo['flv']['header']['videoSizeType'] = $PictureSizeType;
                         switch ($PictureSizeType) {
                             case 0:
                                 //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
                                 //$PictureSizeEnc <<= 1;
                                 //$ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8;
                                 //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2));
                                 //$PictureSizeEnc <<= 1;
                                 //$ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8;
                                 $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 2));
                                 $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
                                 $PictureSizeEnc['x'] >>= 7;
                                 $PictureSizeEnc['y'] >>= 7;
                                 $ThisFileInfo['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xff;
                                 $ThisFileInfo['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xff;
                                 break;
                             case 1:
                                 $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 3));
                                 $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 3));
                                 $PictureSizeEnc['x'] >>= 7;
                                 $PictureSizeEnc['y'] >>= 7;
                                 $ThisFileInfo['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xffff;
                                 $ThisFileInfo['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xffff;
                                 break;
                             case 2:
                                 $ThisFileInfo['video']['resolution_x'] = 352;
                                 $ThisFileInfo['video']['resolution_y'] = 288;
                                 break;
                             case 3:
                                 $ThisFileInfo['video']['resolution_x'] = 176;
                                 $ThisFileInfo['video']['resolution_y'] = 144;
                                 break;
                             case 4:
                                 $ThisFileInfo['video']['resolution_x'] = 128;
                                 $ThisFileInfo['video']['resolution_y'] = 96;
                                 break;
                             case 5:
                                 $ThisFileInfo['video']['resolution_x'] = 320;
                                 $ThisFileInfo['video']['resolution_y'] = 240;
                                 break;
                             case 6:
                                 $ThisFileInfo['video']['resolution_x'] = 160;
                                 $ThisFileInfo['video']['resolution_y'] = 120;
                                 break;
                             default:
                                 $ThisFileInfo['video']['resolution_x'] = 0;
                                 $ThisFileInfo['video']['resolution_y'] = 0;
                                 break;
                         }
                     }
                 }
                 break;
                 // Meta tag
             // Meta tag
             case GETID3_FLV_TAG_META:
                 if (!$found_meta) {
                     $found_meta = true;
                     fseek($fd, -1, SEEK_CUR);
                     $bData = fread($fd, $DataLength);
                     $b = new AMFStream($bData);
                     //						$reader = new AMFReader(new AMFStream(fread($fd, $DataLength)));
                     $reader = new AMFReader($b);
                     $eventName = $reader->readData();
                     $ThisFileInfo['meta'][$eventName] = $reader->readData();
                     unset($reader);
                     $ThisFileInfo['video']['frame_rate'] = @$ThisFileInfo['meta']['onMetaData']['framerate'];
                     $ThisFileInfo['video']['resolution_x'] = @$ThisFileInfo['meta']['onMetaData']['width'];
                     $ThisFileInfo['video']['resolution_y'] = @$ThisFileInfo['meta']['onMetaData']['height'];
                 }
                 break;
             default:
                 // noop
                 break;
         }
         fseek($fd, $NextOffset, SEEK_SET);
     }
     if ($ThisFileInfo['playtime_seconds'] = $Duration / 1000) {
         $ThisFileInfo['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds'];
     }
     if ($ThisFileInfo['flv']['header']['hasAudio']) {
         $ThisFileInfo['audio']['codec'] = $this->FLVaudioFormat($ThisFileInfo['flv']['audio']['audioFormat']);
         $ThisFileInfo['audio']['sample_rate'] = $this->FLVaudioRate($ThisFileInfo['flv']['audio']['audioRate']);
         $ThisFileInfo['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($ThisFileInfo['flv']['audio']['audioSampleSize']);
         $ThisFileInfo['audio']['channels'] = $ThisFileInfo['flv']['audio']['audioType'] + 1;
         // 0=mono,1=stereo
         $ThisFileInfo['audio']['lossless'] = $ThisFileInfo['flv']['audio']['audioFormat'] ? false : true;
         // 0=uncompressed
         $ThisFileInfo['audio']['dataformat'] = 'flv';
     }
     if (@$ThisFileInfo['flv']['header']['hasVideo']) {
         $ThisFileInfo['video']['codec'] = $this->FLVvideoCodec($ThisFileInfo['flv']['video']['videoCodec']);
         $ThisFileInfo['video']['dataformat'] = 'flv';
         $ThisFileInfo['video']['lossless'] = false;
     }
     return true;
 }
 public function Analyze()
 {
     $info =& $this->getid3->info;
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $FLVdataLength = $info['avdataend'] - $info['avdataoffset'];
     $FLVheader = fread($this->getid3->fp, 5);
     $info['fileformat'] = 'flv';
     $info['flv']['header']['signature'] = substr($FLVheader, 0, 3);
     $info['flv']['header']['version'] = getid3_lib::BigEndian2Int(substr($FLVheader, 3, 1));
     $TypeFlags = getid3_lib::BigEndian2Int(substr($FLVheader, 4, 1));
     $magic = 'FLV';
     if ($info['flv']['header']['signature'] != $magic) {
         $info['error'][] = 'Expecting "' . getid3_lib::PrintHexBytes($magic) . '" at offset ' . $info['avdataoffset'] . ', found "' . getid3_lib::PrintHexBytes($info['flv']['header']['signature']) . '"';
         unset($info['flv']);
         unset($info['fileformat']);
         return false;
     }
     $info['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 0x4);
     $info['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 0x1);
     $FrameSizeDataLength = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4));
     $FLVheaderFrameLength = 9;
     if ($FrameSizeDataLength > $FLVheaderFrameLength) {
         fseek($this->getid3->fp, $FrameSizeDataLength - $FLVheaderFrameLength, SEEK_CUR);
     }
     $Duration = 0;
     $found_video = false;
     $found_audio = false;
     $found_meta = false;
     $found_valid_meta_playtime = false;
     $tagParseCount = 0;
     $info['flv']['framecount'] = array('total' => 0, 'audio' => 0, 'video' => 0);
     $flv_framecount =& $info['flv']['framecount'];
     while (ftell($this->getid3->fp) + 16 < $info['avdataend'] && ($tagParseCount++ <= $this->max_frames || !$found_valid_meta_playtime)) {
         $ThisTagHeader = fread($this->getid3->fp, 16);
         $PreviousTagLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 0, 4));
         $TagType = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 4, 1));
         $DataLength = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 5, 3));
         $Timestamp = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 8, 3));
         $LastHeaderByte = getid3_lib::BigEndian2Int(substr($ThisTagHeader, 15, 1));
         $NextOffset = ftell($this->getid3->fp) - 1 + $DataLength;
         if ($Timestamp > $Duration) {
             $Duration = $Timestamp;
         }
         $flv_framecount['total']++;
         switch ($TagType) {
             case GETID3_FLV_TAG_AUDIO:
                 $flv_framecount['audio']++;
                 if (!$found_audio) {
                     $found_audio = true;
                     $info['flv']['audio']['audioFormat'] = $LastHeaderByte >> 4 & 0xf;
                     $info['flv']['audio']['audioRate'] = $LastHeaderByte >> 2 & 0x3;
                     $info['flv']['audio']['audioSampleSize'] = $LastHeaderByte >> 1 & 0x1;
                     $info['flv']['audio']['audioType'] = $LastHeaderByte & 0x1;
                 }
                 break;
             case GETID3_FLV_TAG_VIDEO:
                 $flv_framecount['video']++;
                 if (!$found_video) {
                     $found_video = true;
                     $info['flv']['video']['videoCodec'] = $LastHeaderByte & 0x7;
                     $FLVvideoHeader = fread($this->getid3->fp, 11);
                     if ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H264) {
                         // this code block contributed by: moysevichØgmail*com
                         $AVCPacketType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 0, 1));
                         if ($AVCPacketType == H264_AVC_SEQUENCE_HEADER) {
                             //	read AVCDecoderConfigurationRecord
                             $configurationVersion = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 1));
                             $AVCProfileIndication = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 1));
                             $profile_compatibility = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 1));
                             $lengthSizeMinusOne = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 7, 1));
                             $numOfSequenceParameterSets = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 8, 1));
                             if (($numOfSequenceParameterSets & 0x1f) != 0) {
                                 //	there is at least one SequenceParameterSet
                                 //	read size of the first SequenceParameterSet
                                 //$spsSize = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 9, 2));
                                 $spsSize = getid3_lib::LittleEndian2Int(substr($FLVvideoHeader, 9, 2));
                                 //	read the first SequenceParameterSet
                                 $sps = fread($this->getid3->fp, $spsSize);
                                 if (strlen($sps) == $spsSize) {
                                     //	make sure that whole SequenceParameterSet was red
                                     $spsReader = new AVCSequenceParameterSetReader($sps);
                                     $spsReader->readData();
                                     $info['video']['resolution_x'] = $spsReader->getWidth();
                                     $info['video']['resolution_y'] = $spsReader->getHeight();
                                 }
                             }
                         }
                         // end: moysevichØgmail*com
                     } elseif ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H263) {
                         $PictureSizeType = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 3, 2)) >> 7;
                         $PictureSizeType = $PictureSizeType & 0x7;
                         $info['flv']['header']['videoSizeType'] = $PictureSizeType;
                         switch ($PictureSizeType) {
                             case 0:
                                 //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
                                 //$PictureSizeEnc <<= 1;
                                 //$info['video']['resolution_x'] = ($PictureSizeEnc & 0xFF00) >> 8;
                                 //$PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 2));
                                 //$PictureSizeEnc <<= 1;
                                 //$info['video']['resolution_y'] = ($PictureSizeEnc & 0xFF00) >> 8;
                                 $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 2));
                                 $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 5, 2));
                                 $PictureSizeEnc['x'] >>= 7;
                                 $PictureSizeEnc['y'] >>= 7;
                                 $info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xff;
                                 $info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xff;
                                 break;
                             case 1:
                                 $PictureSizeEnc['x'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 4, 3));
                                 $PictureSizeEnc['y'] = getid3_lib::BigEndian2Int(substr($FLVvideoHeader, 6, 3));
                                 $PictureSizeEnc['x'] >>= 7;
                                 $PictureSizeEnc['y'] >>= 7;
                                 $info['video']['resolution_x'] = $PictureSizeEnc['x'] & 0xffff;
                                 $info['video']['resolution_y'] = $PictureSizeEnc['y'] & 0xffff;
                                 break;
                             case 2:
                                 $info['video']['resolution_x'] = 352;
                                 $info['video']['resolution_y'] = 288;
                                 break;
                             case 3:
                                 $info['video']['resolution_x'] = 176;
                                 $info['video']['resolution_y'] = 144;
                                 break;
                             case 4:
                                 $info['video']['resolution_x'] = 128;
                                 $info['video']['resolution_y'] = 96;
                                 break;
                             case 5:
                                 $info['video']['resolution_x'] = 320;
                                 $info['video']['resolution_y'] = 240;
                                 break;
                             case 6:
                                 $info['video']['resolution_x'] = 160;
                                 $info['video']['resolution_y'] = 120;
                                 break;
                             default:
                                 $info['video']['resolution_x'] = 0;
                                 $info['video']['resolution_y'] = 0;
                                 break;
                         }
                     }
                     $info['video']['pixel_aspect_ratio'] = $info['video']['resolution_x'] / $info['video']['resolution_y'];
                 }
                 break;
                 // Meta tag
             // Meta tag
             case GETID3_FLV_TAG_META:
                 if (!$found_meta) {
                     $found_meta = true;
                     fseek($this->getid3->fp, -1, SEEK_CUR);
                     $datachunk = fread($this->getid3->fp, $DataLength);
                     $AMFstream = new AMFStream($datachunk);
                     $reader = new AMFReader($AMFstream);
                     $eventName = $reader->readData();
                     $info['flv']['meta'][$eventName] = $reader->readData();
                     unset($reader);
                     $copykeys = array('framerate' => 'frame_rate', 'width' => 'resolution_x', 'height' => 'resolution_y', 'audiodatarate' => 'bitrate', 'videodatarate' => 'bitrate');
                     foreach ($copykeys as $sourcekey => $destkey) {
                         if (isset($info['flv']['meta']['onMetaData'][$sourcekey])) {
                             switch ($sourcekey) {
                                 case 'width':
                                 case 'height':
                                     $info['video'][$destkey] = intval(round($info['flv']['meta']['onMetaData'][$sourcekey]));
                                     break;
                                 case 'audiodatarate':
                                     $info['audio'][$destkey] = getid3_lib::CastAsInt(round($info['flv']['meta']['onMetaData'][$sourcekey] * 1000));
                                     break;
                                 case 'videodatarate':
                                 case 'frame_rate':
                                 default:
                                     $info['video'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey];
                                     break;
                             }
                         }
                     }
                     if (!empty($info['flv']['meta']['onMetaData']['duration'])) {
                         $found_valid_meta_playtime = true;
                     }
                 }
                 break;
             default:
                 // noop
                 break;
         }
         fseek($this->getid3->fp, $NextOffset, SEEK_SET);
     }
     $info['playtime_seconds'] = $Duration / 1000;
     if ($info['playtime_seconds'] > 0) {
         $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
     }
     if ($info['flv']['header']['hasAudio']) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['audio']['audioFormat']);
         $info['audio']['sample_rate'] = $this->FLVaudioRate($info['flv']['audio']['audioRate']);
         $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info['flv']['audio']['audioSampleSize']);
         $info['audio']['channels'] = $info['flv']['audio']['audioType'] + 1;
         // 0=mono,1=stereo
         $info['audio']['lossless'] = $info['flv']['audio']['audioFormat'] ? false : true;
         // 0=uncompressed
         $info['audio']['dataformat'] = 'flv';
     }
     if (!empty($info['flv']['header']['hasVideo'])) {
         $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['video']['videoCodec']);
         $info['video']['dataformat'] = 'flv';
         $info['video']['lossless'] = false;
     }
     // Set information from meta
     if (!empty($info['flv']['meta']['onMetaData']['duration'])) {
         $info['playtime_seconds'] = $info['flv']['meta']['onMetaData']['duration'];
         $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) * 8 / $info['playtime_seconds'];
     }
     if (isset($info['flv']['meta']['onMetaData']['audiocodecid'])) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['meta']['onMetaData']['audiocodecid']);
     }
     if (isset($info['flv']['meta']['onMetaData']['videocodecid'])) {
         $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['meta']['onMetaData']['videocodecid']);
     }
     return true;
 }
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['flv'] = array();
     $info_flv =& $info['flv'];
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $flv_data_length = $info['avdataend'] - $info['avdataoffset'];
     $flv_header = fread($this->getid3->fp, 5);
     $info['fileformat'] = 'flv';
     $info_flv['header']['signature'] = substr($flv_header, 0, 3);
     $info_flv['header']['version'] = getid3_lib::BigEndian2Int(substr($flv_header, 3, 1));
     $type_flags = getid3_lib::BigEndian2Int(substr($flv_header, 4, 1));
     $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x4);
     $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x1);
     $frame_size_data_length = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4));
     $flv_header_frame_length = 9;
     if ($frame_size_data_length > $flv_header_frame_length) {
         fseek($this->getid3->fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR);
     }
     $duration = 0;
     while (ftell($this->getid3->fp) + 1 < $info['avdataend']) {
         $this_tag_header = fread($this->getid3->fp, 16);
         $previous_tag_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 0, 4));
         $tag_type = getid3_lib::BigEndian2Int(substr($this_tag_header, 4, 1));
         $data_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 5, 3));
         $timestamp = getid3_lib::BigEndian2Int(substr($this_tag_header, 8, 3));
         $last_header_byte = getid3_lib::BigEndian2Int(substr($this_tag_header, 15, 1));
         $next_offset = ftell($this->getid3->fp) - 1 + $data_length;
         switch ($tag_type) {
             case getid3_flv::TAG_AUDIO:
                 if (!isset($info_flv['audio']['audioFormat'])) {
                     $info_flv['audio']['audioFormat'] = $last_header_byte & 0x7;
                     $info_flv['audio']['audioRate'] = ($last_header_byte & 0x30) / 0x10;
                     $info_flv['audio']['audioSampleSize'] = ($last_header_byte & 0x40) / 0x40;
                     $info_flv['audio']['audioType'] = ($last_header_byte & 0x80) / 0x80;
                 }
                 break;
             case getid3_flv::TAG_VIDEO:
                 if (!isset($info_flv['video']['videoCodec'])) {
                     $info_flv['video']['videoCodec'] = $last_header_byte & 0x7;
                     $flv_video_header = fread($this->getid3->fp, 11);
                     if ($info['flv']['video']['videoCodec'] == getid3_flv::VIDEO_H264) {
                         // this code block contributed by: moysevichØgmail*com
                         $AVCPacketType = getid3_lib::BigEndian2Int(substr($flv_video_header, 0, 1));
                         if ($AVCPacketType == AVCSequenceParameterSetReader::H264_AVC_SEQUENCE_HEADER) {
                             //	read AVCDecoderConfigurationRecord
                             $configurationVersion = getid3_lib::BigEndian2Int(substr($flv_video_header, 4, 1));
                             $AVCProfileIndication = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 1));
                             $profile_compatibility = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 1));
                             $lengthSizeMinusOne = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 1));
                             $numOfSequenceParameterSets = getid3_lib::BigEndian2Int(substr($flv_video_header, 8, 1));
                             if (($numOfSequenceParameterSets & 0x1f) != 0) {
                                 //	there is at least one SequenceParameterSet
                                 //	read size of the first SequenceParameterSet
                                 //$spsSize = getid3_lib::BigEndian2Int(substr($flv_video_header, 9, 2));
                                 $spsSize = getid3_lib::LittleEndian2Int(substr($flv_video_header, 9, 2));
                                 //	read the first SequenceParameterSet
                                 $sps = fread($this->getid3->fp, $spsSize);
                                 if (strlen($sps) == $spsSize) {
                                     //	make sure that whole SequenceParameterSet was red
                                     $spsReader = new AVCSequenceParameterSetReader($sps);
                                     $spsReader->readData();
                                     $info['video']['resolution_x'] = $spsReader->getWidth();
                                     $info['video']['resolution_y'] = $spsReader->getHeight();
                                 }
                             }
                         }
                         // end: moysevichØgmail*com
                     } elseif ($info_flv['video']['videoCodec'] == getid3_flv::VIDEO_H263) {
                         $picture_size_type = getid3_lib::BigEndian2Int(substr($flv_video_header, 3, 2)) >> 7;
                         $picture_size_type = $picture_size_type & 0x7;
                         $info_flv['header']['videoSizeType'] = $picture_size_type;
                         switch ($picture_size_type) {
                             case 0:
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 2));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_x'] = ($picture_size_enc & 0xff00) >> 8;
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 2));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_y'] = ($picture_size_enc & 0xff00) >> 8;
                                 break;
                             case 1:
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 4));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_x'] = ($picture_size_enc & 0xffff0000) >> 16;
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 4));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_y'] = ($picture_size_enc & 0xffff0000) >> 16;
                                 break;
                             case 2:
                                 $info['video']['resolution_x'] = 352;
                                 $info['video']['resolution_y'] = 288;
                                 break;
                             case 3:
                                 $info['video']['resolution_x'] = 176;
                                 $info['video']['resolution_y'] = 144;
                                 break;
                             case 4:
                                 $info['video']['resolution_x'] = 128;
                                 $info['video']['resolution_y'] = 96;
                                 break;
                             case 5:
                                 $info['video']['resolution_x'] = 320;
                                 $info['video']['resolution_y'] = 240;
                                 break;
                             case 6:
                                 $info['video']['resolution_x'] = 160;
                                 $info['video']['resolution_y'] = 120;
                                 break;
                             default:
                                 $info['video']['resolution_x'] = 0;
                                 $info['video']['resolution_y'] = 0;
                                 break;
                         }
                     }
                     $info['video']['pixel_aspect_ratio'] = $info['video']['resolution_x'] / $info['video']['resolution_y'];
                 }
                 break;
                 // Meta tag
             // Meta tag
             case getid3_flv::TAG_META:
                 fseek($this->getid3->fp, -1, SEEK_CUR);
                 $reader = new AMFReader(new AMFStream(fread($this->getid3->fp, $data_length)));
                 $event_name = $reader->readData();
                 $info['flv']['meta'][$event_name] = $reader->readData();
                 unset($reader);
                 $copykeys = array('framerate' => 'frame_rate', 'width' => 'resolution_x', 'height' => 'resolution_y', 'audiodatarate' => 'bitrate', 'videodatarate' => 'bitrate');
                 foreach ($copykeys as $sourcekey => $destkey) {
                     if (isset($info['flv']['meta']['onMetaData'][$sourcekey])) {
                         switch ($sourcekey) {
                             case 'width':
                             case 'height':
                                 $info['video'][$destkey] = intval(round($info['flv']['meta']['onMetaData'][$sourcekey]));
                                 break;
                             case 'audiodatarate':
                                 $info['audio'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey];
                                 break;
                             case 'videodatarate':
                             case 'frame_rate':
                             default:
                                 $info['video'][$destkey] = $info['flv']['meta']['onMetaData'][$sourcekey];
                                 break;
                         }
                     }
                 }
                 break;
             default:
                 // noop
                 break;
         }
         if ($timestamp > $duration) {
             $duration = $timestamp;
         }
         fseek($this->getid3->fp, $next_offset, SEEK_SET);
     }
     if ($info['playtime_seconds'] = $duration / 1000) {
         $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds'];
     }
     if ($info_flv['header']['hasAudio']) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info_flv['audio']['audioFormat']);
         $info['audio']['sample_rate'] = $this->FLVaudioRate($info_flv['audio']['audioRate']);
         $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']);
         $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1;
         // 0=mono,1=stereo
         $info['audio']['lossless'] = $info_flv['audio']['audioFormat'] ? false : true;
         // 0=uncompressed
         $info['audio']['dataformat'] = 'flv';
     }
     if (@$info_flv['header']['hasVideo']) {
         $info['video']['codec'] = $this->FLVvideoCodec($info_flv['video']['videoCodec']);
         $info['video']['dataformat'] = 'flv';
         $info['video']['lossless'] = false;
     }
     // Set information from meta
     if (isset($info['flv']['meta']['onMetaData']['duration'])) {
         $info['playtime_seconds'] = $info['flv']['meta']['onMetaData']['duration'];
     }
     if (isset($info['flv']['meta']['onMetaData']['audiocodecid'])) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info['flv']['meta']['onMetaData']['audiocodecid']);
     }
     if (isset($info['flv']['meta']['onMetaData']['videocodecid'])) {
         $info['video']['codec'] = $this->FLVvideoCodec($info['flv']['meta']['onMetaData']['videocodecid']);
     }
     return true;
 }
 public function Analyze()
 {
     $info =& $this->getid3->info;
     $info['flv'] = array();
     $info_flv =& $info['flv'];
     fseek($this->getid3->fp, $info['avdataoffset'], SEEK_SET);
     $flv_data_length = $info['avdataend'] - $info['avdataoffset'];
     $flv_header = fread($this->getid3->fp, 5);
     $info['fileformat'] = 'flv';
     $info_flv['header']['signature'] = substr($flv_header, 0, 3);
     $info_flv['header']['version'] = getid3_lib::BigEndian2Int(substr($flv_header, 3, 1));
     $type_flags = getid3_lib::BigEndian2Int(substr($flv_header, 4, 1));
     $info_flv['header']['hasAudio'] = (bool) ($type_flags & 0x4);
     $info_flv['header']['hasVideo'] = (bool) ($type_flags & 0x1);
     $frame_size_data_length = getid3_lib::BigEndian2Int(fread($this->getid3->fp, 4));
     $flv_header_frame_length = 9;
     if ($frame_size_data_length > $flv_header_frame_length) {
         fseek($this->getid3->fp, $frame_size_data_length - $flv_header_frame_length, SEEK_CUR);
     }
     $duration = 0;
     while (ftell($this->getid3->fp) + 1 < $info['avdataend']) {
         $this_tag_header = fread($this->getid3->fp, 16);
         $previous_tag_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 0, 4));
         $tag_type = getid3_lib::BigEndian2Int(substr($this_tag_header, 4, 1));
         $data_length = getid3_lib::BigEndian2Int(substr($this_tag_header, 5, 3));
         $timestamp = getid3_lib::BigEndian2Int(substr($this_tag_header, 8, 3));
         $last_header_byte = getid3_lib::BigEndian2Int(substr($this_tag_header, 15, 1));
         $next_offset = ftell($this->getid3->fp) - 1 + $data_length;
         switch ($tag_type) {
             case getid3_flv::TAG_AUDIO:
                 if (!isset($info_flv['audio']['audioFormat'])) {
                     $info_flv['audio']['audioFormat'] = $last_header_byte & 0x7;
                     $info_flv['audio']['audioRate'] = ($last_header_byte & 0x30) / 0x10;
                     $info_flv['audio']['audioSampleSize'] = ($last_header_byte & 0x40) / 0x40;
                     $info_flv['audio']['audioType'] = ($last_header_byte & 0x80) / 0x80;
                 }
                 break;
             case getid3_flv::TAG_VIDEO:
                 if (!isset($info_flv['video']['videoCodec'])) {
                     $info_flv['video']['videoCodec'] = $last_header_byte & 0x7;
                     $flv_video_header = fread($this->getid3->fp, 11);
                     if ($info_flv['video']['videoCodec'] != getid3_flv::VIDEO_VP6) {
                         $picture_size_type = getid3_lib::BigEndian2Int(substr($flv_video_header, 3, 2)) >> 7;
                         $picture_size_type = $picture_size_type & 0x7;
                         $info_flv['header']['videoSizeType'] = $picture_size_type;
                         switch ($picture_size_type) {
                             case 0:
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 2));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_x'] = ($picture_size_enc & 0xff00) >> 8;
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 6, 2));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_y'] = ($picture_size_enc & 0xff00) >> 8;
                                 break;
                             case 1:
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 5, 4));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_x'] = ($picture_size_enc & 0xffff0000) >> 16;
                                 $picture_size_enc = getid3_lib::BigEndian2Int(substr($flv_video_header, 7, 4));
                                 $picture_size_enc <<= 1;
                                 $info['video']['resolution_y'] = ($picture_size_enc & 0xffff0000) >> 16;
                                 break;
                             case 2:
                                 $info['video']['resolution_x'] = 352;
                                 $info['video']['resolution_y'] = 288;
                                 break;
                             case 3:
                                 $info['video']['resolution_x'] = 176;
                                 $info['video']['resolution_y'] = 144;
                                 break;
                             case 4:
                                 $info['video']['resolution_x'] = 128;
                                 $info['video']['resolution_y'] = 96;
                                 break;
                             case 5:
                                 $info['video']['resolution_x'] = 320;
                                 $info['video']['resolution_y'] = 240;
                                 break;
                             case 6:
                                 $info['video']['resolution_x'] = 160;
                                 $info['video']['resolution_y'] = 120;
                                 break;
                             default:
                                 $info['video']['resolution_x'] = 0;
                                 $info['video']['resolution_y'] = 0;
                                 break;
                         }
                     }
                 }
                 break;
                 // Meta tag
             // Meta tag
             case getid3_flv::TAG_META:
                 fseek($this->getid3->fp, -1, SEEK_CUR);
                 $reader = new AMFReader(new AMFStream(fread($this->getid3->fp, $data_length)));
                 $event_name = $reader->readData();
                 $info['meta'][$event_name] = $reader->readData();
                 unset($reader);
                 $info['video']['frame_rate'] = @$info['meta']['onMetaData']['framerate'];
                 $info['video']['resolution_x'] = @$info['meta']['onMetaData']['width'];
                 $info['video']['resolution_y'] = @$info['meta']['onMetaData']['height'];
                 break;
             default:
                 // noop
                 break;
         }
         if ($timestamp > $duration) {
             $duration = $timestamp;
         }
         fseek($this->getid3->fp, $next_offset, SEEK_SET);
     }
     if ($info['playtime_seconds'] = $duration / 1000) {
         $info['bitrate'] = ($info['avdataend'] - $info['avdataoffset']) / $info['playtime_seconds'];
     }
     if ($info_flv['header']['hasAudio']) {
         $info['audio']['codec'] = $this->FLVaudioFormat($info_flv['audio']['audioFormat']);
         $info['audio']['sample_rate'] = $this->FLVaudioRate($info_flv['audio']['audioRate']);
         $info['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($info_flv['audio']['audioSampleSize']);
         $info['audio']['channels'] = $info_flv['audio']['audioType'] + 1;
         // 0=mono,1=stereo
         $info['audio']['lossless'] = $info_flv['audio']['audioFormat'] ? false : true;
         // 0=uncompressed
         $info['audio']['dataformat'] = 'flv';
     }
     if (@$info_flv['header']['hasVideo']) {
         $info['video']['codec'] = $this->FLVvideoCodec($info_flv['video']['videoCodec']);
         $info['video']['dataformat'] = 'flv';
         $info['video']['lossless'] = false;
     }
     return true;
 }
 function getid3_flv(&$fd, &$ThisFileInfo, $ReturnAllTagData = false)
 {
     fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
     $FLVfileData = fread($fd, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']);
     $FLVmagic = substr($FLVfileData, 0, 3);
     if ($FLVmagic != 'FLV') {
         $ThisFileInfo['error'][] = 'Expecting "FLV" at offset ' . $ThisFileInfo['avdataoffset'] . ', found "' . $ThisFileInfo['flv']['header']['signature'] . '"';
         unset($ThisFileInfo['flv']);
         unset($ThisFileInfo['fileformat']);
         return false;
     }
     $ThisFileInfo['flv']['header']['signature'] = $FLVmagic;
     $ThisFileInfo['flv']['header']['version'] = ord($FLVfileData[3]);
     $ThisFileInfo['fileformat'] = 'flv';
     $TypeFlags = ord($FLVfileData[4]);
     $ThisFileInfo['flv']['header']['hasAudio'] = (bool) ($TypeFlags & 4);
     $ThisFileInfo['flv']['header']['hasVideo'] = (bool) ($TypeFlags & 1);
     $FrameSizeDataLength = getid3_lib::BigEndian2Int(substr($FLVfileData, 5, 4));
     // FLV tags
     $CurrentOffset = $FrameSizeDataLength;
     $FLVdataLength = strlen($FLVfileData);
     $Duration = 0;
     $SoundFormat = null;
     $VideoFormat = null;
     while ($CurrentOffset < $FLVdataLength) {
         // previous tag size
         $PreviousTagLength = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset, 4));
         $CurrentOffset += 4;
         $TagType = ord(substr($FLVfileData, $CurrentOffset, 1));
         $DataLength = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 1, 3));
         $Timestamp = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 4, 3));
         switch ($TagType) {
             case GETID3_FLV_TAG_AUDIO:
                 if (is_null($SoundFormat)) {
                     $SoundInfo = ord(substr($FLVfileData, $CurrentOffset + 11, 1));
                     $SoundFormat = $SoundInfo & 0x7;
                     $ThisFileInfo['flv']['audio']['audioFormat'] = $SoundFormat;
                     $ThisFileInfo['flv']['audio']['audioRate'] = ($SoundInfo & 0x30) / 0x10;
                     $ThisFileInfo['flv']['audio']['audioSampleSize'] = ($SoundInfo & 0x40) / 0x40;
                     $ThisFileInfo['flv']['audio']['audioType'] = ($SoundInfo & 0x80) / 0x80;
                 }
                 break;
             case GETID3_FLV_TAG_VIDEO:
                 if (is_null($VideoFormat)) {
                     $VideoInfo = ord(substr($FLVfileData, $CurrentOffset + 11, 1));
                     $VideoFormat = $VideoInfo & 0x7;
                     $ThisFileInfo['flv']['video']['videoCodec'] = $VideoFormat;
                     if ($VideoFormat != GETID3_FLV_VIDEO_VP6) {
                         $PictureSizeType = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 15, 2)) >> 7;
                         $PictureSizeType = $PictureSizeType & 0x7;
                         $ThisFileInfo['flv']['header']['videoSizeType'] = $PictureSizeType;
                         switch ($PictureSizeType) {
                             case 0:
                                 $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 16, 2));
                                 $PictureSizeEnc <<= 1;
                                 $ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xff00) >> 8;
                                 $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 17, 2));
                                 $PictureSizeEnc <<= 1;
                                 $ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xff00) >> 8;
                                 break;
                             case 1:
                                 $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 16, 4));
                                 $PictureSizeEnc <<= 1;
                                 $ThisFileInfo['video']['resolution_x'] = ($PictureSizeEnc & 0xffff0000) >> 16;
                                 $PictureSizeEnc = getid3_lib::BigEndian2Int(substr($FLVfileData, $CurrentOffset + 18, 4));
                                 $PictureSizeEnc <<= 1;
                                 $ThisFileInfo['video']['resolution_y'] = ($PictureSizeEnc & 0xffff0000) >> 16;
                                 break;
                             case 2:
                                 $ThisFileInfo['video']['resolution_x'] = 352;
                                 $ThisFileInfo['video']['resolution_y'] = 288;
                                 break;
                             case 3:
                                 $ThisFileInfo['video']['resolution_x'] = 176;
                                 $ThisFileInfo['video']['resolution_y'] = 144;
                                 break;
                             case 4:
                                 $ThisFileInfo['video']['resolution_x'] = 128;
                                 $ThisFileInfo['video']['resolution_y'] = 96;
                                 break;
                             case 5:
                                 $ThisFileInfo['video']['resolution_x'] = 320;
                                 $ThisFileInfo['video']['resolution_y'] = 240;
                                 break;
                             case 6:
                                 $ThisFileInfo['video']['resolution_x'] = 160;
                                 $ThisFileInfo['video']['resolution_y'] = 120;
                                 break;
                             default:
                                 $ThisFileInfo['video']['resolution_x'] = 0;
                                 $ThisFileInfo['video']['resolution_y'] = 0;
                                 break;
                         }
                     }
                 }
                 break;
                 // Meta tag
             // Meta tag
             case GETID3_FLV_TAG_META:
                 $reader = new AMFReader(new AMFStream(substr($FLVfileData, $CurrentOffset + 11, $DataLength)));
                 $eventName = $reader->readData();
                 $ThisFileInfo['meta'][$eventName] = $reader->readData();
                 unset($reader);
                 $ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['meta']['onMetaData']['framerate'];
                 $ThisFileInfo['video']['resolution_x'] = $ThisFileInfo['meta']['onMetaData']['width'];
                 $ThisFileInfo['video']['resolution_y'] = $ThisFileInfo['meta']['onMetaData']['height'];
                 break;
             default:
                 // noop
                 break;
         }
         if ($Timestamp > $Duration) {
             $Duration = $Timestamp;
         }
         $CurrentOffset += $DataLength + 11;
     }
     $ThisFileInfo['playtime_seconds'] = $Duration / 1000;
     $ThisFileInfo['bitrate'] = ($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) / $ThisFileInfo['playtime_seconds'];
     if ($ThisFileInfo['flv']['header']['hasAudio']) {
         $ThisFileInfo['audio']['codec'] = $this->FLVaudioFormat($ThisFileInfo['flv']['audio']['audioFormat']);
         $ThisFileInfo['audio']['sample_rate'] = $this->FLVaudioRate($ThisFileInfo['flv']['audio']['audioRate']);
         $ThisFileInfo['audio']['bits_per_sample'] = $this->FLVaudioBitDepth($ThisFileInfo['flv']['audio']['audioSampleSize']);
         $ThisFileInfo['audio']['channels'] = $ThisFileInfo['flv']['audio']['audioType'] + 1;
         // 0=mono,1=stereo
         $ThisFileInfo['audio']['lossless'] = $ThisFileInfo['flv']['audio']['audioFormat'] ? false : true;
         // 0=uncompressed
         $ThisFileInfo['audio']['dataformat'] = 'flv';
     }
     if (@$ThisFileInfo['flv']['header']['hasVideo']) {
         $ThisFileInfo['video']['codec'] = $this->FLVvideoCodec($ThisFileInfo['flv']['video']['videoCodec']);
         $ThisFileInfo['video']['dataformat'] = 'flv';
         $ThisFileInfo['video']['lossless'] = false;
     }
     return true;
 }