0
我有一個motion-jpeg解碼器,我爲查看ip-camera流而編寫。它工作的很好,我可以輕鬆實現超過30 fps與多個設備。我的問題是這些幀可能通過網絡爆發。平滑可變幀率(視頻)
我想實現的是一個公式,用於平均幀之間的時間以獲得更穩定的回放。目前,我的幀被放入網絡線程的ConcurrentQueue中,並且最近的幀被顯示在UI線程中。下面是我的電流平滑的視頻流編碼,但我的計劃是不工作...
PlaybackFrame)類持有的BitmapImage - > 「圖片」
base.getFrame() )從ConcurrentQueue
private const int MAX_FRAME_DELAY = 500;
private const float RATE_FACTOR = 0.1f;
private long last_frame_time;
private long last_update_time;
private float rate;
//=============================
public override bool Get(out BitmapImage image) {
PlaybackFrame f = null;
if (base.getFrame(out f)) {
long now = Environment.TickCount;
if (last_frame_time > 0) {
// Get # of frames in buffer
int count = getCount();
//
// Get duration since last update & last frame displayed
int update_duration = (int)(now - last_update_time);
int frame_duration = (int)(now - last_frame_time);
//
// estimated delay based on current frame-rate
float target_rate = 0;
if (count > 0) target_rate = update_duration/(float)count;
//
// offset actual delay/rate by current value
last_update_time = now;
rate = lerp(rate, target_rate, RATE_FACTOR);
//
// [backup] if duration exceeds 0.5 seconds, display next frame
if (frame_duration >= MAX_FRAME_DELAY) {
image = f.Image;
last_frame_time = now;
return true;
}
//
// if duration exceeds delay, display image
if (frame_duration > rate) {
image = f.Image;
last_frame_time = now;
return true;
} else {
// too soon, wait...
image = null;
return false;
}
} else {
// first image, display
last_frame_time = now;
image = f.Image;
return true;
}
} else {
// no image available
image = null;
return false;
}
}
private float lerp(float a, float b, float f) {
return a*(1f - f) + b*f;
}
爲什麼不使用緩衝區? – SimpleVar
你能更具體嗎? ConcurrentQueue充當緩衝區,保存傳入圖像的列表。我正在尋找一種方法來延遲這些圖像的顯示,基於傳入的幀速率。 – Null511
每當緩衝區少於X個下一幀時暫停視頻。 – SimpleVar