我只是试着从一个缓冲区中保存相同的帧,在那里我正确地保存了位图帧,以及帧的时间戳。
writer1 = new VideoFileWriter();
this.writer1.Width = this.videoSourceEndo.VideoResolution.FrameSize.Width;
this.writer1.Height = this.videoSourceEndo.VideoResolution.FrameSize.Height;
this.writer1.VideoCodec = VideoCodec.H264;
this.writer1.BitRate = (this.videoSourceEndo.VideoResolution.FrameSize.Height * this.videoSourceEndo.VideoResolution.FrameSize.Width * 30);
this.writer1.VideoOptions["preset"] = "superfast";
this.writer1.VideoOptions["tune"] = "zerolatency";
writer1.Open("test_HDMI.mp4");(...)
writer1.WriteVideoFrame(endoFrameBuffer[endoFrameBuffer.Tail],endoFrameBuffer.getframetime(endoFrameBuffer.Tail));但是在visual (不是第一帧)上,我得到了这个错误: Accord.Video.VideoException:“编写视频帧时出错。Error -22:无效参数。有关更多细节,请参阅控制台输出。”
在控制台上:在流0: 512 >= 512中,应用程序提供了无效的、非单调增加的dts到muxer。
我不知道原因,因为在调试时,所有的值似乎都是正确的。(如果您需要更多代码,请告诉我)
发布于 2018-03-08 13:28:30
好吧,我把它放这儿。第一件事,从哪里来的VideoStream->time_base: 1/15360,这应该是1000/30000的30 fps或1001/30000的29.97 fps。
第二,你的pts/dts和帧持续时间计算有问题。正如您所看到的,最后两个pt/dts值是相同的。
对于数据包持续时间(我假设fps是常量的,通常应该如此),请使用这些预先计算过的值(或与您的值检查作为参考):
fps duration (same unit as AVPacket::duration)
23.98 2086
24.00 2000
25.00 2000
29.97 2068
30.00 2000
50.00 1000
59.94 1016
60.00 1000至于手动计算pts/dts:这是我使用的C++函数:
static void write_video_pts(EncoderContext *ectx, AVPacket *pkt)
{
pkt->pts = ectx->video_pts; /* this is to keep next pts value, same unit as AVPacket::pts */
ectx->video_pts += ectx->frame_duration; /* check above table for ectx->frame_duration value */
pkt->dts = pkt->pts;
pkt->duration = ectx->frame_duration; /* check above table for ectx->frame_duration value */
pkt->stream_index = ectx->VideoStream->index; /* AVStream */
}当手动从原始源(如您的源)编码时,这些绝对有效。当然不是用来转码的。
希望这能有所帮助。
https://stackoverflow.com/questions/49136872
复制相似问题