Changeset 7ac10f1db02d25da1deb18e4b3ba230e48b98828
- Timestamp:
- 02/02/05 16:54:00
(4 years ago)
- Author:
- Gildas Bazin <gbazin@videolan.org>
- git-committer:
- Gildas Bazin <gbazin@videolan.org> 1107359640 +0000
- git-parent:
[63709bff1f8504fa7145ac67e111dbd18ad419c5]
- git-author:
- Gildas Bazin <gbazin@videolan.org> 1107359640 +0000
- Message:
* modules/packetizer/mpeg4video.c: proper PTS/DTS calculation.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| ra90a19a |
r7ac10f1 |
|
| 7 | 7 | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
|---|
| 8 | 8 | * Eric Petit <titer@videolan.org> |
|---|
| 9 | | * Gildas Bazin <gbazin@netcourrier.com> |
|---|
| | 9 | * Gildas Bazin <gbazin@videolan.org> |
|---|
| 10 | 10 | * |
|---|
| 11 | 11 | * This program is free software; you can redistribute it and/or modify |
|---|
| … | … | |
| 60 | 60 | * Common properties |
|---|
| 61 | 61 | */ |
|---|
| 62 | | mtime_t i_pts; |
|---|
| 63 | | mtime_t i_dts; |
|---|
| 64 | | |
|---|
| | 62 | mtime_t i_interpolated_pts; |
|---|
| | 63 | mtime_t i_interpolated_dts; |
|---|
| | 64 | mtime_t i_last_ref_pts; |
|---|
| | 65 | mtime_t i_last_time_ref; |
|---|
| | 66 | mtime_t i_time_ref; |
|---|
| | 67 | mtime_t i_last_time; |
|---|
| | 68 | mtime_t i_last_timeincr; |
|---|
| 65 | 69 | |
|---|
| 66 | 70 | vlc_bool_t b_vop; |
|---|
| … | … | |
| 70 | 74 | unsigned int i_flags; |
|---|
| 71 | 75 | |
|---|
| | 76 | int i_fps_num; |
|---|
| | 77 | int i_fps_den; |
|---|
| | 78 | int i_last_incr; |
|---|
| | 79 | int i_last_incr_diff; |
|---|
| | 80 | |
|---|
| 72 | 81 | vlc_bool_t b_frame; |
|---|
| 73 | 82 | }; |
|---|
| 74 | 83 | |
|---|
| 75 | | static int m4v_FindStartCode( uint8_t **pp_start, uint8_t *p_end ); |
|---|
| 76 | | static int m4v_VOLParse( es_format_t *fmt, uint8_t *p_vol, int i_vol ); |
|---|
| | 84 | static int m4v_FindStartCode( uint8_t **, uint8_t * ); |
|---|
| | 85 | static int m4v_VOLParse( decoder_t *, es_format_t *, uint8_t *, int ); |
|---|
| | 86 | static int vlc_log2( unsigned int ); |
|---|
| 77 | 87 | |
|---|
| 78 | 88 | #define VIDEO_OBJECT_MASK 0x01f |
|---|
| … | … | |
| 134 | 144 | return VLC_EGENERIC; |
|---|
| 135 | 145 | } |
|---|
| 136 | | p_sys->i_pts = 0; |
|---|
| 137 | | p_sys->i_dts = 0; |
|---|
| 138 | | p_sys->b_vop = VLC_FALSE; |
|---|
| 139 | | p_sys->i_buffer = 0; |
|---|
| 140 | | p_sys->i_buffer_size = 0; |
|---|
| 141 | | p_sys->p_buffer = 0; |
|---|
| 142 | | p_sys->i_flags = 0; |
|---|
| 143 | | p_sys->b_frame = VLC_FALSE; |
|---|
| | 146 | memset( p_sys, 0, sizeof(decoder_sys_t) ); |
|---|
| 144 | 147 | |
|---|
| 145 | 148 | /* Setup properties */ |
|---|
| … | … | |
| 156 | 159 | |
|---|
| 157 | 160 | msg_Dbg( p_dec, "opening with vol size:%d", p_dec->fmt_in.i_extra ); |
|---|
| 158 | | m4v_VOLParse( &p_dec->fmt_out, |
|---|
| | 161 | m4v_VOLParse( p_dec, &p_dec->fmt_out, |
|---|
| 159 | 162 | p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra ); |
|---|
| 160 | 163 | } |
|---|
| … | … | |
| 238 | 241 | realloc( p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra ); |
|---|
| 239 | 242 | memcpy( p_dec->fmt_out.p_extra, p_vol, p_dec->fmt_out.i_extra ); |
|---|
| 240 | | m4v_VOLParse( &p_dec->fmt_out, |
|---|
| | 243 | m4v_VOLParse( p_dec, &p_dec->fmt_out, |
|---|
| 241 | 244 | p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra ); |
|---|
| 242 | 245 | |
|---|
| … | … | |
| 260 | 263 | |
|---|
| 261 | 264 | p_out->i_flags = p_sys->i_flags; |
|---|
| 262 | | |
|---|
| 263 | | /* FIXME do proper dts/pts */ |
|---|
| 264 | | p_out->i_pts = p_sys->i_pts; |
|---|
| 265 | | p_out->i_dts = p_sys->i_dts; |
|---|
| | 265 | p_out->i_pts = p_sys->i_interpolated_pts; |
|---|
| | 266 | p_out->i_dts = p_sys->i_interpolated_dts; |
|---|
| | 267 | |
|---|
| 266 | 268 | /* FIXME doesn't work when there is multiple VOP in one block */ |
|---|
| 267 | | if( p_block->i_dts > p_sys->i_dts ) |
|---|
| 268 | | { |
|---|
| 269 | | p_out->i_length = p_block->i_dts - p_sys->i_dts; |
|---|
| | 269 | if( p_block->i_dts > p_sys->i_interpolated_dts ) |
|---|
| | 270 | { |
|---|
| | 271 | p_out->i_length = p_block->i_dts - p_sys->i_interpolated_dts; |
|---|
| 270 | 272 | } |
|---|
| 271 | 273 | |
|---|
| … | … | |
| 280 | 282 | } |
|---|
| 281 | 283 | |
|---|
| 282 | | #if 0 |
|---|
| 283 | | fprintf( stderr, "pts=%lld dts=%lld length=%lldms\n", |
|---|
| 284 | | p_out->i_pts, p_out->i_dts, |
|---|
| 285 | | p_out->i_length / 1000 ); |
|---|
| 286 | | #endif |
|---|
| 287 | 284 | p_sys->b_vop = VLC_FALSE; |
|---|
| 288 | 285 | } |
|---|
| … | … | |
| 293 | 290 | p_vol = p_start; |
|---|
| 294 | 291 | } |
|---|
| | 292 | else if( p_start[3] == 0xb3 ) |
|---|
| | 293 | { |
|---|
| | 294 | /* GOP header */ |
|---|
| | 295 | } |
|---|
| 295 | 296 | else if( p_start[3] == 0xb6 ) |
|---|
| 296 | 297 | { |
|---|
| 297 | | p_sys->b_vop = VLC_TRUE; |
|---|
| 298 | | switch( p_start[4] >> 6 ) |
|---|
| | 298 | /* Parse the VOP */ |
|---|
| | 299 | bs_t s; |
|---|
| | 300 | int i_modulo_time_base = 0; |
|---|
| | 301 | int i_time_increment_bits; |
|---|
| | 302 | int64_t i_time_increment, i_time_ref; |
|---|
| | 303 | |
|---|
| | 304 | /* FIXME: we don't actually check we received enough data to read |
|---|
| | 305 | * the VOP time increment. */ |
|---|
| | 306 | bs_init( &s, &p_start[4], |
|---|
| | 307 | p_sys->i_buffer - (p_start - p_sys->p_buffer) - 4 ); |
|---|
| | 308 | |
|---|
| | 309 | switch( bs_read( &s, 2 ) ) |
|---|
| 299 | 310 | { |
|---|
| 300 | 311 | case 0: |
|---|
| … | … | |
| 313 | 324 | } |
|---|
| 314 | 325 | |
|---|
| 315 | | /* The pts information is not available in all the containers. |
|---|
| 316 | | * FIXME: calculate the pts correctly */ |
|---|
| | 326 | while( bs_read( &s, 1 ) ) i_modulo_time_base++; |
|---|
| | 327 | if( !bs_read1( &s ) ) continue; /* Marker */ |
|---|
| | 328 | |
|---|
| | 329 | /* VOP time increment */ |
|---|
| | 330 | i_time_increment_bits = vlc_log2(p_dec->p_sys->i_fps_num - 1) + 1; |
|---|
| | 331 | if( i_time_increment_bits < 1 ) i_time_increment_bits = 1; |
|---|
| | 332 | i_time_increment = bs_read( &s, i_time_increment_bits ); |
|---|
| | 333 | |
|---|
| | 334 | /* Interpolate PTS/DTS */ |
|---|
| | 335 | if( !(p_sys->i_flags & BLOCK_FLAG_TYPE_B) ) |
|---|
| | 336 | { |
|---|
| | 337 | p_sys->i_last_time_ref = p_sys->i_time_ref; |
|---|
| | 338 | p_sys->i_time_ref += |
|---|
| | 339 | (i_modulo_time_base * p_dec->p_sys->i_fps_num); |
|---|
| | 340 | i_time_ref = p_sys->i_time_ref; |
|---|
| | 341 | } |
|---|
| | 342 | else |
|---|
| | 343 | { |
|---|
| | 344 | i_time_ref = p_sys->i_last_time_ref + |
|---|
| | 345 | (i_modulo_time_base * p_dec->p_sys->i_fps_num); |
|---|
| | 346 | } |
|---|
| | 347 | |
|---|
| | 348 | p_sys->i_interpolated_pts += |
|---|
| | 349 | ( (i_time_ref + i_time_increment - |
|---|
| | 350 | p_sys->i_last_time - p_sys->i_last_timeincr) * |
|---|
| | 351 | I64C(1000000) / p_dec->p_sys->i_fps_num ); |
|---|
| | 352 | |
|---|
| | 353 | p_sys->i_last_time = i_time_ref; |
|---|
| | 354 | p_sys->i_last_timeincr = i_time_increment; |
|---|
| | 355 | |
|---|
| | 356 | /* Correct interpolated dts when we receive a new pts/dts */ |
|---|
| 317 | 357 | if( p_block->i_pts > 0 ) |
|---|
| 318 | | { |
|---|
| 319 | | p_sys->i_pts = p_block->i_pts; |
|---|
| 320 | | } |
|---|
| 321 | | else if( (p_sys->i_flags&BLOCK_FLAG_TYPE_B) || !p_sys->b_frame ) |
|---|
| 322 | | { |
|---|
| 323 | | p_sys->i_pts = p_block->i_dts; |
|---|
| | 358 | p_sys->i_interpolated_pts = p_block->i_pts; |
|---|
| | 359 | if( p_block->i_dts > 0 ) |
|---|
| | 360 | p_sys->i_interpolated_dts = p_block->i_dts; |
|---|
| | 361 | |
|---|
| | 362 | if( (p_sys->i_flags & BLOCK_FLAG_TYPE_B) || !p_sys->b_frame ) |
|---|
| | 363 | { |
|---|
| | 364 | /* Trivial case (DTS == PTS) */ |
|---|
| | 365 | |
|---|
| | 366 | p_sys->i_interpolated_dts = p_sys->i_interpolated_pts; |
|---|
| | 367 | |
|---|
| | 368 | if( p_block->i_pts > 0 ) |
|---|
| | 369 | p_sys->i_interpolated_dts = p_block->i_pts; |
|---|
| | 370 | |
|---|
| | 371 | p_sys->i_interpolated_pts = p_sys->i_interpolated_dts; |
|---|
| 324 | 372 | } |
|---|
| 325 | 373 | else |
|---|
| 326 | 374 | { |
|---|
| 327 | | p_sys->i_pts = 0; |
|---|
| 328 | | } |
|---|
| 329 | | if( p_block->i_dts > 0 ) |
|---|
| 330 | | { |
|---|
| 331 | | p_sys->i_dts = p_block->i_dts; |
|---|
| 332 | | } |
|---|
| 333 | | else if( p_sys->i_dts > 0 ) |
|---|
| 334 | | { |
|---|
| 335 | | /* XXX KLUDGE immonde, else transcode won't work */ |
|---|
| 336 | | p_sys->i_dts += 1000; |
|---|
| 337 | | } |
|---|
| 338 | | } |
|---|
| | 375 | if( p_sys->i_last_ref_pts > 0 ) |
|---|
| | 376 | p_sys->i_interpolated_dts = p_sys->i_last_ref_pts; |
|---|
| | 377 | |
|---|
| | 378 | p_sys->i_last_ref_pts = p_sys->i_interpolated_pts; |
|---|
| | 379 | } |
|---|
| | 380 | |
|---|
| | 381 | p_sys->b_vop = VLC_TRUE; |
|---|
| | 382 | |
|---|
| | 383 | /* Don't re-use the same PTS/DTS twice */ |
|---|
| | 384 | p_block->i_pts = p_block->i_dts = 0; |
|---|
| | 385 | } |
|---|
| | 386 | |
|---|
| 339 | 387 | p_start += 4; /* Next */ |
|---|
| 340 | 388 | } |
|---|
| … | … | |
| 396 | 444 | * - support aspect ratio |
|---|
| 397 | 445 | */ |
|---|
| 398 | | static int m4v_VOLParse( es_format_t *fmt, uint8_t *p_vol, int i_vol ) |
|---|
| | 446 | static int m4v_VOLParse( decoder_t *p_dec, es_format_t *fmt, |
|---|
| | 447 | uint8_t *p_vol, int i_vol ) |
|---|
| 399 | 448 | { |
|---|
| 400 | 449 | bs_t s; |
|---|
| … | … | |
| 403 | 452 | int i_ar; |
|---|
| 404 | 453 | int i_shape; |
|---|
| 405 | | int i_time_increment_resolution; |
|---|
| 406 | 454 | |
|---|
| 407 | 455 | for( ;; ) |
|---|
| … | … | |
| 470 | 518 | } |
|---|
| 471 | 519 | |
|---|
| 472 | | if( !bs_read1( &s ) ) |
|---|
| 473 | | { |
|---|
| 474 | | /* marker */ |
|---|
| 475 | | return VLC_EGENERIC; |
|---|
| 476 | | } |
|---|
| 477 | | i_time_increment_resolution = bs_read( &s, 16 ); |
|---|
| 478 | | if( !bs_read1( &s ) ) |
|---|
| 479 | | { |
|---|
| 480 | | /* marker */ |
|---|
| 481 | | return VLC_EGENERIC; |
|---|
| 482 | | } |
|---|
| | 520 | if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */ |
|---|
| | 521 | |
|---|
| | 522 | p_dec->p_sys->i_fps_num = bs_read( &s, 16 ); /* Time increment resolution*/ |
|---|
| | 523 | if( !p_dec->p_sys->i_fps_num ) p_dec->p_sys->i_fps_num = 1; |
|---|
| | 524 | |
|---|
| | 525 | if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */ |
|---|
| 483 | 526 | |
|---|
| 484 | 527 | if( bs_read1( &s ) ) |
|---|
| 485 | 528 | { |
|---|
| 486 | | int i_time_increment_bits = vlc_log2( i_time_increment_resolution - 1 ) + 1; |
|---|
| 487 | | if( i_time_increment_bits < 1 ) |
|---|
| 488 | | { |
|---|
| 489 | | i_time_increment_bits = 1; |
|---|
| 490 | | } |
|---|
| 491 | | bs_skip( &s, i_time_increment_bits ); |
|---|
| | 529 | int i_time_increment_bits = |
|---|
| | 530 | vlc_log2( p_dec->p_sys->i_fps_num - 1 ) + 1; |
|---|
| | 531 | |
|---|
| | 532 | if( i_time_increment_bits < 1 ) i_time_increment_bits = 1; |
|---|
| | 533 | |
|---|
| | 534 | p_dec->p_sys->i_fps_den = bs_read( &s, i_time_increment_bits ); |
|---|
| 492 | 535 | } |
|---|
| 493 | 536 | if( i_shape == 0 ) |
|---|