comparison libmpdemux/mpeg_hdr.c @ 14798:0bd50330e688

framerate autodetection for H264 in raw/ts streams
author nicodvb
date Thu, 24 Feb 2005 20:02:41 +0000
parents 92553e3c8f01
children a109ae86ba63
comparison
equal deleted inserted replaced
14797:05eab20de476 14798:0bd50330e688
208 n++; 208 n++;
209 getbits(buffer, n, 1); 209 getbits(buffer, n, 1);
210 n++; 210 n++;
211 n = read_timeinc(picture, buffer, n); 211 n = read_timeinc(picture, buffer, n);
212 } 212 }
213
214 #define min(a, b) ((a) <= (b) ? (a) : (b))
215
216 static unsigned int read_golomb(unsigned char *buffer, unsigned int *init)
217 {
218 unsigned int x, v = 0, v2 = 0, m, len = 0, n = *init;
219
220 while(getbits(buffer, n++, 1) == 0)
221 len++;
222
223 x = len + n;
224 while(n < x)
225 {
226 m = min(x - n, 8);
227 v |= getbits(buffer, n, m);
228 n += m;
229 if(x - n > 8)
230 v <<= 8;
231 }
232
233 v2 = 1;
234 for(n = 0; n < len; n++)
235 v2 <<= 1;
236 v2 = (v2 - 1) + v;
237
238 //fprintf(stderr, "READ_GOLOMB(%u), V=2^%u + %u-1 = %u\n", *init, len, v, v2);
239 *init = x;
240 return v2;
241 }
242
243
244 static int h264_parse_vui(mp_mpeg_header_t * picture, unsigned char * buf, unsigned int n)
245 {
246 unsigned int overscan, vsp_color, chroma, timing, fixed_fps;
247
248 if(getbits(buf, n++, 1))
249 {
250 picture->aspect_ratio_information = getbits(buf, n, 8);
251 n += 8;
252 if(picture->aspect_ratio_information == 255)
253 {
254 picture->display_picture_width = (getbits(buf, n, 8) << 8) | getbits(buf, n + 8, 8);
255 n += 16;
256
257 picture->display_picture_height = (getbits(buf, n, 8) << 8) | getbits(buf, n + 8, 8);
258 n += 16;
259 }
260 }
261
262 if(overscan=getbits(buf, n++, 1))
263 n++;
264 if(vsp_color=getbits(buf, n++, 1))
265 {
266 n += 4;
267 if(getbits(buf, n++, 1))
268 n += 24;
269 }
270 if(chroma=getbits(buf, n++, 1))
271 {
272 read_golomb(buf, &n);
273 read_golomb(buf, &n);
274 }
275 if(timing=getbits(buf, n++, 1))
276 {
277 picture->timeinc_unit = (getbits(buf, n, 8) << 24) | (getbits(buf, n+8, 8) << 16) | (getbits(buf, n+16, 8) << 8) | getbits(buf, n+24, 8);
278 n += 32;
279
280 picture->timeinc_resolution = (getbits(buf, n, 8) << 24) | (getbits(buf, n+8, 8) << 16) | (getbits(buf, n+16, 8) << 8) | getbits(buf, n+24, 8);
281 n += 32;
282
283 fixed_fps = getbits(buf, n, 1);
284
285 if(picture->timeinc_unit > 0 && picture->timeinc_resolution > 0)
286 picture->fps = (picture->timeinc_resolution * 10000) / picture->timeinc_unit;
287 }
288
289 //fprintf(stderr, "H264_PARSE_VUI, OVESCAN=%u, VSP_COLOR=%u, CHROMA=%u, TIMING=%u, DISPW=%u, DISPH=%u, TIMERES=%u, TIMEINC=%u, FIXED_FPS=%u\n", overscan, vsp_color, chroma, timing, picture->display_picture_width, picture->display_picture_height,
290 // picture->timeinc_resolution, picture->timeinc_unit, picture->timeinc_unit, fixed_fps);
291
292 return n;
293 }
294
295 int h264_parse_sps(mp_mpeg_header_t * picture, unsigned char * buf, int len)
296 {
297 unsigned int n = 0, m = 0, v, i, j;
298 unsigned char *dest;
299
300 dest = (unsigned char*) malloc(len);
301 if(! dest)
302 return 0;
303 j = i = 0;
304 while(i <= len-3)
305 {
306 if(buf[i] == 0 && buf[i+1] == 0 && buf[i+2] == 3)
307 {
308 dest[j] = dest[j+1] = 0;
309 j += 2;
310 i += 3;
311 }
312 else
313 {
314 dest[j] = buf[i];
315 j++;
316 i++;
317 }
318 }
319 dest[j] = buf[len-2];
320 dest[j+1] = buf[len-1];
321 j += 2;
322 len = j+1;
323 buf = dest;
324
325 picture->fps = picture->timeinc_unit = picture->timeinc_resolution = 0;
326 n = 24;
327 read_golomb(buf, &n);
328 read_golomb(buf, &n);
329 v = read_golomb(buf, &n);
330 if(v == 0)
331 read_golomb(buf, &n);
332 else if(v == 1)
333 {
334 getbits(buf, n++, 1);
335 read_golomb(buf, &n);
336 read_golomb(buf, &n);
337 v = read_golomb(buf, &n);
338 for(i = 0; i < v; i++)
339 read_golomb(buf, &n);
340 }
341 read_golomb(buf, &n);
342 getbits(buf, n++, 1);
343 read_golomb(buf, &n);
344 read_golomb(buf, &n);
345 if(!getbits(buf, n++, 1))
346 getbits(buf, n++, 1);
347 getbits(buf, n++, 1);
348 if(getbits(buf, n++, 1))
349 {
350 read_golomb(buf, &n);
351 read_golomb(buf, &n);
352 read_golomb(buf, &n);
353 read_golomb(buf, &n);
354 }
355 if(getbits(buf, n++, 1))
356 n = h264_parse_vui(picture, buf, n);
357
358 free(dest);
359 return n;
360 }