31 {
32 if ($ThisFileInfo['avdataend'] <= $ThisFileInfo['avdataoffset']) {
33 $ThisFileInfo['error'][] = '"avdataend" ('.$ThisFileInfo['avdataend'].') is unexpectedly less-than-or-equal-to "avdataoffset" ('.$ThisFileInfo['avdataoffset'].')';
34 return false;
35 }
36 $ThisFileInfo['fileformat'] = 'mpeg';
37 fseek($fd, $ThisFileInfo['avdataoffset'], SEEK_SET);
38 $MPEGstreamData = fread($fd, min(100000, $ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']));
39 $MPEGstreamDataLength = strlen($MPEGstreamData);
40
41 $foundVideo = true;
42 $VideoChunkOffset = 0;
44 if ($VideoChunkOffset >= $MPEGstreamDataLength) {
45 $foundVideo = false;
46 break;
47 }
48 }
49 if ($foundVideo) {
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 $ThisFileInfo['video']['dataformat'] = 'mpeg';
66
68
70 $VideoChunkOffset += 3;
71
73 $VideoChunkOffset += 1;
74
76 $VideoChunkOffset += 4;
77
78 $ThisFileInfo['mpeg']['video']['raw']['framesize_horizontal'] = ($FrameSizeDWORD & 0xFFF000) >> 12;
79 $ThisFileInfo['mpeg']['video']['raw']['framesize_vertical'] = ($FrameSizeDWORD & 0x000FFF);
80 $ThisFileInfo['mpeg']['video']['raw']['pixel_aspect_ratio'] = ($AspectRatioFrameRateDWORD & 0xF0) >> 4;
81 $ThisFileInfo['mpeg']['video']['raw']['frame_rate'] = ($AspectRatioFrameRateDWORD & 0x0F);
82
83 $ThisFileInfo['mpeg']['video']['framesize_horizontal'] = $ThisFileInfo['mpeg']['video']['raw']['framesize_horizontal'];
84 $ThisFileInfo['mpeg']['video']['framesize_vertical'] = $ThisFileInfo['mpeg']['video']['raw']['framesize_vertical'];
85
86 $ThisFileInfo[
'mpeg'][
'video'][
'pixel_aspect_ratio'] = $this->
MPEGvideoAspectRatioLookup($ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'pixel_aspect_ratio']);
87 $ThisFileInfo[
'mpeg'][
'video'][
'pixel_aspect_ratio_text'] = $this->
MPEGvideoAspectRatioTextLookup($ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'pixel_aspect_ratio']);
88 $ThisFileInfo[
'mpeg'][
'video'][
'frame_rate'] = $this->
MPEGvideoFramerateLookup($ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'frame_rate']);
89
90 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'bitrate'] =
getid3_lib::Bin2Dec(substr($assortedinformation, 0, 18));
91 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'marker_bit'] = (bool)
getid3_lib::Bin2Dec(substr($assortedinformation, 18, 1));
92 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'vbv_buffer_size'] =
getid3_lib::Bin2Dec(substr($assortedinformation, 19, 10));
93 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'constrained_param_flag'] = (bool)
getid3_lib::Bin2Dec(substr($assortedinformation, 29, 1));
94 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'intra_quant_flag'] = (bool)
getid3_lib::Bin2Dec(substr($assortedinformation, 30, 1));
95 if ($ThisFileInfo['mpeg']['video']['raw']['intra_quant_flag']) {
96
97
98 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'intra_quant'] =
getid3_lib::BigEndian2Bin(substr($MPEGstreamData, $VideoChunkOffset, 64));
99 $VideoChunkOffset += 64;
100
101 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'non_intra_quant_flag'] = (bool)
getid3_lib::Bin2Dec(substr($ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'intra_quant'], 511, 1));
103
104 if ($ThisFileInfo['mpeg']['video']['raw']['non_intra_quant_flag']) {
105 $ThisFileInfo['mpeg']['video']['raw']['non_intra_quant'] = substr($MPEGstreamData, $VideoChunkOffset, 64);
106 $VideoChunkOffset += 64;
107 }
108
109 } else {
110
111 $ThisFileInfo[
'mpeg'][
'video'][
'raw'][
'non_intra_quant_flag'] = (bool)
getid3_lib::Bin2Dec(substr($assortedinformation, 31, 1));
112 if ($ThisFileInfo['mpeg']['video']['raw']['non_intra_quant_flag']) {
113 $ThisFileInfo['mpeg']['video']['raw']['non_intra_quant'] = substr($MPEGstreamData, $VideoChunkOffset, 64);
114 $VideoChunkOffset += 64;
115 }
116
117 }
118
119 if ($ThisFileInfo['mpeg']['video']['raw']['bitrate'] == 0x3FFFF) {
120
121 $ThisFileInfo['warning'][] = 'This version of getID3() ['.GETID3_VERSION.'] cannot determine average bitrate of VBR MPEG video files';
122 $ThisFileInfo['mpeg']['video']['bitrate_mode'] = 'vbr';
123
124 } else {
125
126 $ThisFileInfo['mpeg']['video']['bitrate'] = $ThisFileInfo['mpeg']['video']['raw']['bitrate'] * 400;
127 $ThisFileInfo['mpeg']['video']['bitrate_mode'] = 'cbr';
128 $ThisFileInfo['video']['bitrate'] = $ThisFileInfo['mpeg']['video']['bitrate'];
129
130 }
131
132 $ThisFileInfo['video']['resolution_x'] = $ThisFileInfo['mpeg']['video']['framesize_horizontal'];
133 $ThisFileInfo['video']['resolution_y'] = $ThisFileInfo['mpeg']['video']['framesize_vertical'];
134 $ThisFileInfo['video']['frame_rate'] = $ThisFileInfo['mpeg']['video']['frame_rate'];
135 $ThisFileInfo['video']['bitrate_mode'] = $ThisFileInfo['mpeg']['video']['bitrate_mode'];
136 $ThisFileInfo['video']['pixel_aspect_ratio'] = $ThisFileInfo['mpeg']['video']['pixel_aspect_ratio'];
137 $ThisFileInfo['video']['lossless'] = false;
138 $ThisFileInfo['video']['bits_per_sample'] = 24;
139
140 } else {
141
142 $ThisFileInfo['error'][] = 'Could not find start of video block in the first 100,000 bytes (or before end of file) - this might not be an MPEG-video file?';
143
144 }
145
146
147
148
149
150
151
152
154 $ThisFileInfo['video']['codec'] = 'MPEG-2';
155 } else {
156 $ThisFileInfo['video']['codec'] = 'MPEG-1';
157 }
158
159
160 $AudioChunkOffset = 0;
161 while (true) {
163 if ($AudioChunkOffset >= $MPEGstreamDataLength) {
164 break 2;
165 }
166 }
167
168 for ($i = 0; $i <= 7; $i++) {
169
170
171
172
173 $dummy = $ThisFileInfo;
175 $ThisFileInfo = $dummy;
176 $ThisFileInfo['audio']['bitrate_mode'] = 'cbr';
177 $ThisFileInfo['audio']['lossless'] = false;
178 break 2;
179
180 }
181 }
182 }
183
184
185 if (!empty($ThisFileInfo['video']['bitrate']) && !empty($ThisFileInfo['audio']['bitrate'])) {
186 $ThisFileInfo['playtime_seconds'] = (($ThisFileInfo['avdataend'] - $ThisFileInfo['avdataoffset']) * 8) / ($ThisFileInfo['video']['bitrate'] + $ThisFileInfo['audio']['bitrate']);
187
188
189
190
191
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213 if ($ThisFileInfo['video']['bitrate'] < 50000) {
214 $ThisFileInfo['warning'][] = 'Interleaved MPEG audio/video playtime may be slightly inaccurate for video bitrates below 100kbps. Except in extreme low-bitrate situations, error should be less than 1%. Report to info@getid3.org if greater than this.';
215 }
216 }
217
218 return true;
219 }
BigEndian2Int($byteword, $synchsafe=false, $signed=false)
Bin2Dec($binstring, $signed=false)
decodeMPEGaudioHeader($fd, $offset, &$ThisFileInfo, $recursivesearch=true, $ScanAsCBR=false, $FastMPEGheaderScan=false)
MPEGvideoAspectRatioLookup($rawaspectratio)
MPEGsystemNonOverheadPercentage($VideoBitrate, $AudioBitrate)
MPEGvideoAspectRatioTextLookup($rawaspectratio)
MPEGvideoFramerateLookup($rawframerate)
const GETID3_MPEG_VIDEO_EXTENSION_START
const GETID3_MPEG_VIDEO_SEQUENCE_HEADER
const GETID3_MPEG_AUDIO_START