Merge "mm-video-v4l2: raise onConfigUpdate Event on FBD"
diff --git a/mm-core/inc/OMX_Core.h b/mm-core/inc/OMX_Core.h
index 4a2f5db..6fa88c2 100644
--- a/mm-core/inc/OMX_Core.h
+++ b/mm-core/inc/OMX_Core.h
@@ -534,6 +534,20 @@
* fool-proof way to do that for video encoders.
*/
OMX_EventDataSpaceChanged,
+
+ /**
+ * Event when a component has an updated configuration on output for the client to retrieve.
+ * |arg1| contains the port index (currently only output port is valid). |arg2| contains the
+ * index of the updated config.
+ *
+ * For config updates that's associated with one frame, the update should be applied to the
+ * next output frame that comes in EmptyBufferDone callback.
+ *
+ * Upon receiving this event, the client must call the corresponding OMX_GetConfig to retrieve
+ * the config update.
+ */
+ OMX_EventConfigUpdate,
+
OMX_EventMax = 0x7FFFFFFF
} OMX_EVENTTYPE;
diff --git a/mm-core/inc/OMX_QCOMExtns.h b/mm-core/inc/OMX_QCOMExtns.h
index 6d9006d..39b82d8 100644
--- a/mm-core/inc/OMX_QCOMExtns.h
+++ b/mm-core/inc/OMX_QCOMExtns.h
@@ -705,6 +705,8 @@
OMX_QTIIndexParamNativeRecorder = 0x7F100008,
OMX_QTIIndexParamVideoDecoderOutputFrameRate = 0x7F100009,
+ /*"OMX.google.android.index.describeHDR10PlusInfo"*/
+ OMX_QTIIndexConfigDescribeHDR10PlusInfo = 0x7F10000a,
};
/**
diff --git a/mm-core/inc/OMX_VideoExt.h b/mm-core/inc/OMX_VideoExt.h
index db48d3c..1d372d2 100644
--- a/mm-core/inc/OMX_VideoExt.h
+++ b/mm-core/inc/OMX_VideoExt.h
@@ -164,6 +164,7 @@
// HDR profiles also support passing HDR metadata
OMX_VIDEO_VP9Profile2HDR = 0x1000,
OMX_VIDEO_VP9Profile3HDR = 0x2000,
+ OMX_VIDEO_VP9Profile2HDR10Plus = 0x4000,
OMX_VIDEO_VP9ProfileUnknown = 0x6EFFFFFF,
OMX_VIDEO_VP9ProfileMax = 0x7FFFFFFF
} OMX_VIDEO_VP9PROFILETYPE;
diff --git a/mm-video-v4l2/vidc/common/src/vidc_common.cpp b/mm-video-v4l2/vidc/common/src/vidc_common.cpp
index 0db59ee..464504c 100644
--- a/mm-video-v4l2/vidc/common/src/vidc_common.cpp
+++ b/mm-video-v4l2/vidc/common/src/vidc_common.cpp
@@ -78,6 +78,7 @@
pl_map profile_level_converter::profile_vp9_omx_to_v4l2 ({
{OMX_VIDEO_VP9Profile0, V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P0},
{OMX_VIDEO_VP9Profile2HDR, V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10},
+ {OMX_VIDEO_VP9Profile2HDR10Plus, V4L2_MPEG_VIDC_VIDEO_VP9_PROFILE_P2_10},
});
pl_map profile_level_converter::profile_vp9_v4l2_to_omx ({});
diff --git a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
index 689a637..05b1ce5 100644
--- a/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
+++ b/mm-video-v4l2/vidc/vdec/inc/omx_vdec.h
@@ -56,6 +56,7 @@
#include "media/hardware/HardwareAPI.h"
#include <unordered_map>
#include <media/msm_media_info.h>
+#include <list>
#include <linux/msm_ion.h>
#if TARGET_ION_ABI_VERSION >= 2
@@ -415,6 +416,18 @@
unsigned long fps_numerator;
};
+struct hdr10plusInfo {
+ bool is_new;
+ unsigned int cookie;
+ OMX_TICKS timestamp;
+ OMX_U32 nSize;
+ OMX_VERSIONTYPE nVersion;
+ OMX_U32 nPortIndex;
+ OMX_U32 nParamSize;
+ OMX_U32 nParamSizeUsed;
+ OMX_U8 payload[MAX_HDR10PLUSINFO_SIZE];
+};
+
#ifdef USE_ION
struct vdec_ion {
int dev_fd;
@@ -1103,6 +1116,9 @@
OMX_BUFFERHEADERTYPE *m_client_output_extradata_mem_ptr;
// number of input bitstream error frame count
unsigned int m_inp_err_count;
+
+ pthread_mutex_t m_hdr10pluslock;
+ std::list<hdr10plusInfo> m_hdr10pluslist;
#ifdef _ANDROID_
// Timestamp list
ts_arr_list m_timestamp_list;
@@ -1130,6 +1146,8 @@
// encapsulate the waiting states.
uint64_t m_flags;
+ OMX_U32 m_etb_count;
+ OMX_TICKS m_etb_timestamp;
// store I/P PORT state
OMX_BOOL m_inp_bEnabled;
// store O/P PORT state
@@ -1452,6 +1470,12 @@
void get_preferred_color_aspects(ColorAspects& preferredColorAspects);
void get_preferred_hdr_info(HDRStaticInfo& preferredHDRInfo);
bool vdec_query_cap(struct v4l2_queryctrl &cap);
+ bool store_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusinfo);
+ void update_hdr10plusinfo_cookie_using_timestamp(OMX_PTR cookie, OMX_TICKS timestamp);
+ void convert_hdr10plusinfo_to_metadata(OMX_PTR cookie, ColorMetaData &colorData);
+ void remove_hdr10plusinfo_using_cookie(OMX_PTR cookie);
+ void clear_hdr10plusinfo();
+ void get_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata);
public:
bool is_down_scalar_enabled;
bool m_is_split_mode;
diff --git a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
index cf2d0e5..09fea4b 100644
--- a/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
+++ b/mm-video-v4l2/vidc/vdec/src/omx_vdec_v4l2.cpp
@@ -152,6 +152,16 @@
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
+/*
+To enable sending vp9 hdr10plus metadata via private gralloc
+handle to display, define VP9_HDR10PLUS_GRALLOC_PATH_ENABLE
+as 1. This disables sending metadata via framework.
+To enable sending vp9 hdr10plus metadata via framework, define
+VP9_HDR10PLUS_GRALLOC_PATH_ENABLE as 0. This disables sending
+metadata via gralloc handle.
+*/
+#define VP9HDR10PLUS_SETMETADATA_ENABLE 1
+
using namespace android;
#ifdef HYPERVISOR
@@ -876,6 +886,7 @@
pthread_mutex_init(&m_lock, NULL);
pthread_mutex_init(&c_lock, NULL);
pthread_mutex_init(&buf_lock, NULL);
+ pthread_mutex_init(&m_hdr10pluslock, NULL);
sem_init(&m_cmd_lock,0,0);
sem_init(&m_safe_flush, 0, 0);
streaming[CAPTURE_PORT] =
@@ -921,6 +932,9 @@
m_dither_config = DITHER_DISABLE;
DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config);
+ m_etb_count = 0;
+ m_etb_timestamp = 0;
+
m_color_space = EXCEPT_BT2020;
init_color_aspects_map();
@@ -1046,9 +1060,11 @@
#else
close(drv_ctx.video_driver_fd);
#endif
+ clear_hdr10plusinfo();
pthread_mutex_destroy(&m_lock);
pthread_mutex_destroy(&c_lock);
pthread_mutex_destroy(&buf_lock);
+ pthread_mutex_destroy(&m_hdr10pluslock);
sem_destroy(&m_cmd_lock);
if (perf_flag) {
DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
@@ -1588,11 +1604,36 @@
if (p2 != VDEC_S_SUCCESS) {
DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
pThis->omx_report_error ();
- } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
+ break;
+ }
+ if (pThis->fill_buffer_done(&pThis->m_cmp,
(OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
DEBUG_PRINT_ERROR("fill_buffer_done failure");
pThis->omx_report_error ();
+ break;
}
+#if !VP9HDR10PLUS_SETMETADATA_ENABLE
+ if (pThis->output_capability != V4L2_PIX_FMT_VP9)
+ break;
+
+ if (!pThis->m_cb.EventHandler) {
+ DEBUG_PRINT_ERROR("fill_buffer_done: null event handler");
+ break;
+ }
+ bool is_list_empty;
+ is_list_empty = false;
+ pthread_mutex_lock(&pThis->m_hdr10pluslock);
+ is_list_empty = pThis->m_hdr10pluslist.empty();
+ pthread_mutex_unlock(&pThis->m_hdr10pluslock);
+ if (!is_list_empty) {
+ DEBUG_PRINT_LOW("fill_buffer_done: event config update");
+ pThis->m_cb.EventHandler(&pThis->m_cmp,
+ pThis->m_app_data,
+ OMX_EventConfigUpdate,
+ OMX_CORE_OUTPUT_PORT_INDEX,
+ OMX_QTIIndexConfigDescribeHDR10PlusInfo, NULL);
+ }
+#endif
break;
case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
@@ -3444,6 +3485,8 @@
pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
OMX_EventCmdComplete,OMX_CommandFlush,
OMX_CORE_INPUT_PORT_INDEX,NULL );
+ //clear hdr10plusinfo list upon input flush done
+ clear_hdr10plusinfo();
}
}
}
@@ -3533,9 +3576,10 @@
OMX_VIDEO_HEVCProfileMain10HDR10 };
int mpeg2_profiles[2] = { OMX_VIDEO_MPEG2ProfileSimple,
OMX_VIDEO_MPEG2ProfileMain};
- int vp9_profiles[3] = { OMX_VIDEO_VP9Profile0,
+ int vp9_profiles[4] = { OMX_VIDEO_VP9Profile0,
OMX_VIDEO_VP9Profile2,
- OMX_VIDEO_VP9Profile2HDR};
+ OMX_VIDEO_VP9Profile2HDR,
+ OMX_VIDEO_VP9Profile2HDR10Plus};
if (!profileLevelType)
return OMX_ErrorBadParameter;
@@ -5360,6 +5404,13 @@
break;
}
+ case OMX_QTIIndexConfigDescribeHDR10PlusInfo:
+ {
+ VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
+ DescribeHDR10PlusInfoParams *params = (DescribeHDR10PlusInfoParams *)configData;
+ get_hdr10plusinfo(params);
+ break;
+ }
case OMX_IndexConfigAndroidVendorExtension:
{
VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
@@ -5558,6 +5609,13 @@
memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams));
return ret;
+ } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDR10PlusInfo) {
+ VALIDATE_OMX_PARAM_DATA(configData, DescribeHDR10PlusInfoParams);
+ if (!store_hdr10plusinfo((DescribeHDR10PlusInfoParams *)configData)) {
+ DEBUG_PRINT_ERROR("Failed to set hdr10plus info");
+ }
+ return ret;
+
} else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) {
VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
@@ -5660,6 +5718,8 @@
*indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo;
} else if (extn_equals(paramName, "OMX.QTI.index.param.ClientConfiguredProfileLevel")) {
*indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamClientConfiguredProfileLevelForSufficiency;
+ } else if (extn_equals(paramName, "OMX.google.android.index.describeHDR10PlusInfo")) {
+ *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDR10PlusInfo;
}else {
DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
return OMX_ErrorNotImplemented;
@@ -7378,14 +7438,21 @@
buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
}
- DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
- buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
+ m_etb_count++;
+ //To handle wrap around case. m_etb_count++ to ensure value is non-zero.
+ if (!m_etb_count)
+ m_etb_count++;
+ m_etb_timestamp = buffer->nTimeStamp;
+ DEBUG_PRINT_LOW("[ETB] nCnt(%u) BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
+ m_etb_count, buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
+ buffer->pMarkData = (OMX_PTR)(unsigned long)m_etb_count;
if (arbitrary_bytes) {
post_event ((unsigned long)hComp,(unsigned long)buffer,
OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
} else {
post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
}
+
time_stamp_dts.insert_timestamp(buffer);
return OMX_ErrorNone;
}
@@ -7436,7 +7503,7 @@
/* return zero length and not an EOS buffer */
if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
- DEBUG_PRINT_HIGH("return zero legth buffer");
+ DEBUG_PRINT_HIGH("return zero length buffer");
post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
OMX_COMPONENT_GENERATE_EBD);
return OMX_ErrorNone;
@@ -7560,6 +7627,8 @@
buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
}
+ // update hdr10plusinfo list with cookie as pMarkData
+ update_hdr10plusinfo_cookie_using_timestamp(buffer->pMarkData, buffer->nTimeStamp);
OMX_ERRORTYPE eRet = OMX_ErrorNone;
buf.index = nPortIndex;
@@ -11521,6 +11590,10 @@
get_preferred_hdr_info(final_hdr_info);
convert_color_aspects_to_metadata(final_color_aspects, color_mdata);
convert_hdr_info_to_metadata(final_hdr_info, color_mdata);
+#if VP9HDR10PLUS_SETMETADATA_ENABLE
+ convert_hdr10plusinfo_to_metadata(p_buf_hdr->pMarkData, color_mdata);
+ remove_hdr10plusinfo_using_cookie(p_buf_hdr->pMarkData);
+#endif
print_debug_hdr_color_info_mdata(&color_mdata);
print_debug_hdr10plus_metadata(color_mdata);
set_colormetadata_in_handle(&color_mdata, buf_index);
@@ -13077,6 +13150,219 @@
return rc;
}
+bool omx_vdec::store_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
+{
+ struct hdr10plusInfo metadata;
+
+ if (!hdr10plusdata) {
+ DEBUG_PRINT_ERROR("hdr10plus info not present");
+ return false;
+ }
+
+ if (hdr10plusdata->nParamSize > MAX_HDR10PLUSINFO_SIZE ||
+ hdr10plusdata->nParamSize < 1) {
+ DEBUG_PRINT_ERROR("Invalid hdr10plus metadata size %u", hdr10plusdata->nParamSize);
+ return false;
+ }
+
+ if (output_capability != V4L2_PIX_FMT_VP9) {
+ DEBUG_PRINT_ERROR("DescribeHDR10PlusInfoParams is not supported for %d codec",
+ output_capability);
+ return false;
+ }
+
+ memset(&metadata, 0, sizeof(struct hdr10plusInfo));
+ metadata.nSize = hdr10plusdata->nSize;
+ metadata.nVersion = hdr10plusdata->nVersion;
+ metadata.nPortIndex = hdr10plusdata->nPortIndex;
+ metadata.nParamSize = hdr10plusdata->nParamSize;
+ metadata.nParamSizeUsed = hdr10plusdata->nParamSizeUsed;
+ memcpy(metadata.payload, hdr10plusdata->nValue , hdr10plusdata->nParamSizeUsed);
+ metadata.is_new = true;
+
+ /*
+ * For the first setconfig, set the timestamp as zero. For
+ * the remaining, set the timestamp equal to previous
+ * etb timestamp + 1 to know this hdr10plus data arrived
+ * after previous etb.
+ */
+ if (m_etb_count) {
+ metadata.timestamp = m_etb_timestamp + 1;
+ }
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ DEBUG_PRINT_LOW("add hdr10plus info to the list with timestamp %lld and size %u",
+ metadata.timestamp, metadata.nParamSizeUsed);
+ m_hdr10pluslist.push_back(metadata);
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ return true;
+}
+
+void omx_vdec::update_hdr10plusinfo_cookie_using_timestamp(OMX_PTR markdata, OMX_TICKS timestamp)
+{
+ std::list<hdr10plusInfo>::reverse_iterator iter;
+ unsigned int found = 0;
+ unsigned int cookie = (unsigned int)(unsigned long)markdata;
+ bool is_list_empty = false;
+
+ if (output_capability != V4L2_PIX_FMT_VP9)
+ return;
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ is_list_empty = m_hdr10pluslist.empty();
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ if (is_list_empty) {
+ DEBUG_PRINT_HIGH("update_hdr10plusinfo_cookie_using_timestamp: hdr10plusinfo list is empty!");
+ return;
+ }
+ /*
+ * look for the hdr10plus data which has timestamp nearest and
+ * lower than the etb timestamp, we should not take the
+ * hdr10plus data which has the timestamp greater than etb timestamp.
+ */
+ pthread_mutex_lock(&m_hdr10pluslock);
+ iter = m_hdr10pluslist.rbegin();
+ while (iter != m_hdr10pluslist.rend()) {
+ if (iter->timestamp <= timestamp && iter->is_new) {
+ found++;
+ if (found == 1) {
+ iter->cookie = cookie;
+ iter->is_new = false;
+ DEBUG_PRINT_LOW("Cookie value %u stored in hdr10plus list with timestamp %lld, size %u",
+ iter->cookie, iter->timestamp, iter->nParamSizeUsed);
+ }
+ }
+ iter++;
+ }
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ if(found > 1)
+ DEBUG_PRINT_HIGH("Multiple hdr10plus data not expected. Continue with the latest");
+}
+
+void omx_vdec::convert_hdr10plusinfo_to_metadata(OMX_PTR markdata, ColorMetaData &colorData)
+{
+ std::list<hdr10plusInfo>::iterator iter;
+ unsigned int cookie = (unsigned int)(unsigned long)markdata;
+ bool is_list_empty = false;
+
+ if (output_capability != V4L2_PIX_FMT_VP9)
+ return;
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ is_list_empty = m_hdr10pluslist.empty();
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ if (is_list_empty) {
+ DEBUG_PRINT_HIGH("convert_hdr10plusinfo_to_metadata: hdr10plusinfo list is empty!");
+ return;
+ }
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ iter = m_hdr10pluslist.begin();
+ while (iter != m_hdr10pluslist.end()) {
+ if (iter->cookie == cookie && !iter->is_new) {
+ colorData.dynamicMetaDataValid = true;
+ colorData.dynamicMetaDataLen = iter->nParamSizeUsed;
+ memcpy(colorData.dynamicMetaDataPayload, iter->payload,
+ iter->nParamSizeUsed);
+ DEBUG_PRINT_LOW("found hdr10plus metadata for cookie %u with timestamp %lld, size %u",
+ cookie, iter->timestamp, colorData.dynamicMetaDataLen);
+ break;
+ }
+ iter++;
+ }
+ pthread_mutex_unlock(&m_hdr10pluslock);
+}
+
+void omx_vdec::remove_hdr10plusinfo_using_cookie(OMX_PTR markdata)
+{
+ std::list<hdr10plusInfo>::iterator iter;
+ unsigned int cookie = (unsigned int)(unsigned long)markdata;
+ bool is_list_empty = false;
+
+ if (output_capability != V4L2_PIX_FMT_VP9)
+ return;
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ is_list_empty = m_hdr10pluslist.empty();
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ if (is_list_empty) {
+ DEBUG_PRINT_HIGH("remove_hdr10plusinfo_using_cookie: hdr10plusinfo list is empty!");
+ return;
+ }
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ iter = m_hdr10pluslist.begin();
+ while (iter != m_hdr10pluslist.end()) {
+ if (iter->cookie == cookie && !iter->is_new) {
+ iter = m_hdr10pluslist.erase(iter);
+ DEBUG_PRINT_LOW("removed hdr10plusinfo from the list for the cookie %u", cookie);
+ break;
+ }
+ iter++;
+ }
+ pthread_mutex_unlock(&m_hdr10pluslock);
+}
+
+void omx_vdec::clear_hdr10plusinfo()
+{
+ bool is_list_empty = false;
+
+ if (output_capability != V4L2_PIX_FMT_VP9)
+ return;
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ is_list_empty = m_hdr10pluslist.empty();
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ if (is_list_empty) {
+ DEBUG_PRINT_HIGH("clear_hdr10plusinfo: hdr10plusinfo list is empty!");
+ return;
+ }
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ m_hdr10pluslist.clear();
+ pthread_mutex_unlock(&m_hdr10pluslock);
+}
+
+void omx_vdec::get_hdr10plusinfo(DescribeHDR10PlusInfoParams *hdr10plusdata)
+{
+ std::list<hdr10plusInfo>::iterator iter;
+ bool is_list_empty = false;
+
+ if (output_capability != V4L2_PIX_FMT_VP9)
+ return;
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ is_list_empty = m_hdr10pluslist.empty();
+ pthread_mutex_unlock(&m_hdr10pluslock);
+
+ if (is_list_empty) {
+ DEBUG_PRINT_HIGH("get_hdr10plusinfo: hdr10plusinfo list is empty!");
+ return;
+ }
+
+ pthread_mutex_lock(&m_hdr10pluslock);
+ iter = m_hdr10pluslist.begin();
+ while (iter != m_hdr10pluslist.end()) {
+ if (!iter->is_new) {
+ hdr10plusdata->nParamSizeUsed = iter->nParamSizeUsed;
+ memcpy(hdr10plusdata->nValue, iter->payload,
+ iter->nParamSizeUsed);
+ DEBUG_PRINT_LOW("found hdr10plus metadata with timestamp %lld, size %u",
+ iter->timestamp, iter->nParamSizeUsed);
+ iter = m_hdr10pluslist.erase(iter);
+ break;
+ }
+ iter++;
+ }
+ pthread_mutex_unlock(&m_hdr10pluslock);
+}
+
// No code beyond this !
// inline import of vendor-extensions implementation