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

nvidia hardware decoder support #1296

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
6e82380
minor encoder reporting cleanup
bradh Sep 2, 2024
956ba09
nvdec: initial merge
bradh Sep 2, 2024
8c7cbe0
nvdec: enable HEVC support
bradh Sep 3, 2024
6540c04
nvdec: clean up HEVC
bradh Sep 3, 2024
346bea6
nvdec: add AVC support
bradh Sep 3, 2024
d57eebf
nvidia: add to CI
bradh Sep 3, 2024
b4134f1
nvdec: additional CI fixes
bradh Sep 3, 2024
5cd9fc3
ci: fix nvdec option
bradh Sep 3, 2024
41c129a
nvidia: add to cmake presets
bradh Sep 3, 2024
ec2bb0b
avc: additional avcC box parsing
bradh Sep 3, 2024
b8f8ffb
nvdec: additional CI packages
bradh Sep 3, 2024
e2768b4
nvdec: remove mandatory requirement for CUDA
bradh Sep 3, 2024
348a37e
nvdec: only link cuda if found
bradh Sep 3, 2024
81fc370
nvdec: check if we can build without cuda-dev
bradh Sep 3, 2024
cc359f2
Merge pull request #1297 from bradh/avcc_parse
farindk Sep 3, 2024
015c9cf
AVC: pass SPS-Ext to decoder (#1297)
farindk Sep 3, 2024
0672d7d
AVC: dump seq-ext parameters (#1297)
farindk Sep 3, 2024
c22db22
Merge pull request #1295 from bradh/encoder_cleanup_2024-09-03
farindk Sep 3, 2024
321ae91
heif-enc: similar output of uncompressed codec in encoder list as in …
farindk Sep 3, 2024
541782e
heif-dec sort list of decoders
farindk Sep 3, 2024
e65c9a3
avc_box: adapt test output
farindk Sep 3, 2024
c178400
tild: fix parsing of 'tiles_are_sequential' and more dump output
farindk Sep 5, 2024
d9928fe
heif_reader_range_request_result: allow 'overreading' a range request
farindk Sep 5, 2024
8cc6c79
tild: omit writing image size and take it from ispe instead
farindk Sep 6, 2024
aab4c9f
Windows build fix for C++ version.
bradh Sep 8, 2024
83c0954
use C++17 [[fallthrough]]
farindk Sep 10, 2024
831532a
Windows alternatives for unistd and friends.
bradh Sep 8, 2024
4af34ee
fix constness of getopt* implementation for Windows
farindk Sep 10, 2024
24a2435
safe integer check in ftyp parsing
farindk Sep 10, 2024
7b7ac8e
avcC: fix test, write extended avcC fields, error handling
farindk Sep 10, 2024
252ed4a
fix windows compilation (#1302)
farindk Sep 10, 2024
9bd33c0
remove unnecessary check for _WIN64 (#1302)
farindk Sep 10, 2024
64c8cae
fix windows compilation, undefined 'cnt' (#1302)
farindk Sep 10, 2024
2395082
tild: remove support for 64bit dimensions and cleanup
farindk Sep 10, 2024
9483961
limit maximum memory allocation (should fix ClusterFuzz 71389)
farindk Sep 11, 2024
10e455b
iden: make sure that references image item exists
farindk Sep 11, 2024
f50ef3b
iovl: detect self-references
farindk Sep 11, 2024
4e9eb8e
define chroma-420 sample position enum
farindk Sep 11, 2024
e962b59
fix HeifContext::has_alpha() for broken input (fixes #1305)
farindk Sep 11, 2024
4563a2f
move get_tile_size() into ImageItem class
farindk Sep 11, 2024
487318c
url-box: parse 'data-in-same-file' flag
farindk Sep 12, 2024
3a043d9
add option to set plugin install directory independently from search …
farindk Sep 12, 2024
808fbd7
Merge branch 'nvdev_merge_2' of https://github.com/bradh/libheif into…
farindk Sep 13, 2024
3608adf
nvdec: show gfxcard name in plugin description
farindk Sep 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ jobs:
- { NAME: "graphics", WITH_GRAPHICS: 1 }
- { NAME: "x265", WITH_X265: 1 }
- { NAME: "x265 / graphics", WITH_GRAPHICS: 1, WITH_X265: 1 }
- { NAME: "nvidia / graphics", WITH_GRAPHICS: 1, WITH_NVIDIA: 1 }
- { NAME: "libde265 (1) / graphics", WITH_GRAPHICS: 1, WITH_LIBDE265: 1 }
- { NAME: "libde265 (2) / graphics", WITH_GRAPHICS: 1, WITH_LIBDE265: 2 }
- { NAME: "libde265 (1) / x265 / graphics", WITH_GRAPHICS: 1, WITH_X265: 1, WITH_LIBDE265: 1 }
Expand Down
46 changes: 35 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ if(NOT MSVC)
endif ()
endif()

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

Expand All @@ -66,11 +66,19 @@ LIST (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")
# --- codec plugins

option(ENABLE_PLUGIN_LOADING "Support loading of plugins" ON)
set(PLUGIN_DIRECTORY "${CMAKE_INSTALL_FULL_LIBDIR}/libheif" CACHE STRING "Plugin install directory")
set(PLUGIN_DIRECTORY "${CMAKE_INSTALL_FULL_LIBDIR}/libheif" CACHE STRING "Plugin directory")
set(PLUGIN_INSTALL_DIRECTORY "" CACHE STRING "Plugin install directory (leaving it empty will use PLUGIN_DIRECTORY)")

if (ENABLE_PLUGIN_LOADING)
set(PLUGIN_LOADING_SUPPORTED_AND_ENABLED TRUE)
install(DIRECTORY DESTINATION ${PLUGIN_DIRECTORY} DIRECTORY_PERMISSIONS

if (PLUGIN_INSTALL_DIRECTORY STREQUAL "")
set(COMPUTED_PLUGIN_INSTALL_DIRECTORY ${PLUGIN_DIRECTORY})
else ()
set(COMPUTED_PLUGIN_INSTALL_DIRECTORY ${PLUGIN_INSTALL_DIRECTORY})
endif ()

install(DIRECTORY DESTINATION ${COMPUTED_PLUGIN_INSTALL_DIRECTORY} DIRECTORY_PERMISSIONS
OWNER_WRITE OWNER_READ OWNER_EXECUTE
GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE)
Expand Down Expand Up @@ -164,7 +172,7 @@ endif ()
# openh264 decoder

plugin_option(OpenH264_DECODER "OpenH264 decoder" ON OFF)
plugin_option(OpenH264_ENCODER "OpenH264 encoder" ON OFF)
# plugin_option(OpenH264_ENCODER "OpenH264 encoder" ON OFF)
if (WITH_OpenH264_ENCODER OR WITH_OpenH264_DECODER)
find_package(OpenH264)

Expand All @@ -173,9 +181,9 @@ if (WITH_OpenH264_ENCODER OR WITH_OpenH264_DECODER)
if (OpenH264_FOUND AND WITH_OpenH264_DECODER)
set(OpenH264_DECODER_FOUND TRUE)
endif()
if (OpenH264_FOUND AND WITH_OpenH264_ENCODER)
set(OpenH264_ENCODER_FOUND TRUE)
endif()
# if (OpenH264_FOUND AND WITH_OpenH264_ENCODER)
# set(OpenH264_ENCODER_FOUND TRUE)
# endif()
endif()


Expand Down Expand Up @@ -248,6 +256,13 @@ if (WITH_OPENJPH_ENCODER OR WITH_OPENJPH_DECODER)
find_package(OPENJPH)
endif()

# nvidia hardware decode

plugin_option(NV_DECODER "NVIDIA Hardware AVC/AV1/HEVC/JPEG decoder" OFF OFF)
if (WITH_NV_DECODER)
find_package(NVDEC)
endif()

# uncompressed

option(WITH_UNCOMPRESSED_CODEC " Support internal ISO/IEC 23001-17 uncompressed codec (experimental) " OFF)
Expand All @@ -268,14 +283,16 @@ plugin_compilation_info(RAV1E RAV1E "Rav1e AV1 encoder")
plugin_compilation_info(JPEG_DECODER JPEG "JPEG decoder")
plugin_compilation_info(JPEG_ENCODER JPEG "JPEG encoder")
plugin_compilation_info(OpenH264_DECODER OpenH264_DECODER "OpenH264 decoder")
plugin_compilation_info(OpenH264_ENCODER OpenH264_ENCODER "OpenH264 encoder")
# plugin_compilation_info(OpenH264_ENCODER OpenH264_ENCODER "OpenH264 encoder")
plugin_compilation_info(OpenJPEG_DECODER OpenJPEG "OpenJPEG J2K decoder")
plugin_compilation_info(OpenJPEG_ENCODER OpenJPEG "OpenJPEG J2K encoder")
# plugin_compilation_info(OPENJPH_DECODER OPENJPH "OpenJPH HT-J2K decoder")
plugin_compilation_info(OPENJPH_ENCODER OPENJPH "OpenJPH HT-J2K encoder")
plugin_compilation_info(UVG266_ENCODER UVG266 "uvg266 VVC enc. (experimental)")
plugin_compilation_info(VVENC vvenc "vvenc VVC enc. (experimental)")
plugin_compilation_info(VVDEC vvdec "vvdec VVC dec. (experimental)")
plugin_compilation_info(NV_DECODER NVDEC "NVIDIA hardware decoder")


# --- show summary which formats are supported

Expand Down Expand Up @@ -343,6 +360,12 @@ endif()
if (OpenH264_ENCODER_FOUND)
set(SUPPORTS_AVC_ENCODING TRUE)
endif()
if (NVDEC_FOUND)
set(SUPPORTS_HEIC_DECODING TRUE)
set(SUPPORTS_AVC_DECODING TRUE)
set(SUPPORTS_JPEG_DECODING TRUE)
set(SUPPORTS_AVIF_DECODING TRUE)
endif()

if (WITH_UNCOMPRESSED_CODEC)
set(SUPPORTS_UNCOMPRESSED_DECODING TRUE)
Expand All @@ -351,14 +374,15 @@ endif()

message("\n=== Supported formats ===")
message("format decoding encoding")
format_compilation_info("HEIC" SUPPORTS_HEIC_DECODING SUPPORTS_HEIC_ENCODING)
format_compilation_info("AVIF" SUPPORTS_AVIF_DECODING SUPPORTS_AVIF_ENCODING)
format_compilation_info("VVC" SUPPORTS_VVC_DECODING SUPPORTS_VVC_ENCODING)
format_compilation_info("AVC" SUPPORTS_AVC_DECODING SUPPORTS_AVC_ENCODING)
format_compilation_info("AVIF" SUPPORTS_AVIF_DECODING SUPPORTS_AVIF_ENCODING)
format_compilation_info("HEIC" SUPPORTS_HEIC_DECODING SUPPORTS_HEIC_ENCODING)
format_compilation_info("JPEG" SUPPORTS_JPEG_DECODING SUPPORTS_JPEG_ENCODING)
format_compilation_info("JPEG2000" SUPPORTS_J2K_DECODING SUPPORTS_J2K_ENCODING)
format_compilation_info("JPEG2000-HT" SUPPORTS_J2K_HT_DECODING SUPPORTS_J2K_HT_ENCODING)
format_compilation_info("Uncompressed" SUPPORTS_UNCOMPRESSED_DECODING SUPPORTS_UNCOMPRESSED_ENCODING)
format_compilation_info("VVC" SUPPORTS_VVC_DECODING SUPPORTS_VVC_ENCODING)

message("")

# --- Libsharpyuv color space transforms
Expand Down
8 changes: 8 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@
"WITH_OpenJPEG_ENCODER_PLUGIN" : "OFF",
"WITH_FFMPEG_DECODER" : "ON",
"WITH_FFMPEG_DECODER_PLUGIN" : "OFF",
"WITH_OpenH264_DECODER" : "ON",
"WITH_OpenH264_DECODER_PLUGIN" : "OFF",
"WITH_NV_DECODER" : "ON",
"WITH_NV_DECODER_PLUGIN" : "OFF",

"WITH_REDUCED_VISIBILITY" : "OFF",
"WITH_HEADER_COMPRESSION" : "ON",
Expand Down Expand Up @@ -89,6 +93,10 @@
"WITH_OPENJPH_ENCODER" : "ON",
"WITH_FFMPEG_DECODER" : "ON",
"WITH_FFMPEG_DECODER_PLUGIN" : "ON",
"WITH_OpenH264_DECODER" : "ON",
"WITH_OpenH264_DECODER_PLUGIN" : "ON",
"WITH_NV_DECODER" : "ON",
"WITH_NV_DECODER_PLUGIN" : "ON",

"WITH_REDUCED_VISIBILITY" : "ON",
"WITH_HEADER_COMPRESSION" : "ON",
Expand Down
16 changes: 16 additions & 0 deletions cmake/modules/FindNVDEC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
include(LibFindMacros)

find_library(NVDEC_LIBRARY
NAMES libnvcuvid nvcuvid
)

find_package(CUDAToolkit)

set(NVDEC_PROCESS_LIBS NVDEC_LIBRARY)
libfind_process(NVDEC)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(NVDEC
REQUIRED_VARS
NVDEC_LIBRARY
)
18 changes: 9 additions & 9 deletions examples/heif_dec.cc
Original file line number Diff line number Diff line change
Expand Up @@ -168,32 +168,32 @@ void list_decoders(heif_compression_format format)

void list_all_decoders()
{
std::cout << "HEIC decoders:\n";
list_decoders(heif_compression_HEVC);
std::cout << "AVC decoders:\n";
list_decoders(heif_compression_AVC);

std::cout << "AVIF decoders:\n";
list_decoders(heif_compression_AV1);

std::cout << "VVIC decoders:\n";
list_decoders(heif_compression_VVC);

std::cout << "AVC decoders:\n";
list_decoders(heif_compression_AVC);
std::cout << "HEIC decoders:\n";
list_decoders(heif_compression_HEVC);

std::cout << "JPEG decoders:\n";
list_decoders(heif_compression_JPEG);

std::cout << "JPEG 2000 decoders:\n";
list_decoders(heif_compression_JPEG2000);

std::cout << "HT-J2K decoders:\n";
std::cout << "JPEG 2000 (HT) decoders:\n";
list_decoders(heif_compression_HTJ2K);

#if WITH_UNCOMPRESSED_CODEC
std::cout << "uncompressed: yes\n";
#else
std::cout << "uncompressed: no\n";
#endif

std::cout << "VVIC decoders:\n";
list_decoders(heif_compression_VVC);
}


Expand Down Expand Up @@ -261,7 +261,7 @@ int main(int argc, char** argv)
break;
case '?':
std::cerr << "\n";
// fallthrough
[[fallthrough]];
case 'h':
show_help(argv[0]);
return 0;
Expand Down
28 changes: 19 additions & 9 deletions examples/heif_enc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,9 @@ static const char* get_compression_format_name(heif_compression_format format)
case heif_compression_AV1:
return "AV1";
break;
case heif_compression_AVC:
return "AVC";
break;
case heif_compression_VVC:
return "VVC";
break;
Expand All @@ -399,19 +402,18 @@ static const char* get_compression_format_name(heif_compression_format format)

static void show_list_of_all_encoders()
{
for (auto compression_format : {heif_compression_HEVC, heif_compression_AV1, heif_compression_VVC, heif_compression_JPEG, heif_compression_JPEG2000, heif_compression_HTJ2K
#if WITH_UNCOMPRESSED_CODEC
, heif_compression_uncompressed
#endif
for (auto compression_format: {heif_compression_AVC, heif_compression_AV1, heif_compression_HEVC,
heif_compression_JPEG, heif_compression_JPEG2000, heif_compression_HTJ2K,
heif_compression_uncompressed, heif_compression_VVC
}) {

switch (compression_format) {
case heif_compression_AVC:
std::cout << "AVC";
break;
case heif_compression_AV1:
std::cout << "AVIF";
break;
case heif_compression_VVC:
std::cout << "VVIC";
break;
case heif_compression_HEVC:
std::cout << "HEIC";
break;
Expand All @@ -422,10 +424,18 @@ static void show_list_of_all_encoders()
std::cout << "JPEG 2000";
break;
case heif_compression_HTJ2K:
std::cout << "HT-J2K";
std::cout << "JPEG 2000 (HT)";
break;
case heif_compression_uncompressed:
std::cout << "Uncompressed";
#if WITH_UNCOMPRESSED_CODEC
std::cout << "Uncompressed: yes\n";
#else
std::cout << "Uncompressed: no\n";
#endif
continue; // special handling of this case because it is built in without plugin
break;
case heif_compression_VVC:
std::cout << "VVIC";
break;
default:
assert(false);
Expand Down
4 changes: 2 additions & 2 deletions extra/getopt.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ struct option
#define required_argument 1
#define optional_argument 2

int getopt(int, char**, char*);
int getopt_long(int, char**, char*, struct option*, int*);
int getopt(int, char**, const char*);
int getopt_long(int, char**, const char*, struct option*, int*);

#ifdef __cplusplus
}
Expand Down
2 changes: 1 addition & 1 deletion extra/getopt_long.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ getopt2(int nargc, char * nargv, const char *ostr)
* Parse argc/argv argument vector.
*/
int
getopt_long(int nargc, char ** nargv, char * options, struct option * long_options, int * index)
getopt_long(int nargc, char ** nargv, const char * options, struct option * long_options, int * index)
{
int retval;

Expand Down
13 changes: 1 addition & 12 deletions libheif/api/libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -909,18 +909,7 @@ struct heif_error heif_image_handle_get_tile_size(const struct heif_image_handle

uint32_t w,h;

if (std::shared_ptr<ImageItem_Grid> gridItem = std::dynamic_pointer_cast<ImageItem_Grid>(handle->image)) {
gridItem->get_tile_size(w,h);
}
else if (std::shared_ptr<ImageItem_Tild> tildItem = std::dynamic_pointer_cast<ImageItem_Tild>(handle->image)) {
tildItem->get_tile_size(w,h);
}
else {
// return whole image size (the image is the only tile)

w = handle->image->get_width();
h = handle->image->get_height();
}
handle->image->get_tile_size(w,h);

if (tile_width) {
*tile_width = w;
Expand Down
22 changes: 16 additions & 6 deletions libheif/api/libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,13 @@ typedef uint32_t heif_brand2;
*/
#define heif_brand2_miaf heif_fourcc('m','i','a','f')

/**
* AVC (H.264) image (`avci`) brand.
*
* See ISO/IEC 23008-12:2022 Annex E.4
*/
#define heif_brand2_avci heif_fourcc('a','v','c','i')

/**
* Single picture file brand.
*
Expand Down Expand Up @@ -936,7 +943,7 @@ struct heif_reading_options;
enum heif_reader_grow_status
{
heif_reader_grow_status_size_reached, // requested size has been reached, we can read until this point
heif_reader_grow_status_timeout, // size has not been reached yet, but it may still grow further
heif_reader_grow_status_timeout, // size has not been reached yet, but it may still grow further (deprecated)
heif_reader_grow_status_size_beyond_eof, // size has not been reached and never will. The file has grown to its full size
heif_reader_grow_status_error // an error has occurred
};
Expand All @@ -945,8 +952,11 @@ struct heif_reader_range_request_result
{
enum heif_reader_grow_status status; // should not return 'heif_reader_grow_status_timeout'

// for status == 'heif_reader_grow_status_size_beyond_eof'
uint64_t range_end; // if not the whole file range could be read, this is the end position
// Indicates until what position the file has been read.
// If we cannot read the whole file range (status == 'heif_reader_grow_status_size_beyond_eof'), this is the actual end position.
// On the other hand, it may be that the reader was reading more data than requested. In that case, it should indicate the full size here
// and libheif may decide to make use of the additional data (e.g. for filling 'tild' offset tables).
uint64_t range_end;

// for status == 'heif_reader_grow_status_error'
int reader_error_code; // a reader specific error code
Expand Down Expand Up @@ -2426,8 +2436,8 @@ struct heif_tild_image_parameters {

// --- version 1

uint64_t image_width;
uint64_t image_height;
uint32_t image_width;
uint32_t image_height;

uint32_t tile_width;
uint32_t tile_height;
Expand All @@ -2438,7 +2448,7 @@ struct heif_tild_image_parameters {
uint8_t size_field_length; // one of: 0, 24, 32, 64

uint8_t number_of_extra_dimensions; // 0 for normal images, 1 for volumetric (3D), ...
uint64_t extra_dimensions[8]; // size of extra dimensions (first 8 dimensions)
uint32_t extra_dimensions[8]; // size of extra dimensions (first 8 dimensions)

// boolean flags
uint8_t tiles_are_sequential; // TODO: can we derive this automatically
Expand Down
Loading
Loading