From 5c8afb1129476026ceb7eb1957951f914ebf1989 Mon Sep 17 00:00:00 2001 From: devjeonghwan Date: Wed, 31 May 2023 22:56:08 +0900 Subject: [PATCH] * Add new `SampleJpegEncoder` code for nvJPEG module of CUDA (pull #1365) --- CHANGELOG.md | 1 + ...SampleJpeg.java => SampleJpegDecoder.java} | 6 +- cuda/samples/SampleJpegEncoder.java | 155 ++++++++++++++++++ .../org/bytedeco/cuda/presets/nvjpeg.java | 4 +- .../org/bytedeco/nvcodec/presets/nvcuvid.java | 4 +- .../bytedeco/nvcodec/presets/nvencodeapi.java | 4 +- 6 files changed, 165 insertions(+), 9 deletions(-) rename cuda/samples/{SampleJpeg.java => SampleJpegDecoder.java} (98%) create mode 100644 cuda/samples/SampleJpegEncoder.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 44624fa0de8..5da5f947380 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ + * Add new `SampleJpegEncoder` code for nvJPEG module of CUDA ([pull #1365](https://github.com/bytedeco/javacpp-presets/pull/1365)) * Map `std::vector` of `CameraParams`, `ImageFeatures`, and `MatchesInfo` from `cv::detail` ([issue bytedeco/javacv#2027](https://github.com/bytedeco/javacv/issues/2027)) * Fix H.264 decoder of FFmpeg by increasing MAX_SLICES to 256 ([pull #1349](https://github.com/bytedeco/javacpp-presets/pull/1349)) * Link FFmpeg with latest version of VA-API libraries ([pull #1296](https://github.com/bytedeco/javacpp-presets/pull/1296)) diff --git a/cuda/samples/SampleJpeg.java b/cuda/samples/SampleJpegDecoder.java similarity index 98% rename from cuda/samples/SampleJpeg.java rename to cuda/samples/SampleJpegDecoder.java index 36b253d780f..49a620b1e64 100644 --- a/cuda/samples/SampleJpeg.java +++ b/cuda/samples/SampleJpegDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 Park JeongHwan + * Copyright (C) 2022 Jeonghwan Park * * Licensed either under the Apache License, Version 2.0, or (at your option) * under the terms of the GNU General Public License as published by @@ -92,7 +92,7 @@ public static void main(String[] args) { nvjpegDecodeParams params = new nvjpegDecodeParams(); - // Create Components + // Create components CHECK_NVJPEG("nvjpegCreateEx", nvjpegCreateEx(NVJPEG_BACKEND_DEFAULT, devAllocator, pinnedAllocator, NVJPEG_FLAGS_DEFAULT, handle)); CHECK_NVJPEG("nvjpegJpegStateCreate", nvjpegJpegStateCreate(handle, state)); @@ -108,7 +108,7 @@ public static void main(String[] args) { CHECK_NVJPEG("nvjpegDecodeParamsCreate", nvjpegDecodeParamsCreate(handle, params)); - // Destroy Components + // Destroy components CHECK_NVJPEG("nvjpegDecodeParamsDestroy", nvjpegDecodeParamsDestroy(params)); CHECK_NVJPEG("nvjpegJpegStreamDestroy", nvjpegJpegStreamDestroy(streams[0])); diff --git a/cuda/samples/SampleJpegEncoder.java b/cuda/samples/SampleJpegEncoder.java new file mode 100644 index 00000000000..222600d1d08 --- /dev/null +++ b/cuda/samples/SampleJpegEncoder.java @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2023 Jeonghwan Park + * + * Licensed either under the Apache License, Version 2.0, or (at your option) + * under the terms of the GNU General Public License as published by + * the Free Software Foundation (subject to the "Classpath" exception), + * either version 2, or any later version (collectively, the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.gnu.org/licenses/ + * http://www.gnu.org/software/classpath/license.html + * + * or as provided in the LICENSE.txt file that accompanied this code. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import org.bytedeco.cuda.cudart.*; +import org.bytedeco.cuda.nvjpeg.*; +import org.bytedeco.javacpp.Pointer; +import org.bytedeco.javacpp.SizeTPointer; +import org.bytedeco.javacpp.BytePointer; +import org.bytedeco.javacpp.PointerPointer; + +import static org.bytedeco.cuda.global.cudart.*; +import static org.bytedeco.cuda.global.nvjpeg.*; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; + +public class SampleJpeg { + static class dev_malloc extends tDevMalloc { + final static dev_malloc instance = new dev_malloc().retainReference(); + + @Override + public int call(PointerPointer pointerPointer, long l) { + return cudaMalloc(pointerPointer, l); + } + } + + static class dev_free extends tDevFree { + final static dev_free instance = new dev_free().retainReference(); + + @Override + public int call(Pointer pointer) { + return cudaFree(pointer); + } + } + + static class host_malloc extends tPinnedMalloc { + final static host_malloc instance = new host_malloc().retainReference(); + + @Override + public int call(PointerPointer pointerPointer, long l, int i) { + return cudaHostAlloc(pointerPointer, l, i); + } + } + + static class host_free extends tPinnedFree { + final static host_free instance = new host_free().retainReference(); + + @Override + public int call(Pointer pointer) { + return cudaFreeHost(pointer); + } + } + + public static void CHECK_CUDA(String functionName, int result) { + if (result != CUDA_SUCCESS) { + throw new IllegalStateException(String.format("%s returned '%d'", functionName, result)); + } + } + + public static void CHECK_NVJPEG(String functionName, int result) { + if (result != NVJPEG_STATUS_SUCCESS) { + throw new IllegalStateException(String.format("%s returned '%d'", functionName, result)); + } + } + + public static void main(String[] args) { + int imageWidth = 1280; + int imageHeight = 720; + + nvjpegDevAllocator_t devAllocator = new nvjpegDevAllocator_t(); + devAllocator.dev_malloc(devMalloc.instance); + devAllocator.dev_free(dev_free.instance); + + nvjpegPinnedAllocator_t pinnedAllocator = new nvjpegPinnedAllocator_t(); + pinnedAllocator.pinned_malloc(hostMalloc.instance); + pinnedAllocator.pinned_free(hostFree.instance); + + // Initialize cuda + CUctx_st context = new CUctx_st(); + CHECK_CUDA("cuInit", cuInit(0)); + CHECK_CUDA("cuCtxCreate", cuCtxCreate(context, CU_CTX_SCHED_BLOCKING_SYNC, 0)); + + // Create cuda stream + CUstream_st stream = new CUstream_st(); + CHECK_CUDA("cuStreamCreate", cuStreamCreate(stream, 0)); + + // Create handle + nvjpegHandle nvjpegHandle = new nvjpegHandle(); + CHECK_NVJPEG("nvjpegCreateEx", nvjpegCreateEx(NVJPEG_BACKEND_DEFAULT, devAllocator, pinnedAllocator, NVJPEG_FLAGS_DEFAULT, nvjpegHandle)); + + // Create encoder components + nvjpegEncoderState nvjpegEncoderState = new nvjpegEncoderState(); + nvjpegEncoderParams nvjpegEncoderParams = new nvjpegEncoderParams(); + CHECK_NVJPEG("nvjpegEncoderParamsCreate", nvjpegEncoderParamsCreate(nvjpegHandle, nvjpegEncoderParams, stream)); + CHECK_NVJPEG("nvjpegEncoderStateCreate", nvjpegEncoderStateCreate(nvjpegHandle, nvjpegEncoderState, stream)); + CHECK_NVJPEG("nvjpegEncoderParamsSetSamplingFactors", nvjpegEncoderParamsSetSamplingFactors(nvjpegEncoderParams, NVJPEG_CSS_444, stream)); + + // Create jpeg image + nvjpegImage_t nvjpegImage = new nvjpegImage_t(); + + long channelSize = imageWidth * imageHeight; + + // Fill image to blue + for (int i = 0; i < 3; i++) { + nvjpegImage.pitch(i, imageWidth); + BytePointer deviceMemory = new BytePointer(); + + CHECK_CUDA("cudaMalloc", cudaMalloc(deviceMemory, channelSize)); + CHECK_CUDA("cudaMemset", cudaMemset(deviceMemory, i == 0 ? 255 : 0, channelSize)); + + nvjpegImage.channel(i, deviceMemory); + } + + // Compress image + CHECK_NVJPEG("nvjpegEncodeImage", nvjpegEncodeImage(nvjpegHandle, nvjpegEncoderState, nvjpegEncoderParams, nvjpegImage, NVJPEG_INPUT_BGR, imageWidth, imageHeight, stream)); + + // Get compressed size + SizeTPointer jpegSize = new SizeTPointer(1); + CHECK_NVJPEG("nvjpegEncodeRetrieveBitstream", nvjpegEncodeRetrieveBitstream(nvjpegHandle, nvjpegEncoderState, (BytePointer) null, jpegSize, stream)); + + // Retrieve bitstream + BytePointer jpegBytePointer = new BytePointer(jpegSize.get()); + CHECK_NVJPEG("nvjpegEncodeRetrieveBitstream", nvjpegEncodeRetrieveBitstream(nvjpegHandle, nvjpegEncoderState, jpegBytePointer, jpegSize, stream)); + + // Synchronize cuda stream + CHECK_CUDA("cudaStreamSynchronize", cudaStreamSynchronize(stream)); + + // Get bitstream to java side array + byte[] bytes = new byte[(int) jpegSize.get()]; + jpegBytePointer.get(bytes); + + // Write + Files.write(new File("out.jpg").toPath(), bytes); + } +} diff --git a/cuda/src/main/java/org/bytedeco/cuda/presets/nvjpeg.java b/cuda/src/main/java/org/bytedeco/cuda/presets/nvjpeg.java index 6f563f425ff..4647ffe3f63 100644 --- a/cuda/src/main/java/org/bytedeco/cuda/presets/nvjpeg.java +++ b/cuda/src/main/java/org/bytedeco/cuda/presets/nvjpeg.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022-2023 Park JeongHwan, Samuel Audet + * Copyright (C) 2022-2023 Jeonghwan Park, Samuel Audet * * Licensed either under the Apache License, Version 2.0, or (at your option) * under the terms of the GNU General Public License as published by @@ -31,7 +31,7 @@ /** * - * @author Park JeongHwan + * @author Jeonghwan Park */ @Properties(inherit = cudart.class, value = { @Platform(include = "", link = "nvjpeg@.12"), diff --git a/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvcuvid.java b/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvcuvid.java index f30332bf612..26f610cdcf3 100644 --- a/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvcuvid.java +++ b/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvcuvid.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 Park JeongHwan + * Copyright (C) 2021 Jeonghwan Park * * Licensed either under the Apache License, Version 2.0, or (at your option) * under the terms of the GNU General Public License as published by @@ -37,7 +37,7 @@ /** * - * @author Park JeongHwan + * @author Jeonghwan Park */ @Properties( inherit = cudart.class, diff --git a/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvencodeapi.java b/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvencodeapi.java index b8f05c135a1..1458e0bb961 100644 --- a/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvencodeapi.java +++ b/nvcodec/src/main/java/org/bytedeco/nvcodec/presets/nvencodeapi.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021-2023 Park JeongHwan, Samuel Audet + * Copyright (C) 2021-2023 Jeonghwan Park, Samuel Audet * * Licensed either under the Apache License, Version 2.0, or (at your option) * under the terms of the GNU General Public License as published by @@ -32,7 +32,7 @@ /** * - * @author Park JeongHwan + * @author Jeonghwan Park */ @Properties( inherit = nvcuvid.class,