流中非单调增加dts的多路复用器 [英] Non monotonically increasing dts to muxer in stream
问题描述
我只是想在缓冲区中的视频上保存相同的帧,在这里我正确地保存了该帧的位图帧和时间戳.
I'm just trying to save same frames on video from a buffer, where I properly saved the Bitmap Frame, and the Time Stamp, of the frame.
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:参数无效.有关更多详细信息,请参见控制台输出.'
But on visual studio (not on the first frame) I'm getting this error: Accord.Video.VideoException: 'Error while writing video frame. Error -22: Invalid argument. See console output for more details.'
在控制台上: 应用程序向流0中的复用器提供了无效且非单调递增的dts:512> = 512
我不知道原因,因为在调试时所有值似乎都是正确的. (请让我知道是否需要更多代码)
I don't know the reason for that because on debug all values seems right. (Please let me know if you need more code)
推荐答案
好的,我把它放在这里.
VideoStream->time_base: 1/15360
的第一件事,对于30fps应为1000/30000,对于29.97 fps应为1001/30000.
Ok, I'll put here.
1st thing where does VideoStream->time_base: 1/15360
comes from, this should be 1000/30000 for 30fps or 1001/30000 for 29.97 fps.
第二点您的pts/dts和帧持续时间计算有问题.如您所见,最后两个pts/dts值相同.
2nd something wrong with your pts/dts and frame duration calculation. As you see last two pts/dts values are same.
对于数据包持续时间(我假设fps像往常一样是恒定的),请使用以下预先计算的值(或与您的参考值进行比较):
For packet duration (I'm assuming fps is constant as normally should) use these pre-calculated values (or check with yours as reference):
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 ++函数:
As for manually calculating pts/dts: this is my C++ function that I use:
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来源手动编码时,这些绝对有效.当然不是为了转码.
These definitely works when manually encode from RAW source, like yours. Not for transcoding of course.
希望有帮助.
这篇关于流中非单调增加dts的多路复用器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!