From 186a3a8d1370e886e07323e826f2765ec2f20d5b Mon Sep 17 00:00:00 2001 From: wenchangliu Date: Sat, 25 Mar 2023 09:15:08 +0000 Subject: videoapi: fix HDR10+ full metadata parsing issue Bug: 233398860 Test: run cts -m CtsMediaV2TestCases -t android.mediav2.cts.EncoderHDRInfoTest Test: run cts -m CtsMediaV2TestCases -t android.mediav2.cts.DecoderHDRInfoTest Test: run cts -m CtsMediaDecoderTestCases -t android.media.decoder.cts.HDRDecoderTest Change-Id: Ie6faa6f8c495223131a175763ebe47f08b16e203 Signed-off-by: wenchangliu --- videoapi/VendorVideoAPI.cpp | 139 +++++++++++++++++++++++++++----------------- 1 file changed, 85 insertions(+), 54 deletions(-) diff --git a/videoapi/VendorVideoAPI.cpp b/videoapi/VendorVideoAPI.cpp index 6e7f6ee..e439051 100644 --- a/videoapi/VendorVideoAPI.cpp +++ b/videoapi/VendorVideoAPI.cpp @@ -27,12 +27,12 @@ #define LOG_TAG "VendorVideoAPI" /* Check data boundary before read it */ -#define CHECK_BOUNDARY(bit_offset, size) { \ - if ((bit_offset) > (size) * 8) { \ - ALOGE("[%s] read bit offset(%d) > total bits(%d)", \ - __func__, (bit_offset), (size) * 8); \ - return -1; \ - } \ +#define CHECK_BOUNDARY(bit_offset, size) { \ + if ((bit_offset) > (size) * 8) { \ + ALOGE("[%s][%d] read bit offset(%d) > total bits(%d)", \ + __func__, __LINE__, (bit_offset), (size) * 8); \ + return -1; \ + } \ } #include @@ -155,7 +155,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -178,7 +178,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -201,7 +201,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -224,7 +224,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -247,7 +247,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -270,7 +270,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -293,7 +293,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 1) + if (j < 1 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -316,7 +316,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -339,7 +339,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -362,7 +362,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 2 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -434,7 +434,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j))); } - if (i < 1) + if (i < 1 + extraByte - 1) data = data << 8; extraBit += (j - extraBit); @@ -458,7 +458,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j))); } - if (i < 1) + if (i < 1 + extraByte - 1) data = data << 8; extraBit += (j - extraBit); @@ -475,7 +475,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( for (i = 0; i < num_rows_targeted_system_display_actual_peak_luminance; i++) { for (j = 0; j < num_cols_targeted_system_display_actual_peak_luminance; j++) { CHECK_BOUNDARY(bit_offset + 4, size); - /* mastering_display_actual_peak_luminance : 4bit */ + /* targeted_system_display_actual_peak_luminance : 4bit */ if (extraBit > 4) extraByte = 1; @@ -484,7 +484,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l))); } - if (k < 1) + if (k < 1 + extraByte - 1) data = data << 8; extraBit += (l - extraBit); @@ -494,7 +494,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( extraByte = 0; extraBit = bit_offset % 8; data = (extraBit != 0) ? (data >> (8 - extraBit)) : data; - pHdr10PlusInfo->data.mastering_display_actual_peak_luminance[i][j] = data; + pHdr10PlusInfo->data.targeted_system_display_actual_peak_luminance[i][j] = data; data = 0; } } @@ -502,6 +502,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( for (i = 0; i < pHdr10PlusInfo->data.num_windows; i++) { for (j = 0; j < 3; j++) { + CHECK_BOUNDARY(bit_offset + 17, size); /* maxscl : 17bit */ for (k = 0; k < 3; k++) { for (l = extraBit; l < 8; l++) { @@ -524,6 +525,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; } + CHECK_BOUNDARY(bit_offset + 17, size); /* average_maxrgb : 17bit */ for (j = 0; j < 3; j++) { for (k = extraBit; k < 8; k++) { @@ -542,6 +544,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( pHdr10PlusInfo->data.average_maxrgb[i] = data; data = 0; + CHECK_BOUNDARY(bit_offset + 4, size); /* num_distribution_maxrgb_percentiles : 4bit */ if (extraBit > 4) extraByte = 1; @@ -551,10 +554,8 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (extraByte > 0) { - if (j < 1) - data = data << 8; - } + if (j < 1 + extraByte - 1) + data = data << 8; extraBit += (k - extraBit); extraBit %= 8; @@ -567,6 +568,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; for (j = 0; j < pHdr10PlusInfo->data.num_maxrgb_percentiles[i]; j++) { + CHECK_BOUNDARY(bit_offset + 7, size); /* distribution_maxrgb_percentages : 7bit */ if (extraBit > 1) extraByte = 1; @@ -576,7 +578,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l))); } - if (k < 1) + if (k < 1 + extraByte - 1) data = data << 8; extraBit += (l - extraBit); @@ -589,6 +591,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( pHdr10PlusInfo->data.maxrgb_percentages[i][j] = data; data = 0; + CHECK_BOUNDARY(bit_offset + 17, size); /* distribution_maxrgb_percentiles : 17bit */ if (extraBit >= 0) extraByte = 1; @@ -598,7 +601,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l))); } - if (k < 2) + if (k < 2 + extraByte - 1) data = data << 8; extraBit += (l - extraBit); @@ -612,6 +615,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; } + CHECK_BOUNDARY(bit_offset + 10, size); /* fraction_bright_pixels : 10bit*/ if (extraBit > 6) extraByte = 2; @@ -623,7 +627,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + j) & (1 << (7 - k))); } - if (j < 2) + if (j < 1 + extraByte - 1) data = data << 8; extraBit += (k - extraBit); @@ -637,6 +641,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; } + CHECK_BOUNDARY(bit_offset + 1, size); /* mastering_display_actual_peak_luminance_flag : 1bit */ data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit))); @@ -648,6 +653,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; if (mastering_display_actual_peak_luminance_flag) { + CHECK_BOUNDARY(bit_offset + 5, size); /* num_rows_mastering_display_actual_peak_luminance : 5bit */ if (extraBit > 3) extraByte = 1; @@ -657,7 +663,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j))); } - if (i < 1) + if (i < 1 + extraByte - 1) data = data << 8; extraBit += (j - extraBit); @@ -671,6 +677,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( num_rows_mastering_display_actual_peak_luminance = data; data = 0; + CHECK_BOUNDARY(bit_offset + 5, size); /* num_cols_mastering_display_actual_peak_luminance : 5bit */ if (extraBit > 3) extraByte = 1; @@ -680,7 +687,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + i) & (1 << (7 - j))); } - if (i < 1) + if (i < 1 + extraByte - 1) data = data << 8; extraBit += (j - extraBit); @@ -696,6 +703,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( for (i = 0; i < num_rows_mastering_display_actual_peak_luminance; i++) { for (j = 0; j < num_cols_mastering_display_actual_peak_luminance; j++) { + CHECK_BOUNDARY(bit_offset + 4, size); /* mastering_display_actual_peak_luminance : 4bit */ if (extraBit > 4) extraByte = 1; @@ -705,7 +713,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data |= (*((char *)src + (bit_offset / 8) + k) & (1 << (7 - l))); } - if (k < 1) + if (k < 1 + extraByte - 1) data = data << 8; extraBit += (l - extraBit); @@ -722,20 +730,22 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( } for (i = 0; i < pHdr10PlusInfo->data.num_windows; i++) { + CHECK_BOUNDARY(bit_offset + 1, size); /* tone_mapping_flag : 1bit */ data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit))); bit_offset += 1; extraBit = bit_offset % 8; - data = data >> (8 - extraBit); + data = (extraBit != 0) ? (data >> (8 - extraBit)) : data; pHdr10PlusInfo->data.tone_mapping.tone_mapping_flag[i] = data; data = 0; if (pHdr10PlusInfo->data.tone_mapping.tone_mapping_flag[i]) { + CHECK_BOUNDARY(bit_offset + 12, size); /* knee_point_x : 12bit */ - if (extraBit > 5) + if (extraBit > 4) extraByte = 2; - else if (extraBit <= 5) + else if (extraBit <= 4) extraByte = 1; for (j = 0; j < 1 + extraByte; j++) { @@ -756,10 +766,11 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( pHdr10PlusInfo->data.tone_mapping.knee_point_x[i] = data; data = 0; + CHECK_BOUNDARY(bit_offset + 12, size); /* knee_point_y : 12bit */ - if (extraBit > 5) + if (extraBit > 4) extraByte = 2; - else if (extraBit <= 5) + else if (extraBit <= 4) extraByte = 1; for (j = 0; j < 1 + extraByte; j++) { @@ -780,6 +791,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( pHdr10PlusInfo->data.tone_mapping.knee_point_y[i] = data; data = 0; + CHECK_BOUNDARY(bit_offset + 4, size); /* num_bezier_curve_anchors : 4bit */ if (extraBit > 4) extraByte = 1; @@ -803,6 +815,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; for (j = 0; j < pHdr10PlusInfo->data.tone_mapping.num_bezier_curve_anchors[i]; j++) { + CHECK_BOUNDARY(bit_offset + 10, size); /* bezier_curve_anchors : 10bit */ if (extraBit > 6) extraByte = 2; @@ -829,6 +842,7 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( } } + CHECK_BOUNDARY(bit_offset + 1, size); /* color_saturation_mapping_flag : 1bit */ data |= (*((char *)src + (bit_offset / 8)) & (1 << (7 - extraBit))); @@ -840,8 +854,9 @@ int Exynos_parsing_user_data_registered_itu_t_t35 ( data = 0; if (pHdr10PlusInfo->data.color_saturation_mapping_flag[i]) { + CHECK_BOUNDARY(bit_offset + 6, size); /* color_saturation_weight : 6bit */ - if (extraBit > 3) + if (extraBit > 2) extraByte = 1; for (j = 0; j < 1 + extraByte; j++) { @@ -1249,7 +1264,12 @@ int Exynos_dynamic_meta_to_itu_t_t35 ( extraByte = 0; /* overlap_process_option: 1bit */ + if (pHDRDynamicInfo->data.overlap_process_option[i - 1]) { + *((char *)pBlob + (bit_offset / 8)) |= (1 << (7 - extraBit)); + } + bit_offset += 1; + extraBit = (bit_offset % 8); } /* targeted_system_display_maximum_luminance: 27bit */ @@ -1416,16 +1436,27 @@ int Exynos_dynamic_meta_to_itu_t_t35 ( /* num_distribution_maxrgb_percentiles: 4bit */ offset_limit = bit_offset + 4; - tempBuffer = pHDRDynamicInfo->data.num_maxrgb_percentiles[i] << (4 - extraBit); - for (j = extraBit; j < 8; j++) { - *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&tempBuffer) & (1 << (7 - j))); - bit_offset++; + if (extraBit > 4) + extraByte = 1; - if (bit_offset == offset_limit) - break; + tempBuffer = pHDRDynamicInfo->data.num_maxrgb_percentiles[i] << (28 - extraBit); + for (j = 0; j < 4; j++) { + memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char)); } - extraBit = (bit_offset % 8); + + for (j = 0; j < (1 + extraByte); j++) { + for (k = extraBit; k < 8; k++) { + *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k))); + bit_offset++; + + if (bit_offset == offset_limit) + break; + } + extraBit = (bit_offset % 8); + } + buffer = 0; tempBuffer = 0; + extraByte = 0; for (j = 0; j < pHDRDynamicInfo->data.num_maxrgb_percentiles[i]; j++) { /* distribution_maxrgb_percentaged: 7bit */ @@ -1729,20 +1760,20 @@ int Exynos_dynamic_meta_to_itu_t_t35 ( if (pHDRDynamicInfo->data.color_saturation_mapping_flag[i]) { /* color_saturation_weight: 6bit */ - offset_limit = bit_offset + 5; - - if (extraBit > 3) + if (extraBit > 2) extraByte = 1; - tempBuffer = pHDRDynamicInfo->data.num_rows_targeted_system_display_actual_peak_luminance; - tempBuffer = tempBuffer << (27 - extraBit); - for (i = 0; i < 4; i++) { - memcpy((char *)&buffer + i, (char *)&tempBuffer + (3 - i), sizeof(char)); + offset_limit = bit_offset + 6; + + tempBuffer = pHDRDynamicInfo->data.color_saturation_weight[i]; + tempBuffer = tempBuffer << (26 - extraBit); + for (j = 0; j < 4; j++) { + memcpy((char *)&buffer + j, (char *)&tempBuffer + (3 - j), sizeof(char)); } - for (i = 0; i < (1 + extraByte); i++) { - for (j = extraBit; j < 8; j++) { - *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + i) & (1 << (7 - j))); + for (j = 0; j < (1 + extraByte); j++) { + for (k = extraBit; k < 8; k++) { + *((char *)pBlob + (bit_offset / 8)) |= (*((char *)&buffer + j) & (1 << (7 - k))); bit_offset++; if (bit_offset == offset_limit) { -- cgit v1.2.3