gpt4 book ai didi

c++ - 使用 ffmpeg 库向 HEVC 添加时间戳,使用 Gstreamer 管道运行时时间戳不匹配

转载 作者:行者123 更新时间:2023-12-04 22:47:44 26 4
gpt4 key购买 nike

我们正在使用 NvEncoder 和 HEVC 对样本帧进行编码。由于 HEVC 帧没有任何时间戳,为了对视频执行搜索操作,我们用 C++ 编写了一个 remuxer,它以有序的方式为帧创建时间戳,并将编码的帧写入视频容器 (mp4,mov)。使用 ffplay 播放时,mp4 容器中的输出视频看起来很好,使用 ffprobe 检查时时间戳似乎正确。但是,当我们尝试在 Gstreamer 管道中播放视频时,第 2 帧和第 3 帧似乎具有完全相同的时间戳。所以当视频播放时,第 3 帧被跳过,第 2 帧显示两次。我们不能容忍任何帧丢失,所以我们需要解决这个问题,我们认为这是由于 ffmpeg 和 gstreamer 在帧时间戳方面不兼容。如果有帮助,我还可以提供我们的 remuxer 和示例输出的源代码。
我使用以下 Gstreamer 管道播放 mp4:

gst-launch-1.0 filesrc location=5_fps.mp4 ! qtdemux name=demux demux.video_0 ! queue! decodebin ! videoconvert ! videoscale ! autovideosink 
以下命令还给出了相同的不匹配帧时间戳:
ffmpeg -i 5_fps.bin -vcodec copy -acodec copy 5_fps.mp4
非常感谢!
编辑:我正在添加 remuxer 的一部分,其中读取输入流中的每一帧并添加时间戳。
int frame_no=-1; //starting with -1 gives the same ffprobe results as command line ffmpeg container conversion, starting with 0 again causes the same timestamp problem    
while (1) {
AVStream *in_stream, *out_stream;

_status = av_read_frame(_ifmt_ctx, &_pkt);
if (_status < 0) break;

in_stream = _ifmt_ctx->streams[_pkt.stream_index];
if (_pkt.stream_index >= _stream_mapping_size ||
_stream_mapping[_pkt.stream_index] < 0) {
av_packet_unref(&_pkt);
continue;
}
double inputFPS=av_q2d(in_stream->r_frame_rate);

double outputFPS=av_q2d(in_stream->r_frame_rate);

_pkt.stream_index = _stream_mapping[_pkt.stream_index];
out_stream = _ofmt_ctx->streams[_pkt.stream_index];
_pkt.pts=frame_no*in_stream->time_base.den/inputFPS;
_pkt.dts=_pkt.pts;
_pkt.duration = in_stream->time_base.den/inputFPS;
_pkt.pos = -1;
std::cout<<"rescaled pts: "<<_pkt.pts<<" dts: "<<_pkt.dts<<" frame no: "<< frame_no<<std::endl;

std::cout<<"input time_base den: "<<in_stream->time_base.den<<" output time_base den: "<<out_stream->time_base.den<<std::endl;

frame_no++;
_status = av_interleaved_write_frame(_ofmt_ctx, &_pkt);
if (_status < 0) {
cout<<"Error muxing packet\n";
break;
}
av_packet_unref(&_pkt);}
我首先尝试了这种方法,其中每个帧时间戳(pts 和 dts)按数据包持续时间递增。起初我认为这种方法行不通,因为 B 帧的解码顺序不同,所以我首先尝试了没有 B 帧的视频。但是,当我尝试使用带有 b 帧的视频时,它再次起作用了。我认为解码帧的顺序会有所不同,但事实并非如此。唯一的问题是,在 Gstream 中(不是在 Ffmpeg 中),只有第二帧和第三帧似乎具有相同的时间戳,除了这两帧之外,剩余的视频播放得很好。总的来说,我也很困惑 b 帧不会导致任何帧顺序问题。
示例 encoded input , 示例 output video如果你想检查框架。 (我不知道是否可以通过 google drive 共享文件,如果有更好的共享方式,请纠正我。)

最佳答案

正如@AlanBirtles 提到的,以我幼稚的方式分配 b 帧的时间戳根本不正确。我假设由于视频是可播放的,Ffmpeg 或 Gstreamer 以某种方式更正了时间戳,我并没有将我的主要问题与此联系起来。但是,当我尝试转换没有 b 帧的视频容器时,第 3 帧丢失的问题得到了解决。所以我知道要么正确设置 b 帧的时间戳,要么我应该使用没有 b 帧的视频。尽管这不是可行的解决方案,但暂时我们不会使用 b 帧,但是将来我会尝试重新实现 remuxer,以便任何视频都可以重新混合。

关于c++ - 使用 ffmpeg 库向 HEVC 添加时间戳,使用 Gstreamer 管道运行时时间戳不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70609415/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com