[x265] [PATCH 2 of 5] dhdr10-info: add tone-mapping metadata as SEI message with cli option
bhavna at multicorewareinc.com
bhavna at multicorewareinc.com
Thu Apr 20 07:46:59 CEST 2017
# HG changeset patch
# User Bhavna Hariharan <bhavna at multicorewareinc.com>
# Date 1492645019 25200
# Wed Apr 19 16:36:59 2017 -0700
# Node ID e2eb86dce7f493cd14ea3d8bc002d17f839b1aa7
# Parent f0545a714a70c18bc462e477ce5ce962b9253cb7
dhdr10-info: add tone-mapping metadata as SEI message with cli option
diff -r f0545a714a70 -r e2eb86dce7f4 source/CMakeLists.txt
--- a/source/CMakeLists.txt Wed Mar 22 14:33:20 2017 +0530
+++ b/source/CMakeLists.txt Wed Apr 19 16:36:59 2017 -0700
@@ -29,7 +29,7 @@
option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF)
mark_as_advanced(FPROFILE_USE FPROFILE_GENERATE NATIVE_BUILD)
# X265_BUILD must be incremented each time the public API is changed
-set(X265_BUILD 114)
+set(X265_BUILD 115)
configure_file("${PROJECT_SOURCE_DIR}/x265.def.in"
"${PROJECT_BINARY_DIR}/x265.def")
configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in"
@@ -363,6 +363,13 @@
else(HIGH_BIT_DEPTH)
add_definitions(-DHIGH_BIT_DEPTH=0 -DX265_DEPTH=8)
endif(HIGH_BIT_DEPTH)
+# this option is to enable the inclusion of dynamic HDR10 library to the libx265 compilation
+option(ENABLE_DYNAMIC_HDR10 "Enable dynamic HDR10 compilation" OFF)
+if (ENABLE_DYNAMIC_HDR10)
+ add_subdirectory(dynamicHDR10)
+ include_directories(dynamicHDR10)
+ add_definitions(-DENABLE_DYNAMIC_HDR10)
+endif(ENABLE_DYNAMIC_HDR10)
# this option can only be used when linking multiple libx265 libraries
# together, and some alternate API access method is implemented.
@@ -502,9 +509,12 @@
endforeach()
endif()
endif()
-
source_group(ASM FILES ${ASM_SRCS})
-add_library(x265-static STATIC $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${ASM_OBJS} ${ASM_SRCS})
+if(ENABLE_DYNAMIC_HDR10)
+ add_library(x265-static STATIC $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> $<TARGET_OBJECTS:dynamicHDR10> ${ASM_OBJS} ${ASM_SRCS})
+else()
+ add_library(x265-static STATIC $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${ASM_OBJS} ${ASM_SRCS})
+endif()
if(NOT MSVC)
set_target_properties(x265-static PROPERTIES OUTPUT_NAME x265)
endif()
@@ -535,11 +545,16 @@
if(NOT (MSVC_IDE OR XCODE))
add_custom_target(clean-generated COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/clean-generated.cmake)
endif()
-
option(ENABLE_SHARED "Build shared library" ON)
if(ENABLE_SHARED)
- add_library(x265-shared SHARED "${PROJECT_BINARY_DIR}/x265.def" ${ASM_OBJS}
- ${X265_RC_FILE} $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common>)
+
+ if(ENABLE_DYNAMIC_HDR10)
+ add_library(x265-shared SHARED "${PROJECT_BINARY_DIR}/x265.def" ${ASM_OBJS}
+ ${X265_RC_FILE} $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> $<TARGET_OBJECTS:dynamicHDR10>)
+ else()
+ add_library(x265-shared SHARED "${PROJECT_BINARY_DIR}/x265.def" ${ASM_OBJS}
+ ${X265_RC_FILE} $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common>)
+ endif()
if(EXTRA_LIB)
target_link_libraries(x265-shared ${EXTRA_LIB})
endif()
@@ -629,12 +644,17 @@
if(WIN32)
set(ExportDefs "${PROJECT_BINARY_DIR}/x265.def")
endif(WIN32)
-
if(XCODE)
# Xcode seems unable to link the CLI with libs, so link as one targget
+ if(ENABLE_DYNAMIC_HDR10)
add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${GETOPT}
- x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp
- $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${ASM_OBJS} ${ASM_SRCS})
+ x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp
+ $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> $<TARGET_OBJECTS:dynamicHDR10> ${ASM_OBJS} ${ASM_SRCS})
+ else()
+ add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${GETOPT}
+ x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp
+ $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${ASM_OBJS} ${ASM_SRCS})
+ endif()
else()
add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${GETOPT} ${X265_RC_FILE}
${ExportDefs} x265.cpp x265.h x265cli.h x265-extras.h x265-extras.cpp)
diff -r f0545a714a70 -r e2eb86dce7f4 source/common/param.cpp
--- a/source/common/param.cpp Wed Mar 22 14:33:20 2017 +0530
+++ b/source/common/param.cpp Wed Apr 19 16:36:59 2017 -0700
@@ -272,6 +272,7 @@
param->bAQMotion = 0;
param->bHDROpt = 0;
param->analysisRefineLevel = 5;
+ param->toneMapFile = NULL;
}
int x265_param_default_preset(x265_param* param, const char* preset, const char* tune)
{
@@ -948,6 +949,7 @@
OPT("hdr") p->bEmitHDRSEI = atobool(value);
OPT("hdr-opt") p->bHDROpt = atobool(value);
OPT("limit-sao") p->bLimitSAO = atobool(value);
+ OPT("dhdr10-info") p->toneMapFile = strdup(value);
else
return X265_PARAM_BAD_NAME;
}
@@ -1467,6 +1469,9 @@
TOOLOPT(!param->bSaoNonDeblocked && param->bEnableSAO, "sao");
TOOLOPT(param->rc.bStatWrite, "stats-write");
TOOLOPT(param->rc.bStatRead, "stats-read");
+#if ENABLE_DYNAMIC_HDR10
+ TOOLVAL(param->toneMapFile != NULL, "dhdr10-info");
+#endif
x265_log(param, X265_LOG_INFO, "tools:%s\n", buf);
fflush(stderr);
}
diff -r f0545a714a70 -r e2eb86dce7f4 source/encoder/encoder.cpp
--- a/source/encoder/encoder.cpp Wed Mar 22 14:33:20 2017 +0530
+++ b/source/encoder/encoder.cpp Wed Apr 19 16:36:59 2017 -0700
@@ -84,10 +84,11 @@
m_cR = 1.0;
for (int i = 0; i < X265_MAX_FRAME_THREADS; i++)
m_frameEncoder[i] = NULL;
-
MotionEstimate::initScales();
+#if ENABLE_DYNAMIC_HDR10
+ api = hdr10plus_api_get();
+#endif
}
-
inline char *strcatFilename(const char *input, const char *suffix)
{
char *output = X265_MALLOC(char, strlen(input) + strlen(suffix) + 1);
@@ -502,7 +503,7 @@
free((char*)m_param->scalingLists);
free((char*)m_param->numaPools);
free((char*)m_param->masteringDisplayColorVolume);
-
+ free((char*)m_param->toneMapFile);
PARAM_NS::x265_param_free(m_param);
}
}
@@ -593,9 +594,24 @@
m_exportedPic = NULL;
m_dpb->recycleUnreferenced();
}
-
if (pic_in)
{
+ x265_sei_payload toneMap;
+ toneMap.payload = NULL;
+#if ENABLE_DYNAMIC_HDR10
+ if (m_bToneMap)
+ {
+ uint8_t *cim = NULL;
+ if (api->hdr10plus_json_to_frame_cim(m_param->toneMapFile, pic_in->poc, cim))
+ {
+ toneMap.payload = (uint8_t*)x265_malloc(sizeof(uint8_t) * cim[0]);
+ toneMap.payloadSize = cim[0];
+ toneMap.payloadType = USER_DATA_REGISTERED_ITU_T_T35;
+ memcpy(toneMap.payload, cim, toneMap.payloadSize);
+ }
+ }
+#endif
+
if (pic_in->bitDepth < 8 || pic_in->bitDepth > 16)
{
x265_log(m_param, X265_LOG_ERROR, "Input bit depth (%d) must be between 8 and 16\n",
@@ -677,17 +693,29 @@
inFrame->m_forceqp = pic_in->forceqp;
inFrame->m_param = (m_reconfigure || m_reconfigureRc) ? m_latestParam : m_param;
- if (pic_in->userSEI.numPayloads)
+ int toneMapEnable = 0;
+ if (m_bToneMap && toneMap.payload)
+ toneMapEnable = 1;
+ int numPayloads = pic_in->userSEI.numPayloads + toneMapEnable;
+ inFrame->m_userSEI.numPayloads = numPayloads;
+
+ if (inFrame->m_userSEI.numPayloads)
{
- int numPayloads = inFrame->m_userSEI.numPayloads = pic_in->userSEI.numPayloads;
inFrame->m_userSEI.payloads = new x265_sei_payload[numPayloads];
for (int i = 0; i < numPayloads; i++)
{
- int size = inFrame->m_userSEI.payloads[i].payloadSize = pic_in->userSEI.payloads[i].payloadSize;
- inFrame->m_userSEI.payloads[i].payloadType = pic_in->userSEI.payloads[i].payloadType;
+ x265_sei_payload input;
+ if (i == (numPayloads - 1))
+ input = toneMap;
+ else
+ input = pic_in->userSEI.payloads[i];
+ int size = inFrame->m_userSEI.payloads[i].payloadSize = input.payloadSize;
+ inFrame->m_userSEI.payloads[i].payloadType = input.payloadType;
inFrame->m_userSEI.payloads[i].payload = new uint8_t[size];
- memcpy(inFrame->m_userSEI.payloads[i].payload, pic_in->userSEI.payloads[i].payload, size);
+ memcpy(inFrame->m_userSEI.payloads[i].payload, input.payload, size);
}
+ if (toneMap.payload)
+ x265_free(toneMap.payload);
}
if (pic_in->quantOffsets != NULL)
@@ -2198,6 +2226,28 @@
p->dynamicRd = 0;
x265_log(p, X265_LOG_WARNING, "Dynamic-rd disabled, requires RD <= 4, VBV and aq-mode enabled\n");
}
+#ifdef ENABLE_DYNAMIC_HDR10
+ if (m_param->toneMapFile)
+ {
+ if (!x265_fopen(p->toneMapFile, "r"))
+ {
+ x265_log(p, X265_LOG_WARNING, "Unable to open tone-map file. Disabling --dhdr10-info\n");
+ m_bToneMap = 0;
+ m_param->toneMapFile = NULL;
+ }
+ else
+ m_bToneMap = 1;
+ }
+ else
+ m_bToneMap = 0;
+#else
+ if (m_param->toneMapFile)
+ {
+ x265_log(p, X265_LOG_WARNING, "--dhdr10-info disabled. Enable dynamic HDR in cmake.\n");
+ m_bToneMap = 0;
+ m_param->toneMapFile = NULL;
+ }
+#endif
if (p->uhdBluray)
{
diff -r f0545a714a70 -r e2eb86dce7f4 source/encoder/encoder.h
--- a/source/encoder/encoder.h Wed Mar 22 14:33:20 2017 +0530
+++ b/source/encoder/encoder.h Wed Apr 19 16:36:59 2017 -0700
@@ -31,9 +31,9 @@
#include "x265.h"
#include "nal.h"
#include "framedata.h"
+#include "dynamicHDR10\hdr10plus.h"
struct x265_encoder {};
-
namespace X265_NS {
// private namespace
extern const char g_sliceTypeToChar[3];
@@ -172,10 +172,10 @@
/* For HDR*/
double m_cB;
double m_cR;
-
+ int m_bToneMap; // Enables tone-mapping
+ const hdr10plus_api* api;
Encoder();
~Encoder() {}
-
void create();
void stopJobs();
void destroy();
diff -r f0545a714a70 -r e2eb86dce7f4 source/encoder/frameencoder.cpp
--- a/source/encoder/frameencoder.cpp Wed Mar 22 14:33:20 2017 +0530
+++ b/source/encoder/frameencoder.cpp Wed Apr 19 16:36:59 2017 -0700
@@ -615,18 +615,31 @@
for (int i = 0; i < m_frame->m_userSEI.numPayloads; i++)
{
x265_sei_payload *payload = &m_frame->m_userSEI.payloads[i];
- SEIuserDataUnregistered sei;
+ if (payload->payloadType != USER_DATA_REGISTERED_ITU_T_T35)
+ {
+ SEIuserDataUnregistered sei;
+ sei.m_payloadType = payload->payloadType;
+ sei.m_userDataLength = payload->payloadSize;
+ sei.m_userData = payload->payload;
+ m_bs.resetBits();
+ sei.write(m_bs, *slice->m_sps);
+ m_bs.writeByteAlignment();
+ m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
+ }
+#if ENABLE_DYNAMIC_HDR10
+ else if (m_param->toneMapFile != NULL)
+ {
+ SEICreativeIntentMeta sei;
- sei.m_payloadType = payload->payloadType;
- sei.m_userDataLength = payload->payloadSize;
- sei.m_userData = payload->payload;
+ sei.cim = payload->payload;
- m_bs.resetBits();
- sei.write(m_bs, *slice->m_sps);
- m_bs.writeByteAlignment();
- m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
+ m_bs.resetBits();
+ sei.write(m_bs, *slice->m_sps);
+ m_bs.writeByteAlignment();
+ m_nalList.serialize(NAL_UNIT_PREFIX_SEI, m_bs);
+ }
+#endif
}
-
/* CQP and CRF (without capped VBV) doesn't use mid-frame statistics to
* tune RateControl parameters for other frames.
* Hence, for these modes, update m_startEndOrder and unlock RC for previous threads waiting in
diff -r f0545a714a70 -r e2eb86dce7f4 source/encoder/sei.h
--- a/source/encoder/sei.h Wed Mar 22 14:33:20 2017 +0530
+++ b/source/encoder/sei.h Wed Apr 19 16:36:59 2017 -0700
@@ -313,6 +313,43 @@
writeByteAlign();
}
};
+
+//seongnam.oh at samsung.com :: for the Creative Intent Meta Data Encoding
+class SEICreativeIntentMeta : public SEI
+{
+public:
+ uint8_t *cim;
+
+ SEIPayloadType payloadType() const { return USER_DATA_REGISTERED_ITU_T_T35; }
+
+ // daniel.vt at samsung.com :: for the Creative Intent Meta Data Encoding ( seongnam.oh at samsung.com )
+ void write(Bitstream& bs, const SPS&)
+ {
+ if (!cim)
+ {
+ return;
+ }
+
+ m_bitIf = &bs;
+ WRITE_CODE(USER_DATA_REGISTERED_ITU_T_T35, 8, "payload_type");
+ int i = 0;
+ int payloadSize = cim[0];
+ while (cim[i] == 0xFF)
+ {
+ i++;
+ payloadSize += cim[i];
+ WRITE_CODE(0xFF, 8, "payload_size");
+ }
+ WRITE_CODE((uint8_t)payloadSize, 8, "payload_size");
+ i++;
+ payloadSize += i;
+ for (; i < payloadSize; ++i)
+ {
+ WRITE_CODE(cim[i], 8, "creative_intent_metadata");
+ }
+
+ }
+};
+
}
-
#endif // ifndef X265_SEI_H
diff -r f0545a714a70 -r e2eb86dce7f4 source/x265.h
--- a/source/x265.h Wed Mar 22 14:33:20 2017 +0530
+++ b/source/x265.h Wed Apr 19 16:36:59 2017 -0700
@@ -1379,11 +1379,15 @@
* information stored/reused in save/load analysis-mode. Higher the refine
* level higher the informtion stored/reused. Default is 5 */
int analysisRefineLevel;
+
/* Limit Sample Adaptive Offset filter computation by early terminating SAO
* process based on inter prediction mode, CTU spatial-domain correlations,
* and relations between luma and chroma */
int bLimitSAO;
+ /* File containing the tone mapping information */
+ const char* toneMapFile;
+
} x265_param;
/* x265_param_alloc:
* Allocates an x265_param instance. The returned param structure is not
diff -r f0545a714a70 -r e2eb86dce7f4 source/x265cli.h
--- a/source/x265cli.h Wed Mar 22 14:33:20 2017 +0530
+++ b/source/x265cli.h Wed Apr 19 16:36:59 2017 -0700
@@ -268,6 +268,7 @@
{ "no-hdr-opt", no_argument, NULL, 0 },
{ "limit-sao", no_argument, NULL, 0 },
{ "no-limit-sao", no_argument, NULL, 0 },
+ { "dhdr10-info", required_argument, NULL, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 0, 0 },
@@ -313,6 +314,9 @@
H1(" 1 - i420 (4:2:0 default)\n");
H1(" 2 - i422 (4:2:2)\n");
H1(" 3 - i444 (4:4:4)\n");
+#if ENABLE_DYNAMIC_HDR10
+ H0(" --dhdr10-info <filename> JSON file containing the Creative Intent Metadata to be encoded as Dynamic Tone Mapping \n");
+#endif
H0("-f/--frames <integer> Maximum number of frames to encode. Default all\n");
H0(" --seek <integer> First frame to encode\n");
H1(" --[no-]interlace <bff|tff> Indicate input pictures are interlace fields in temporal order. Default progressive\n");
More information about the x265-devel
mailing list