问题
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));
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.'
And on console: Application provided invalid, non monotonically increasing dts to muxer in stream 0: 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)
回答1:
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.
2nd something wrong with your pts/dts and frame duration calculation. As you see last two pts/dts values are same.
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
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 */
}
These definitely works when manually encode from RAW source, like yours. Not for transcoding of course.
Hope that helps.
来源:https://stackoverflow.com/questions/49136872/non-monotonically-increasing-dts-to-muxer-in-stream