Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(KVS): - Add Support for More Resolution Widths #3609

Merged
merged 12 commits into from
Jul 29, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,27 @@ private void copyCameraFrameIntoInputImage(final int inputBufferIndex,
final Image cameraFrame) {
final Image codecInputImage = mEncoder.getInputImage(inputBufferIndex);

final int imageWidth = cameraFrame.getWidth();
final int imageRowStride = cameraFrame.getPlanes()[0].getRowStride();
final int imageChromaPixelStride = cameraFrame.getPlanes()[1].getPixelStride();

final boolean isRowPaddingPresent = imageWidth != imageRowStride;
final boolean isSemiPlanar = imageChromaPixelStride != 1;

for (int i = 0; i < cameraFrame.getPlanes().length; i++) {
final ByteBuffer sourceImagePlane = cameraFrame.getPlanes()[i].getBuffer();
final ByteBuffer destinationImagePlane = codecInputImage.getPlanes()[i].getBuffer();
copyBuffer(sourceImagePlane, destinationImagePlane);

final int pixelStride = codecInputImage.getPlanes()[i].getPixelStride();

// Accounting for horizontal padding that may have been added for camera optimization. For example, non-multiple-of-64-width
// resolutions may have had padding added to the rows to reach the nearest greater multiple of 64.
// This accounting for is only supported for SemiPlanar format at the moment.
if (isRowPaddingPresent && isSemiPlanar) {
copyPaddedBuffer(sourceImagePlane, destinationImagePlane, imageWidth, imageRowStride, pixelStride);
} else {
copyBuffer(sourceImagePlane, destinationImagePlane);
}
}
}

Expand All @@ -156,6 +173,58 @@ private int copyBuffer(final ByteBuffer sourceBuffer,
return bytesToCopy;
}

// This copy function will ignore the extra padding data when copying into the encoder's input buffer.
// This will only work for SemiPlanar format.
private int copyPaddedBuffer(final ByteBuffer sourceBuffer,
final ByteBuffer destinationBuffer,
final int imageWidth,
final int sourceBufferRowStride,
final int pixelStride) {

// For an unknown reason, the sourceBuffer's remaining bytes are slightly less than expected, rounding up fixes this.
final int numRows = (int) Math.ceil((double) sourceBuffer.remaining() / sourceBufferRowStride);

// Desired bytes might exceed destination buffer capacity.
final int desiredBytesToCopy = numRows * imageWidth;
final int bytesToCopy = Math.min(desiredBytesToCopy, destinationBuffer.capacity());
destinationBuffer.limit(bytesToCopy);

// If this is a chroma plane, then don't include the final row in the for loop - it is an edge case.
final int numRowsToIterate;
if (pixelStride == 2) {
numRowsToIterate = numRows - 1;
} else {
numRowsToIterate = numRows;
}

for (int row = 0; row < numRowsToIterate; row++) {
final int startPos = row * sourceBufferRowStride;
final int endPos = startPos + imageWidth;

sourceBuffer.limit(endPos);
sourceBuffer.position(startPos);

// Put the valid row data into the destination buffer.
destinationBuffer.put(sourceBuffer);
}

// If this is a chroma frame, handle the final row which is missing one value, hence the "-1" to the endPos.
if (pixelStride == 2) {
final int startPos = numRowsToIterate * sourceBufferRowStride;
final int endPos = startPos + imageWidth - 1;

sourceBuffer.limit(endPos);
sourceBuffer.position(startPos);

// Put the valid row data into the destination buffer.
destinationBuffer.put(sourceBuffer);
}

destinationBuffer.rewind();

return bytesToCopy;
}

private long nanosSinceFirstFrame() {
final long currentTime = System.currentTimeMillis();
if (mFirstFrameTimestamp < 0) {
Expand Down