comparison utils.c @ 462:b69898ffc92a libavformat

move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
author michael
date Fri, 21 May 2004 20:43:21 +0000
parents a699cf5c703d
children 696f41bc8784
comparison
equal deleted inserted replaced
461:63540e5504f7 462:b69898ffc92a
353 } 353 }
354 } else { 354 } else {
355 ic->priv_data = NULL; 355 ic->priv_data = NULL;
356 } 356 }
357 357
358 /* default pts settings is MPEG like */
359 av_set_pts_info(ic, 33, 1, 90000);
360 ic->last_pkt_pts = AV_NOPTS_VALUE;
361 ic->last_pkt_dts = AV_NOPTS_VALUE;
362 ic->last_pkt_stream_pts = AV_NOPTS_VALUE;
363 ic->last_pkt_stream_dts = AV_NOPTS_VALUE;
364
365 err = ic->iformat->read_header(ic, ap); 358 err = ic->iformat->read_header(ic, ap);
366 if (err < 0) 359 if (err < 0)
367 goto fail; 360 goto fail;
368 361
369 if (pb) 362 if (pb)
497 490
498 /* convert the packet time stamp units and handle wrapping. The 491 /* convert the packet time stamp units and handle wrapping. The
499 wrapping is handled by considering the next PTS/DTS as a delta to 492 wrapping is handled by considering the next PTS/DTS as a delta to
500 the previous value. We handle the delta as a fraction to avoid any 493 the previous value. We handle the delta as a fraction to avoid any
501 rounding errors. */ 494 rounding errors. */
502 static inline int64_t convert_timestamp_units(AVFormatContext *s, 495 static inline int64_t convert_timestamp_units(AVStream *s,
503 int64_t *plast_pkt_pts, 496 int64_t *plast_pkt_pts,
504 int *plast_pkt_pts_frac, 497 int *plast_pkt_pts_frac,
505 int64_t *plast_pkt_stream_pts, 498 int64_t *plast_pkt_stream_pts,
506 int64_t pts) 499 int64_t pts)
507 { 500 {
513 stream_pts = pts; 506 stream_pts = pts;
514 if (*plast_pkt_stream_pts != AV_NOPTS_VALUE) { 507 if (*plast_pkt_stream_pts != AV_NOPTS_VALUE) {
515 shift = 64 - s->pts_wrap_bits; 508 shift = 64 - s->pts_wrap_bits;
516 delta_pts = ((stream_pts - *plast_pkt_stream_pts) << shift) >> shift; 509 delta_pts = ((stream_pts - *plast_pkt_stream_pts) << shift) >> shift;
517 /* XXX: overflow possible but very unlikely as it is a delta */ 510 /* XXX: overflow possible but very unlikely as it is a delta */
518 delta_pts = delta_pts * AV_TIME_BASE * s->pts_num; 511 delta_pts = delta_pts * AV_TIME_BASE * s->time_base.num;
519 pts = *plast_pkt_pts + (delta_pts / s->pts_den); 512 pts = *plast_pkt_pts + (delta_pts / s->time_base.den);
520 pts_frac = *plast_pkt_pts_frac + (delta_pts % s->pts_den); 513 pts_frac = *plast_pkt_pts_frac + (delta_pts % s->time_base.den);
521 if (pts_frac >= s->pts_den) { 514 if (pts_frac >= s->time_base.den) {
522 pts_frac -= s->pts_den; 515 pts_frac -= s->time_base.den;
523 pts++; 516 pts++;
524 } 517 }
525 } else { 518 } else {
526 /* no previous pts, so no wrapping possible */ 519 /* no previous pts, so no wrapping possible */
527 pts = (int64_t)(((double)stream_pts * AV_TIME_BASE * s->pts_num) / 520 // pts = av_rescale(stream_pts, (int64_t)AV_TIME_BASE * s->time_base.num, s->time_base.den);
528 (double)s->pts_den); 521 pts = (int64_t)(((double)stream_pts * AV_TIME_BASE * s->time_base.num) /
522 (double)s->time_base.den);
529 pts_frac = 0; 523 pts_frac = 0;
530 } 524 }
531 *plast_pkt_stream_pts = stream_pts; 525 *plast_pkt_stream_pts = stream_pts;
532 *plast_pkt_pts = pts; 526 *plast_pkt_pts = pts;
533 *plast_pkt_pts_frac = pts_frac; 527 *plast_pkt_pts_frac = pts_frac;
750 } 744 }
751 } 745 }
752 /* no more packets: really terminates parsing */ 746 /* no more packets: really terminates parsing */
753 return ret; 747 return ret;
754 } 748 }
749
750 st = s->streams[s->cur_pkt.stream_index];
755 751
756 /* convert the packet time stamp units and handle wrapping */ 752 /* convert the packet time stamp units and handle wrapping */
757 s->cur_pkt.pts = convert_timestamp_units(s, 753 s->cur_pkt.pts = convert_timestamp_units(st,
758 &s->last_pkt_pts, &s->last_pkt_pts_frac, 754 &st->last_pkt_pts, &st->last_pkt_pts_frac,
759 &s->last_pkt_stream_pts, 755 &st->last_pkt_stream_pts,
760 s->cur_pkt.pts); 756 s->cur_pkt.pts);
761 s->cur_pkt.dts = convert_timestamp_units(s, 757 s->cur_pkt.dts = convert_timestamp_units(st,
762 &s->last_pkt_dts, &s->last_pkt_dts_frac, 758 &st->last_pkt_dts, &st->last_pkt_dts_frac,
763 &s->last_pkt_stream_dts, 759 &st->last_pkt_stream_dts,
764 s->cur_pkt.dts); 760 s->cur_pkt.dts);
765 #if 0 761 #if 0
766 if (s->cur_pkt.stream_index == 0) { 762 if (s->cur_pkt.stream_index == 0) {
767 if (s->cur_pkt.pts != AV_NOPTS_VALUE) 763 if (s->cur_pkt.pts != AV_NOPTS_VALUE)
768 printf("PACKET pts=%0.3f\n", 764 printf("PACKET pts=%0.3f\n",
770 if (s->cur_pkt.dts != AV_NOPTS_VALUE) 766 if (s->cur_pkt.dts != AV_NOPTS_VALUE)
771 printf("PACKET dts=%0.3f\n", 767 printf("PACKET dts=%0.3f\n",
772 (double)s->cur_pkt.dts / AV_TIME_BASE); 768 (double)s->cur_pkt.dts / AV_TIME_BASE);
773 } 769 }
774 #endif 770 #endif
775 771
776 /* duration field */ 772 /* duration field */
777 if (s->cur_pkt.duration != 0) { 773 s->cur_pkt.duration = av_rescale(s->cur_pkt.duration, AV_TIME_BASE * (int64_t)st->time_base.num, st->time_base.den);
778 s->cur_pkt.duration = ((int64_t)s->cur_pkt.duration * AV_TIME_BASE * s->pts_num) / 774
779 s->pts_den;
780 }
781
782 st = s->streams[s->cur_pkt.stream_index];
783 s->cur_st = st; 775 s->cur_st = st;
784 s->cur_ptr = s->cur_pkt.data; 776 s->cur_ptr = s->cur_pkt.data;
785 s->cur_len = s->cur_pkt.size; 777 s->cur_len = s->cur_pkt.size;
786 if (st->need_parsing && !st->parser) { 778 if (st->need_parsing && !st->parser) {
787 st->parser = av_parser_init(st->codec.codec_id); 779 st->parser = av_parser_init(st->codec.codec_id);
1353 break; 1345 break;
1354 read_size += pkt->size; 1346 read_size += pkt->size;
1355 st = ic->streams[pkt->stream_index]; 1347 st = ic->streams[pkt->stream_index];
1356 if (pkt->pts != AV_NOPTS_VALUE) { 1348 if (pkt->pts != AV_NOPTS_VALUE) {
1357 if (st->start_time == AV_NOPTS_VALUE) 1349 if (st->start_time == AV_NOPTS_VALUE)
1358 st->start_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den); 1350 st->start_time = av_rescale(pkt->pts, st->time_base.num * (int64_t)AV_TIME_BASE, st->time_base.den);
1359 } 1351 }
1360 av_free_packet(pkt); 1352 av_free_packet(pkt);
1361 } 1353 }
1362 1354
1363 /* we compute the minimum start_time and use it as default */ 1355 /* we compute the minimum start_time and use it as default */
1396 if (ret != 0) 1388 if (ret != 0)
1397 break; 1389 break;
1398 read_size += pkt->size; 1390 read_size += pkt->size;
1399 st = ic->streams[pkt->stream_index]; 1391 st = ic->streams[pkt->stream_index];
1400 if (pkt->pts != AV_NOPTS_VALUE) { 1392 if (pkt->pts != AV_NOPTS_VALUE) {
1401 end_time = (int64_t)((double)pkt->pts * ic->pts_num * (double)AV_TIME_BASE / ic->pts_den); 1393 end_time = av_rescale(pkt->pts, st->time_base.num * (int64_t)AV_TIME_BASE, st->time_base.den);
1402 duration = end_time - st->start_time; 1394 duration = end_time - st->start_time;
1403 if (duration > 0) { 1395 if (duration > 0) {
1404 if (st->duration == AV_NOPTS_VALUE || 1396 if (st->duration == AV_NOPTS_VALUE ||
1405 st->duration < duration) 1397 st->duration < duration)
1406 st->duration = duration; 1398 st->duration = duration;
1774 } 1766 }
1775 st->index = s->nb_streams; 1767 st->index = s->nb_streams;
1776 st->id = id; 1768 st->id = id;
1777 st->start_time = AV_NOPTS_VALUE; 1769 st->start_time = AV_NOPTS_VALUE;
1778 st->duration = AV_NOPTS_VALUE; 1770 st->duration = AV_NOPTS_VALUE;
1771
1772 /* default pts settings is MPEG like */
1773 av_set_pts_info(st, 33, 1, 90000);
1774 st->last_pkt_pts = AV_NOPTS_VALUE;
1775 st->last_pkt_dts = AV_NOPTS_VALUE;
1776 st->last_pkt_stream_pts = AV_NOPTS_VALUE;
1777 st->last_pkt_stream_dts = AV_NOPTS_VALUE;
1778
1779 s->streams[s->nb_streams++] = st; 1779 s->streams[s->nb_streams++] = st;
1780 return st; 1780 return st;
1781 } 1781 }
1782 1782
1783 /************************************************************/ 1783 /************************************************************/
1812 int av_write_header(AVFormatContext *s) 1812 int av_write_header(AVFormatContext *s)
1813 { 1813 {
1814 int ret, i; 1814 int ret, i;
1815 AVStream *st; 1815 AVStream *st;
1816 1816
1817 /* default pts settings is MPEG like */
1818 av_set_pts_info(s, 33, 1, 90000);
1819 ret = s->oformat->write_header(s); 1817 ret = s->oformat->write_header(s);
1820 if (ret < 0) 1818 if (ret < 0)
1821 return ret; 1819 return ret;
1822 1820
1823 /* init PTS generation */ 1821 /* init PTS generation */
1825 st = s->streams[i]; 1823 st = s->streams[i];
1826 1824
1827 switch (st->codec.codec_type) { 1825 switch (st->codec.codec_type) {
1828 case CODEC_TYPE_AUDIO: 1826 case CODEC_TYPE_AUDIO:
1829 av_frac_init(&st->pts, 0, 0, 1827 av_frac_init(&st->pts, 0, 0,
1830 (int64_t)s->pts_num * st->codec.sample_rate); 1828 (int64_t)st->time_base.num * st->codec.sample_rate);
1831 break; 1829 break;
1832 case CODEC_TYPE_VIDEO: 1830 case CODEC_TYPE_VIDEO:
1833 av_frac_init(&st->pts, 0, 0, 1831 av_frac_init(&st->pts, 0, 0,
1834 (int64_t)s->pts_num * st->codec.frame_rate); 1832 (int64_t)st->time_base.num * st->codec.frame_rate);
1835 break; 1833 break;
1836 default: 1834 default:
1837 break; 1835 break;
1838 } 1836 }
1839 } 1837 }
1856 AVStream *st; 1854 AVStream *st;
1857 int64_t pts_mask; 1855 int64_t pts_mask;
1858 int ret, frame_size; 1856 int ret, frame_size;
1859 1857
1860 st = s->streams[stream_index]; 1858 st = s->streams[stream_index];
1861 pts_mask = (1LL << s->pts_wrap_bits) - 1; 1859 pts_mask = (1LL << st->pts_wrap_bits) - 1;
1862 1860
1863 /* HACK/FIXME we skip all zero size audio packets so a encoder can pass pts by outputing zero size packets */ 1861 /* HACK/FIXME we skip all zero size audio packets so a encoder can pass pts by outputing zero size packets */
1864 if(st->codec.codec_type==CODEC_TYPE_AUDIO && size==0) 1862 if(st->codec.codec_type==CODEC_TYPE_AUDIO && size==0)
1865 ret = 0; 1863 ret = 0;
1866 else 1864 else
1876 frame_size = get_audio_frame_size(&st->codec, size); 1874 frame_size = get_audio_frame_size(&st->codec, size);
1877 1875
1878 /* HACK/FIXME, we skip the initial 0-size packets as they are most likely equal to the encoder delay, 1876 /* HACK/FIXME, we skip the initial 0-size packets as they are most likely equal to the encoder delay,
1879 but it would be better if we had the real timestamps from the encoder */ 1877 but it would be better if we had the real timestamps from the encoder */
1880 if (frame_size >= 0 && (size || st->pts.num!=st->pts.den>>1 || st->pts.val)) { 1878 if (frame_size >= 0 && (size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
1881 av_frac_add(&st->pts, 1879 av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
1882 (int64_t)s->pts_den * frame_size);
1883 } 1880 }
1884 break; 1881 break;
1885 case CODEC_TYPE_VIDEO: 1882 case CODEC_TYPE_VIDEO:
1886 av_frac_add(&st->pts, 1883 av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec.frame_rate_base);
1887 (int64_t)s->pts_den * st->codec.frame_rate_base);
1888 break; 1884 break;
1889 default: 1885 default:
1890 break; 1886 break;
1891 } 1887 }
1892 return ret; 1888 return ret;
2373 * @param pts_wrap_bits number of bits effectively used by the pts 2369 * @param pts_wrap_bits number of bits effectively used by the pts
2374 * (used for wrap control, 33 is the value for MPEG) 2370 * (used for wrap control, 33 is the value for MPEG)
2375 * @param pts_num numerator to convert to seconds (MPEG: 1) 2371 * @param pts_num numerator to convert to seconds (MPEG: 1)
2376 * @param pts_den denominator to convert to seconds (MPEG: 90000) 2372 * @param pts_den denominator to convert to seconds (MPEG: 90000)
2377 */ 2373 */
2378 void av_set_pts_info(AVFormatContext *s, int pts_wrap_bits, 2374 void av_set_pts_info(AVStream *s, int pts_wrap_bits,
2379 int pts_num, int pts_den) 2375 int pts_num, int pts_den)
2380 { 2376 {
2381 s->pts_wrap_bits = pts_wrap_bits; 2377 s->pts_wrap_bits = pts_wrap_bits;
2382 s->pts_num = pts_num; 2378 s->time_base.num = pts_num;
2383 s->pts_den = pts_den; 2379 s->time_base.den = pts_den;
2384 } 2380 }
2385 2381
2386 /* fraction handling */ 2382 /* fraction handling */
2387 2383
2388 /** 2384 /**