了解视频帧中的PTS和DTS [英] Understanding PTS and DTS in video frames

查看:631
本文介绍了了解视频帧中的PTS和DTS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当从avi转换为mp4(x264)时,我有fps问题。最终问题是PTS和DTS值,所以在av_interleaved_write_frame函数之前添加的第12-15行:

I had fps issues when transcoding from avi to mp4(x264). Eventually the problem was in PTS and DTS values, so lines 12-15 where added before av_interleaved_write_frame function:

1.  AVFormatContext* outContainer = NULL;
2.  avformat_alloc_output_context2(&outContainer, NULL, "mp4", "c:\\test.mp4";
3.  AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
4.  AVStream *outStream = avformat_new_stream(outContainer, encoder);
5.  // outStream->codec initiation
6.  // ...
7.  avformat_write_header(outContainer, NULL);

8.  // reading and decoding packet
9.  // ...
10. avcodec_encode_video2(outStream->codec, &encodedPacket, decodedFrame, &got_frame)
11. 
12. if (encodedPacket.pts != AV_NOPTS_VALUE)
13.     encodedPacket.pts =  av_rescale_q(encodedPacket.pts, outStream->codec->time_base, outStream->time_base);
14. if (encodedPacket.dts != AV_NOPTS_VALUE)
15.     encodedPacket.dts = av_rescale_q(encodedPacket.dts, outStream->codec->time_base, outStream->time_base);
16. 
17. av_interleaved_write_frame(outContainer, &encodedPacket)



< r>发现许多帖子我还是不明白:

After reading many posts I still do not understand:


  1. outStream-> codec-> time_base = 1/25和 outStream-> time_base = 1/12800。第一个是我设置的,但是我不知道为什么和谁设置了12800?我注意到,在第(7)行之前 outStream-> time_base = 1/90000之后,它变为1/12800,为什么?
    当我从avi转码为avi时,意味着将行(2)更改为 avformat_alloc_output_context2(& outContainer,NULL,avi,c:\\test.avi; ,所以前后行(7) outStream-> time_base 始终是1/25,不像mp4的情况,为什么? li>
  2. outStream-> codec outStream 之间的time_base有什么区别?

  3. 计算pts av_rescale_q 确实:需要2个time_base,将它们的分数乘以十进制,然后计算pts,为什么这样做这样?调试时,$ code encodedPacket.pts 的值增量为1,那么为什么要更改它的值呢?

  4. 在开始时,dts值为-2,每次重新调整后仍然为负数,但是尽管视频播放正确!不应该是正面的吗?

  1. outStream->codec->time_base = 1/25 and outStream->time_base = 1/12800. The 1st one was set by me but I cannot figure out why and who set 12800? I noticed that before line (7) outStream->time_base = 1/90000 and right after it it changes to 1/12800, why? When I transcode from avi to avi, meaning changing the line (2) to avformat_alloc_output_context2(&outContainer, NULL, "avi", "c:\\test.avi"; , so before and after line (7) outStream->time_base remains always 1/25 and not like in mp4 case, why?
  2. What is the difference between time_base of outStream->codec and outStream?
  3. To calc the pts av_rescale_q does: takes 2 time_base, multiplies their fractions in cross and then compute the pts. Why it does this in this way? As I debugged, the encodedPacket.pts has value incremental by 1, so why changing it if it does has value?
  4. At the beginning the dts value is -2 and after each rescaling it still has negative number, but despite this the video played correctly! Shouldn't it be positive?


推荐答案


  1. time_base只是一个单位o f测量可以使用不同的单位来表示相同的时间(大约,如果它们不是精确的倍数)。在某些情况下,容器格式需要一定的时间基准,并且将由muxer设置。在其他情况下,容器不需要时基,但它具有您可能需要覆盖的默认值。我不确定1/12800具体,我知道1/600是mp4规格中的一个特殊值。

  1. The time_base is just a unit of measurement. Different units may be used to represent the same times (approximately, if they are not exact multiples). In some cases a container format requires a certain time base and it will be set to that by the muxer. In other cases the container doesn't require a time base but it has a default that you might have to override. I'm not sure about 1/12800 specifically, I know 1/600 is a special value in mp4 spec.

这两个时基是测量编解码器和容器的时间。如果使用常数fps,则编解码器测量单位通常设置为每帧和下一帧之间的间隔(每帧显示的持续时间),以便帧时间是连续的整数。不必将其设置为1 / fps,只要使用的单位是正确的。

The two time bases are the units of measurement of time for the codec and for the container. If using constant fps, the codec unit of measurement is commonly set to the interval between each frame and the next (the duration that each frame gets displayed), so that frame times are successive integers. It doesn't have to be set to 1/fps, however, as long as the pts times are correct in whatever units are used.

你所描述的内容只是将一个单位转换为另一个单位必须做的事情。 (即:乘以旧单位,除以新的)。以 a / b 为单位的时间t可以转换为 c / d t *(a * d)/(b * c)

What you describe is simply what one would have to do to convert from one unit to another. (ie: multiply by old unit, divide by new). A time t in units of a/b can be converted to units c/d as t*(a*d)/(b*c).

dts序列可以从任何值开始,对于dts 0没有特别的意义。在播放开始时,计算挂钟时间和起始dts之间的差异,并且使用它们将所有将来的dts转换成挂钟。 dts = -10,-9,-8,...的视频流完全可以。连续dts之间的区别是使用的,绝对值无关紧要。

The dts sequence can start from any value, there is no special significance to dts 0. At start of playback, the difference between wall clock time and the starting dts is computed, and all future dts are converted to wall clock using that. A video stream with dts=-10, -9, -8, ... is perfectly ok. The difference between successive dts is what is used, the absolute values don't matter.

这篇关于了解视频帧中的PTS和DTS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆