c# - Rendering video to file that may have an inconsistent frame rate -


i'm getting raw video frames source (that can considered black box) @ rate can inconsistent. i'm trying record video feed disk. i'm doing aforge's videorecorder , writing mp4 file.

however, inconsistent rate @ receive frames causes video appear sped up. seems have ability create video files have fixed frame rate, though source not have fixed frame rate.

this isn't issue when rendering screen, can render fast possible. can't when writing file, since playing file play @ fixed frame rate.

what solutions there? output not have same video format long there's reasonable way convert later (which wouldn't have real time). video feeds can quite long, can't store in memory , encode later.

my code looks along lines of:

videofilewriter writer = new videofilewriter(); stopwatch stopwatch = new stopwatch();  public override void start() {     writer.open("output.mp4", videowidth, videoheight, framerate, aforge.video.ffmpeg.videocodec.mpeg4);     stopwatch.start(); }  public override void end() {     writer.close(); }  public override void draw(frame frame) {     double elapsedtimeinseconds = stopwatch.elapsedticks / (double) stopwatch.frequency;     double timebetweenframesinseconds = 1.0 / framerate;     if (elapsedtimeinseconds >= timebetweenframesinseconds) {         stopwatch.restart();         writer.writevideoframe(frame.tobitmap());     } } 

where our black box calls start, end, , draw methods. current check have in draw prevents drawing fast, doesn't handle case of drawing slowly.

it turns out writevideoframe overloaded , 1 variant of function writevideoframe(bitmap frame, timespan timestamp). can guess, time stamp used make frame appear @ time in video.

thus, keeping track of real time, can set each frame use time should in video. of course, video quality worse if can't render enough, resolves issue @ hand.

here's code used draw function:

// can provide frame offset each frame has time it's supposed // seen at. ensures video looks correct if render rate lower // frame rate, since these times used (it'll choppy, @ least it'll // paced correctly -- necessary sound won't go out of sync). long currenttick = datetime.now.ticks; starttick = starttick ?? currenttick; var frameoffset = new timespan(currenttick - starttick.value);  // figure out if need render frame file (ie, has enough time passed // frame in file?). prevents going on // desired frame rate , improves performance (assuming can go on frame // rate). double elapsedtimeinseconds = stopwatch.elapsedticks / (double) stopwatch.frequency; double timebetweenframesinseconds = 1.0 / framerate; if (elapsedtimeinseconds >= timebetweenframesinseconds) {     stopwatch.restart();      writer.writevideoframe(frame.tobitmap(), frameoffset); } 

where starttick long? member of object.


Comments

Popular posts from this blog

apache - PHP Soap issue while content length is larger -

asynchronous - Python asyncio task got bad yield -

javascript - Complete OpenIDConnect auth when requesting via Ajax -