对视频文件和媒体流中PTS的困惑

Confusion about PTS in video files and media streams

本文关键字:PTS 视频 文件 媒体      更新时间:2023-10-16

文件中特定帧的PTS是否可能与流式传输时同一文件中同一帧的PTSs不同?

当我使用av_read_frame读取帧时,我将视频流存储在AVStream中。在我使用avcodec_decode_video2解码帧之后,我使用av_frame_get_best_effort_timestamp将该帧的时间戳存储在int64_t中。现在,如果程序是从一个文件中获取输入的,那么当我将输入(从同一个文件)流式传输到程序时,我会得到一个不同的时间戳。

要更改输入类型,我只需将argv参数从"/path/To/file.mp4"更改为类似"udp://localhost:1234",然后我在命令行中用ffmpeg流式传输文件:"ffmpeg-re-I/path/to/file.mp4-f mpegtsudp://localhost:1234".这可能是因为"-f mpegts"参数改变了媒体的某些特性吗?

下面是我的代码(简化)。通过阅读ffmpeg邮件列表档案,我意识到我要查找的time_base在AVStream中,而不是在AVCodecContext中。我也尝试过使用packet.pts,而不是使用av_frame_get_best_effort_timestamp,但结果没有改变。我需要时间戳来了解正在接收的流媒体视频中的帧数。我真的很感激任何形式的帮助。

//..
//argv[1]="/file.mp4";
argv[1]="udp://localhost:7777";
// define AVFormatContext, AVFrame, etc.
// register av, avcodec, avformat_network_init(), etc.
avformat_open_input(&pFormatCtx, argv, NULL, NULL);
avformat_find_stream_info(pFormatCtx, NULL);
// find the video stream...
// pointer to the codec context...
// open codec...
pFrame=av_frame_alloc();
while(av_read_frame(pFormatCtx, &packet)>=0) {
        AVStream *strem = pFormatCtx->streams[videoStream];
        if(packet.stream_index==videoStream) {
            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
            if(frameFinished) {
                int64_t perts = av_frame_get_best_effort_timestamp(pFrame);
                if (isMyFrame(pFrame)){
                     cout << perts*av_q2d(strem->time_base) << "n";
                }
             }
}
//free allocated space
}
//..

时间戳存储在容器级别,因此更改容器可以更改时间戳。此外,TS存储每个帧的时间戳(基于90kHz时钟)。MP4仅存储假定开始时间为0的帧持续时间(由于第一PTS为零,并且第一DTS<0,所以这对于bframe来说变得更加复杂)。因此,为了获得时间戳,添加了所有帧持续时间。Mp4还允许设置时钟速率。29.97FPS的帧速率通常为每秒1001/3000次,但它可以设置为任何值。因此,av_framegetbest_efft_timestamp以编解码器->流基础单元的形式返回tick。对于TS编解码器->stream_base始终为1/90000