33 $info = &$this->getid3->info;
35 $info[
'fileformat'] =
'mpeg';
38 $MPEGstreamData = $this->
fread($this->getid3->option_fread_buffer_size);
39 $MPEGstreamBaseOffset = 0;
40 $MPEGstreamDataOffset = 0;
42 $StartCodeValue =
false;
43 $prevStartCodeValue =
false;
46 $FramesByGOP = array();
47 $ParsedAVchannels = array();
51 if ($MPEGstreamDataOffset > (strlen($MPEGstreamData) - 16384)) {
54 $MPEGstreamData .= $this->
fread($this->getid3->option_fread_buffer_size);
55 if (strlen($MPEGstreamData) > $this->getid3->option_fread_buffer_size) {
56 $MPEGstreamData = substr($MPEGstreamData, $MPEGstreamDataOffset);
57 $MPEGstreamBaseOffset += $MPEGstreamDataOffset;
58 $MPEGstreamDataOffset = 0;
61 if (($StartCodeOffset = strpos($MPEGstreamData, self::START_CODE_BASE, $MPEGstreamDataOffset)) ===
false) {
65 $MPEGstreamDataOffset = $StartCodeOffset;
66 $prevStartCodeValue = $StartCodeValue;
67 $StartCodeValue = ord(substr($MPEGstreamData, $StartCodeOffset + 3, 1));
70 $MPEGstreamDataOffset += 4;
71 switch ($StartCodeValue) {
74 if (!empty(
$info[
'mpeg'][
'video'][
'bitrate_mode']) && (
$info[
'mpeg'][
'video'][
'bitrate_mode'] ==
'vbr')) {
78 $PictureHeader = array();
80 $PictureHeader[
'temporal_reference'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 10);
81 $PictureHeader[
'picture_coding_type'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 3);
82 $PictureHeader[
'vbv_delay'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 16);
85 $FramesByGOP[$GOPcounter][] = $PictureHeader;
95 $info[
'video'][
'codec'] =
'MPEG-1';
100 $info[
'mpeg'][
'video'][
'raw'][
'horizontal_size_value'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 12);
101 $info[
'mpeg'][
'video'][
'raw'][
'vertical_size_value'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 12);
102 $info[
'mpeg'][
'video'][
'raw'][
'aspect_ratio_information'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
103 $info[
'mpeg'][
'video'][
'raw'][
'frame_rate_code'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
104 $info[
'mpeg'][
'video'][
'raw'][
'bitrate'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 18);
105 $marker_bit = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
106 $info[
'mpeg'][
'video'][
'raw'][
'vbv_buffer_size'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 10);
107 $info[
'mpeg'][
'video'][
'raw'][
'constrained_param_flag'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
108 $info[
'mpeg'][
'video'][
'raw'][
'load_intra_quantiser_matrix'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
110 if (
$info[
'mpeg'][
'video'][
'raw'][
'load_intra_quantiser_matrix']) {
112 for (
$i = 0;
$i < 64;
$i++) {
113 $info[
'mpeg'][
'video'][
'raw'][
'intra_quantiser_matrix'][
$i] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
116 $info[
'mpeg'][
'video'][
'raw'][
'load_non_intra_quantiser_matrix'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
118 if (
$info[
'mpeg'][
'video'][
'raw'][
'load_non_intra_quantiser_matrix']) {
119 $bitstream .=
getid3_lib::BigEndian2Bin(substr($MPEGstreamData, $StartCodeOffset + 12 + (
$info[
'mpeg'][
'video'][
'raw'][
'load_intra_quantiser_matrix'] ? 64 : 0), 64));
120 for (
$i = 0;
$i < 64;
$i++) {
121 $info[
'mpeg'][
'video'][
'raw'][
'non_intra_quantiser_matrix'][
$i] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
125 $info[
'mpeg'][
'video'][
'pixel_aspect_ratio'] = self::videoAspectRatioLookup(
$info[
'mpeg'][
'video'][
'raw'][
'aspect_ratio_information']);
126 $info[
'mpeg'][
'video'][
'pixel_aspect_ratio_text'] = self::videoAspectRatioTextLookup(
$info[
'mpeg'][
'video'][
'raw'][
'aspect_ratio_information']);
127 $info[
'mpeg'][
'video'][
'frame_rate'] = self::videoFramerateLookup(
$info[
'mpeg'][
'video'][
'raw'][
'frame_rate_code']);
128 if (
$info[
'mpeg'][
'video'][
'raw'][
'bitrate'] == 0x3FFFF) {
130 $info[
'mpeg'][
'video'][
'bitrate_mode'] =
'vbr';
132 $info[
'mpeg'][
'video'][
'bitrate'] =
$info[
'mpeg'][
'video'][
'raw'][
'bitrate'] * 400;
133 $info[
'mpeg'][
'video'][
'bitrate_mode'] =
'cbr';
134 $info[
'video'][
'bitrate'] =
$info[
'mpeg'][
'video'][
'bitrate'];
136 $info[
'video'][
'resolution_x'] =
$info[
'mpeg'][
'video'][
'raw'][
'horizontal_size_value'];
137 $info[
'video'][
'resolution_y'] =
$info[
'mpeg'][
'video'][
'raw'][
'vertical_size_value'];
138 $info[
'video'][
'frame_rate'] =
$info[
'mpeg'][
'video'][
'frame_rate'];
139 $info[
'video'][
'bitrate_mode'] =
$info[
'mpeg'][
'video'][
'bitrate_mode'];
140 $info[
'video'][
'pixel_aspect_ratio'] =
$info[
'mpeg'][
'video'][
'pixel_aspect_ratio'];
141 $info[
'video'][
'lossless'] =
false;
142 $info[
'video'][
'bits_per_sample'] = 24;
146 $info[
'video'][
'codec'] =
'MPEG-2';
149 $bitstreamoffset = 0;
151 $info[
'mpeg'][
'video'][
'raw'][
'extension_start_code_identifier'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
153 switch (
$info[
'mpeg'][
'video'][
'raw'][
'extension_start_code_identifier']) {
155 $info[
'mpeg'][
'video'][
'raw'][
'profile_and_level_indication'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
156 $info[
'mpeg'][
'video'][
'raw'][
'progressive_sequence'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
157 $info[
'mpeg'][
'video'][
'raw'][
'chroma_format'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
158 $info[
'mpeg'][
'video'][
'raw'][
'horizontal_size_extension'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
159 $info[
'mpeg'][
'video'][
'raw'][
'vertical_size_extension'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
160 $info[
'mpeg'][
'video'][
'raw'][
'bit_rate_extension'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 12);
161 $marker_bit = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
162 $info[
'mpeg'][
'video'][
'raw'][
'vbv_buffer_size_extension'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
163 $info[
'mpeg'][
'video'][
'raw'][
'low_delay'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
164 $info[
'mpeg'][
'video'][
'raw'][
'frame_rate_extension_n'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
165 $info[
'mpeg'][
'video'][
'raw'][
'frame_rate_extension_d'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 5);
167 $info[
'video'][
'resolution_x'] = (
$info[
'mpeg'][
'video'][
'raw'][
'horizontal_size_extension'] << 12) |
$info[
'mpeg'][
'video'][
'raw'][
'horizontal_size_value'];
168 $info[
'video'][
'resolution_y'] = (
$info[
'mpeg'][
'video'][
'raw'][
'vertical_size_extension'] << 12) |
$info[
'mpeg'][
'video'][
'raw'][
'vertical_size_value'];
169 $info[
'video'][
'interlaced'] = !
$info[
'mpeg'][
'video'][
'raw'][
'progressive_sequence'];
170 $info[
'mpeg'][
'video'][
'interlaced'] = !
$info[
'mpeg'][
'video'][
'raw'][
'progressive_sequence'];
171 $info[
'mpeg'][
'video'][
'chroma_format'] = self::chromaFormatTextLookup(
$info[
'mpeg'][
'video'][
'raw'][
'chroma_format']);
175 $info[
'mpeg'][
'video'][
'raw'][
'video_format'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 3);
176 $info[
'mpeg'][
'video'][
'raw'][
'colour_description'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
177 if (
$info[
'mpeg'][
'video'][
'raw'][
'colour_description']) {
178 $info[
'mpeg'][
'video'][
'raw'][
'colour_primaries'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
179 $info[
'mpeg'][
'video'][
'raw'][
'transfer_characteristics'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
180 $info[
'mpeg'][
'video'][
'raw'][
'matrix_coefficients'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
182 $info[
'mpeg'][
'video'][
'raw'][
'display_horizontal_size'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 14);
183 $marker_bit = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
184 $info[
'mpeg'][
'video'][
'raw'][
'display_vertical_size'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 14);
186 $info[
'mpeg'][
'video'][
'video_format'] = self::videoFormatTextLookup(
$info[
'mpeg'][
'video'][
'raw'][
'video_format']);
193 $info[
'mpeg'][
'video'][
'raw'][
'scalable_mode'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
194 $info[
'mpeg'][
'video'][
'raw'][
'layer_id'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
195 if (
$info[
'mpeg'][
'video'][
'raw'][
'scalable_mode'] == 1) {
196 $info[
'mpeg'][
'video'][
'raw'][
'lower_layer_prediction_horizontal_size'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 14);
197 $marker_bit = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
198 $info[
'mpeg'][
'video'][
'raw'][
'lower_layer_prediction_vertical_size'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 14);
199 $info[
'mpeg'][
'video'][
'raw'][
'horizontal_subsampling_factor_m'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 5);
200 $info[
'mpeg'][
'video'][
'raw'][
'horizontal_subsampling_factor_n'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 5);
201 $info[
'mpeg'][
'video'][
'raw'][
'vertical_subsampling_factor_m'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 5);
202 $info[
'mpeg'][
'video'][
'raw'][
'vertical_subsampling_factor_n'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 5);
203 } elseif (
$info[
'mpeg'][
'video'][
'raw'][
'scalable_mode'] == 3) {
204 $info[
'mpeg'][
'video'][
'raw'][
'picture_mux_enable'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
205 if (
$info[
'mpeg'][
'video'][
'raw'][
'picture_mux_enable']) {
206 $info[
'mpeg'][
'video'][
'raw'][
'mux_to_progressive_sequence'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
208 $info[
'mpeg'][
'video'][
'raw'][
'picture_mux_order'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 3);
209 $info[
'mpeg'][
'video'][
'raw'][
'picture_mux_factor'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 3);
212 $info[
'mpeg'][
'video'][
'scalable_mode'] = self::scalableModeTextLookup(
$info[
'mpeg'][
'video'][
'raw'][
'scalable_mode']);
219 $info[
'mpeg'][
'video'][
'raw'][
'f_code_00'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
220 $info[
'mpeg'][
'video'][
'raw'][
'f_code_01'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
221 $info[
'mpeg'][
'video'][
'raw'][
'f_code_10'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
222 $info[
'mpeg'][
'video'][
'raw'][
'f_code_11'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 4);
223 $info[
'mpeg'][
'video'][
'raw'][
'intra_dc_precision'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
224 $info[
'mpeg'][
'video'][
'raw'][
'picture_structure'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 2);
225 $info[
'mpeg'][
'video'][
'raw'][
'top_field_first'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
226 $info[
'mpeg'][
'video'][
'raw'][
'frame_pred_frame_dct'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
227 $info[
'mpeg'][
'video'][
'raw'][
'concealment_motion_vectors'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
228 $info[
'mpeg'][
'video'][
'raw'][
'q_scale_type'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
229 $info[
'mpeg'][
'video'][
'raw'][
'intra_vlc_format'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
230 $info[
'mpeg'][
'video'][
'raw'][
'alternate_scan'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
231 $info[
'mpeg'][
'video'][
'raw'][
'repeat_first_field'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
232 $info[
'mpeg'][
'video'][
'raw'][
'chroma_420_type'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
233 $info[
'mpeg'][
'video'][
'raw'][
'progressive_frame'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
234 $info[
'mpeg'][
'video'][
'raw'][
'composite_display_flag'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
235 if (
$info[
'mpeg'][
'video'][
'raw'][
'composite_display_flag']) {
236 $info[
'mpeg'][
'video'][
'raw'][
'v_axis'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
237 $info[
'mpeg'][
'video'][
'raw'][
'field_sequence'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 3);
238 $info[
'mpeg'][
'video'][
'raw'][
'sub_carrier'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
239 $info[
'mpeg'][
'video'][
'raw'][
'burst_amplitude'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 7);
240 $info[
'mpeg'][
'video'][
'raw'][
'sub_carrier_phase'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 8);
243 $info[
'mpeg'][
'video'][
'intra_dc_precision_bits'] =
$info[
'mpeg'][
'video'][
'raw'][
'intra_dc_precision'] + 8;
244 $info[
'mpeg'][
'video'][
'picture_structure'] = self::pictureStructureTextLookup(
$info[
'mpeg'][
'video'][
'raw'][
'picture_structure']);
253 $this->
warning(
'Unexpected $info[mpeg][video][raw][extension_start_code_identifier] value of '.
$info[
'mpeg'][
'video'][
'raw'][
'extension_start_code_identifier']);
261 if (
$info[
'mpeg'][
'video'][
'bitrate_mode'] ==
'vbr') {
263 $bitstreamoffset = 0;
265 $GOPheader = array();
267 $GOPheader[
'byte_offset'] = $MPEGstreamBaseOffset + $StartCodeOffset;
268 $GOPheader[
'drop_frame_flag'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
269 $GOPheader[
'time_code_hours'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 5);
270 $GOPheader[
'time_code_minutes'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 6);
271 $marker_bit = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
272 $GOPheader[
'time_code_seconds'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 6);
273 $GOPheader[
'time_code_pictures'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 6);
274 $GOPheader[
'closed_gop'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
275 $GOPheader[
'broken_link'] = self::readBitsFromStream($bitstream, $bitstreamoffset, 1);
277 $time_code_separator = ($GOPheader[
'drop_frame_flag'] ?
';' :
':');
278 $GOPheader[
'time_code'] = sprintf(
'%02d'.$time_code_separator.
'%02d'.$time_code_separator.
'%02d'.$time_code_separator.
'%02d', $GOPheader[
'time_code_hours'], $GOPheader[
'time_code_minutes'], $GOPheader[
'time_code_seconds'], $GOPheader[
'time_code_pictures']);
280 $info[
'mpeg'][
'group_of_pictures'][] = $GOPheader;
332 if (isset($ParsedAVchannels[$StartCodeValue])) {
335 $ParsedAVchannels[$StartCodeValue] = $StartCodeValue;
382 $getid3_temp =
new getID3();
383 $getid3_temp->openfile($this->getid3->filename);
384 $getid3_temp->info =
$info;
386 for (
$i = 0;
$i <= 7;
$i++) {
390 $getid3_temp->info =
$info;
392 if ($getid3_mp3->decodeMPEGaudioHeader($MPEGstreamBaseOffset + $StartCodeOffset + 4 + 8 +
$i, $getid3_temp->info,
false)) {
394 $info = $getid3_temp->info;
395 $info[
'audio'][
'bitrate_mode'] =
'cbr';
396 $info[
'audio'][
'lossless'] =
false;
400 unset($getid3_temp, $getid3_mp3);
490 if (!empty(
$info[
'mpeg'][
'video'][
'bitrate_mode']) && (
$info[
'mpeg'][
'video'][
'bitrate_mode'] ==
'vbr')) {
491 $last_GOP_id = max(array_keys($FramesByGOP));
492 $frames_in_last_GOP = count($FramesByGOP[$last_GOP_id]);
493 $gopdata = &
$info[
'mpeg'][
'group_of_pictures'][$last_GOP_id];
494 $info[
'playtime_seconds'] = ($gopdata[
'time_code_hours'] * 3600) + ($gopdata[
'time_code_minutes'] * 60) + $gopdata[
'time_code_seconds'] + (($gopdata[
'time_code_pictures'] + $frames_in_last_GOP + 1) /
$info[
'mpeg'][
'video'][
'frame_rate']);
495 if (!isset(
$info[
'video'][
'bitrate'])) {
496 $overall_bitrate = (
$info[
'avdataend'] -
$info[
'avdataoffset']) * 8 /
$info[
'playtime_seconds'];
497 $info[
'video'][
'bitrate'] = $overall_bitrate - (isset(
$info[
'audio'][
'bitrate']) ?
$info[
'audio'][
'bitrate'] : 0);
499 unset(
$info[
'mpeg'][
'group_of_pictures']);
static BigEndian2Bin($byteword)
fseek($bytes, $whence=SEEK_SET)