mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-18 08:07:56 +01:00
Write to file on a dedicated thread in VideoFileRenderer.
The disk cannot always keep up to with the frames produced. To solve this, write to disk on a dedicated thread so we don't block rendering. Bug: b/80409365 Change-Id: If9ef3eb6948d81deebb987420599fef446b082d6 Reviewed-on: https://webrtc-review.googlesource.com/79800 Reviewed-by: Paulina Hensman <phensman@webrtc.org> Commit-Queue: Sami Kalliomäki <sakal@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23483}
This commit is contained in:
parent
d45b345700
commit
aa35aeaa66
1 changed files with 37 additions and 20 deletions
|
@ -29,6 +29,8 @@ public class VideoFileRenderer implements VideoSink {
|
||||||
|
|
||||||
private final HandlerThread renderThread;
|
private final HandlerThread renderThread;
|
||||||
private final Handler renderThreadHandler;
|
private final Handler renderThreadHandler;
|
||||||
|
private final HandlerThread fileThread;
|
||||||
|
private final Handler fileThreadHandler;
|
||||||
private final FileOutputStream videoOutFile;
|
private final FileOutputStream videoOutFile;
|
||||||
private final String outputFileName;
|
private final String outputFileName;
|
||||||
private final int outputFileWidth;
|
private final int outputFileWidth;
|
||||||
|
@ -57,10 +59,14 @@ public class VideoFileRenderer implements VideoSink {
|
||||||
("YUV4MPEG2 C420 W" + outputFileWidth + " H" + outputFileHeight + " Ip F30:1 A1:1\n")
|
("YUV4MPEG2 C420 W" + outputFileWidth + " H" + outputFileHeight + " Ip F30:1 A1:1\n")
|
||||||
.getBytes(Charset.forName("US-ASCII")));
|
.getBytes(Charset.forName("US-ASCII")));
|
||||||
|
|
||||||
renderThread = new HandlerThread(TAG);
|
renderThread = new HandlerThread(TAG + "RenderThread");
|
||||||
renderThread.start();
|
renderThread.start();
|
||||||
renderThreadHandler = new Handler(renderThread.getLooper());
|
renderThreadHandler = new Handler(renderThread.getLooper());
|
||||||
|
|
||||||
|
fileThread = new HandlerThread(TAG + "FileThread");
|
||||||
|
fileThread.start();
|
||||||
|
fileThreadHandler = new Handler(fileThread.getLooper());
|
||||||
|
|
||||||
ThreadUtils.invokeAtFrontUninterruptibly(renderThreadHandler, new Runnable() {
|
ThreadUtils.invokeAtFrontUninterruptibly(renderThreadHandler, new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -108,19 +114,21 @@ public class VideoFileRenderer implements VideoSink {
|
||||||
final VideoFrame.I420Buffer i420 = scaledBuffer.toI420();
|
final VideoFrame.I420Buffer i420 = scaledBuffer.toI420();
|
||||||
scaledBuffer.release();
|
scaledBuffer.release();
|
||||||
|
|
||||||
YuvHelper.I420Rotate(i420.getDataY(), i420.getStrideY(), i420.getDataU(), i420.getStrideU(),
|
fileThreadHandler.post(() -> {
|
||||||
i420.getDataV(), i420.getStrideV(), outputFrameBuffer, i420.getWidth(), i420.getHeight(),
|
YuvHelper.I420Rotate(i420.getDataY(), i420.getStrideY(), i420.getDataU(), i420.getStrideU(),
|
||||||
frame.getRotation());
|
i420.getDataV(), i420.getStrideV(), outputFrameBuffer, i420.getWidth(), i420.getHeight(),
|
||||||
i420.release();
|
frame.getRotation());
|
||||||
|
i420.release();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
videoOutFile.write("FRAME\n".getBytes(Charset.forName("US-ASCII")));
|
videoOutFile.write("FRAME\n".getBytes(Charset.forName("US-ASCII")));
|
||||||
videoOutFile.write(
|
videoOutFile.write(
|
||||||
outputFrameBuffer.array(), outputFrameBuffer.arrayOffset(), outputFrameSize);
|
outputFrameBuffer.array(), outputFrameBuffer.arrayOffset(), outputFrameSize);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException("Error writing video to disk", e);
|
throw new RuntimeException("Error writing video to disk", e);
|
||||||
}
|
}
|
||||||
frameCount++;
|
frameCount++;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,14 +143,23 @@ public class VideoFileRenderer implements VideoSink {
|
||||||
cleanupBarrier.countDown();
|
cleanupBarrier.countDown();
|
||||||
});
|
});
|
||||||
ThreadUtils.awaitUninterruptibly(cleanupBarrier);
|
ThreadUtils.awaitUninterruptibly(cleanupBarrier);
|
||||||
|
fileThreadHandler.post(() -> {
|
||||||
|
try {
|
||||||
|
videoOutFile.close();
|
||||||
|
Logging.d(TAG,
|
||||||
|
"Video written to disk as " + outputFileName + ". The number of frames is " + frameCount
|
||||||
|
+ " and the dimensions of the frames are " + outputFileWidth + "x"
|
||||||
|
+ outputFileHeight + ".");
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Error closing output file", e);
|
||||||
|
}
|
||||||
|
fileThread.quit();
|
||||||
|
});
|
||||||
try {
|
try {
|
||||||
videoOutFile.close();
|
fileThread.join();
|
||||||
Logging.d(TAG,
|
} catch (InterruptedException e) {
|
||||||
"Video written to disk as " + outputFileName + ". The number of frames is " + frameCount
|
Thread.currentThread().interrupt();
|
||||||
+ " and the dimensions of the frames are " + outputFileWidth + "x" + outputFileHeight
|
Logging.e(TAG, "Interrupted while waiting for the write to disk to complete.", e);
|
||||||
+ ".");
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException("Error closing output file", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue