我只是想在缓冲区中保存相同的视频帧,我正确地保存了帧的位图帧和时间戳。
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 studio上(不在第一帧),我收到了这个错误: Accord.Video.VideoException:'写视频帧时出错。错误-22:参数无效。有关详细信息,请参阅控制台输出。'
在控制台上: 应用程序在流0中提供了无效的,非单调增加的dts到muxer:512> = 512
我不知道原因,因为在调试时所有值似乎都是正确的。 (如果您需要更多代码,请告诉我)
答案 0 :(得分:0)
好的,我会放在这里。
VideoStream->time_base: 1/15360
来自的第一件事,30fps为1000/30000,29.97 fps为1001/30000。
你的pts / dts和帧持续时间计算的第二个问题。如您所见,最后两个pts / 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 */
}
这些绝对适用于从RAW源手动编码,就像你的。当然不是为了转码。
希望有所帮助。