ColorUtils.cpp revision 58fb7c6e1a9244dd7215a647388c440d8d75851b
1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18#define LOG_TAG "ColorUtils" 19 20#include <inttypes.h> 21 22#include <media/stagefright/foundation/ADebug.h> 23#include <media/stagefright/foundation/ALookup.h> 24#include <media/stagefright/foundation/ColorUtils.h> 25 26namespace android { 27 28// shortcut names for brevity in the following tables 29typedef ColorAspects CA; 30typedef ColorUtils CU; 31 32const static 33ALookup<CU::ColorRange, CA::Range> sRanges{ 34 { 35 { CU::kColorRangeLimited, CA::RangeLimited }, 36 { CU::kColorRangeFull, CA::RangeFull }, 37 { CU::kColorRangeUnspecified, CA::RangeUnspecified }, 38 } 39}; 40 41const static 42ALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandards { 43 { 44 { CU::kColorStandardUnspecified, { CA::PrimariesUnspecified, CA::MatrixUnspecified } }, 45 { CU::kColorStandardBT709, { CA::PrimariesBT709_5, CA::MatrixBT709_5 } }, 46 { CU::kColorStandardBT601_625, { CA::PrimariesBT601_6_625, CA::MatrixBT601_6 } }, 47 { CU::kColorStandardBT601_625_Unadjusted, 48 // this is a really close match 49 { CA::PrimariesBT601_6_625, CA::MatrixBT709_5 } }, 50 { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT601_6 } }, 51 { CU::kColorStandardBT601_525_Unadjusted, 52 { CA::PrimariesBT601_6_525, CA::MatrixSMPTE240M } }, 53 { CU::kColorStandardBT2020, { CA::PrimariesBT2020, CA::MatrixBT2020 } }, 54 { CU::kColorStandardBT2020Constant, { CA::PrimariesBT2020, CA::MatrixBT2020Constant } }, 55 { CU::kColorStandardBT470M, { CA::PrimariesBT470_6M, CA::MatrixBT470_6M } }, 56 // NOTE: there is no close match to the matrix used by standard film, chose closest 57 { CU::kColorStandardFilm, { CA::PrimariesGenericFilm, CA::MatrixBT2020 } }, 58 } 59}; 60 61const static 62ALookup<CU::ColorTransfer, CA::Transfer> sTransfers{ 63 { 64 { CU::kColorTransferUnspecified, CA::TransferUnspecified }, 65 { CU::kColorTransferLinear, CA::TransferLinear }, 66 { CU::kColorTransferSRGB, CA::TransferSRGB }, 67 { CU::kColorTransferSMPTE_170M, CA::TransferSMPTE170M }, 68 { CU::kColorTransferGamma22, CA::TransferGamma22 }, 69 { CU::kColorTransferGamma28, CA::TransferGamma28 }, 70 { CU::kColorTransferST2084, CA::TransferST2084 }, 71 { CU::kColorTransferHLG, CA::TransferHLG }, 72 } 73}; 74 75static bool isValid(ColorAspects::Primaries p) { 76 return p <= ColorAspects::PrimariesOther; 77} 78 79static bool isDefined(ColorAspects::Primaries p) { 80 return p <= ColorAspects::PrimariesBT2020; 81} 82 83static bool isValid(ColorAspects::MatrixCoeffs c) { 84 return c <= ColorAspects::MatrixOther; 85} 86 87static bool isDefined(ColorAspects::MatrixCoeffs c) { 88 return c <= ColorAspects::MatrixBT2020Constant; 89} 90 91//static 92int32_t ColorUtils::wrapColorAspectsIntoColorStandard( 93 ColorAspects::Primaries primaries, ColorAspects::MatrixCoeffs coeffs) { 94 ColorStandard res; 95 if (sStandards.map(std::make_pair(primaries, coeffs), &res)) { 96 return res; 97 } else if (!isValid(primaries) || !isValid(coeffs)) { 98 return kColorStandardUnspecified; 99 } 100 101 // check platform media limits 102 uint32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1; 103 if (isDefined(primaries) && isDefined(coeffs)) { 104 return kColorStandardExtendedStart + primaries + coeffs * numPrimaries; 105 } else { 106 return kColorStandardVendorStart + primaries + coeffs * 0x100; 107 } 108} 109 110//static 111status_t ColorUtils::unwrapColorAspectsFromColorStandard( 112 int32_t standard, 113 ColorAspects::Primaries *primaries, ColorAspects::MatrixCoeffs *coeffs) { 114 std::pair<ColorAspects::Primaries, ColorAspects::MatrixCoeffs> res; 115 if (sStandards.map((ColorStandard)standard, &res)) { 116 *primaries = res.first; 117 *coeffs = res.second; 118 return OK; 119 } 120 121 int32_t start = kColorStandardExtendedStart; 122 int32_t numPrimaries = ColorAspects::PrimariesBT2020 + 1; 123 int32_t numCoeffs = ColorAspects::MatrixBT2020Constant + 1; 124 if (standard >= (int32_t)kColorStandardVendorStart) { 125 start = kColorStandardVendorStart; 126 numPrimaries = ColorAspects::PrimariesOther + 1; // 0x100 127 numCoeffs = ColorAspects::MatrixOther + 1; // 0x100; 128 } 129 if (standard >= start && standard < start + numPrimaries * numCoeffs) { 130 int32_t product = standard - start; 131 *primaries = (ColorAspects::Primaries)(product % numPrimaries); 132 *coeffs = (ColorAspects::MatrixCoeffs)(product / numPrimaries); 133 return OK; 134 } 135 *primaries = ColorAspects::PrimariesOther; 136 *coeffs = ColorAspects::MatrixOther; 137 return BAD_VALUE; 138} 139 140static bool isValid(ColorAspects::Range r) { 141 return r <= ColorAspects::RangeOther; 142} 143 144static bool isDefined(ColorAspects::Range r) { 145 return r <= ColorAspects::RangeLimited; 146} 147 148// static 149int32_t ColorUtils::wrapColorAspectsIntoColorRange(ColorAspects::Range range) { 150 ColorRange res; 151 if (sRanges.map(range, &res)) { 152 return res; 153 } else if (!isValid(range)) { 154 return kColorRangeUnspecified; 155 } else { 156 CHECK(!isDefined(range)); 157 // all platform values are in sRanges 158 return kColorRangeVendorStart + range; 159 } 160} 161 162//static 163status_t ColorUtils::unwrapColorAspectsFromColorRange( 164 int32_t range, ColorAspects::Range *aspect) { 165 if (sRanges.map((ColorRange)range, aspect)) { 166 return OK; 167 } 168 169 int32_t start = kColorRangeVendorStart; 170 int32_t numRanges = ColorAspects::RangeOther + 1; // 0x100 171 if (range >= start && range < start + numRanges) { 172 *aspect = (ColorAspects::Range)(range - start); 173 return OK; 174 } 175 *aspect = ColorAspects::RangeOther; 176 return BAD_VALUE; 177} 178 179static bool isValid(ColorAspects::Transfer t) { 180 return t <= ColorAspects::TransferOther; 181} 182 183static bool isDefined(ColorAspects::Transfer t) { 184 return t <= ColorAspects::TransferHLG 185 || (t >= ColorAspects::TransferSMPTE240M && t <= ColorAspects::TransferST428); 186} 187 188// static 189int32_t ColorUtils::wrapColorAspectsIntoColorTransfer( 190 ColorAspects::Transfer transfer) { 191 ColorTransfer res; 192 if (sTransfers.map(transfer, &res)) { 193 return res; 194 } else if (!isValid(transfer)) { 195 return kColorTransferUnspecified; 196 } else if (isDefined(transfer)) { 197 return kColorTransferExtendedStart + transfer; 198 } else { 199 // all platform values are in sRanges 200 return kColorTransferVendorStart + transfer; 201 } 202} 203 204//static 205status_t ColorUtils::unwrapColorAspectsFromColorTransfer( 206 int32_t transfer, ColorAspects::Transfer *aspect) { 207 if (sTransfers.map((ColorTransfer)transfer, aspect)) { 208 return OK; 209 } 210 211 int32_t start = kColorTransferExtendedStart; 212 int32_t numTransfers = ColorAspects::TransferST428 + 1; 213 if (transfer >= (int32_t)kColorTransferVendorStart) { 214 start = kColorTransferVendorStart; 215 numTransfers = ColorAspects::TransferOther + 1; // 0x100 216 } 217 if (transfer >= start && transfer < start + numTransfers) { 218 *aspect = (ColorAspects::Transfer)(transfer - start); 219 return OK; 220 } 221 *aspect = ColorAspects::TransferOther; 222 return BAD_VALUE; 223} 224 225// static 226status_t ColorUtils::convertPlatformColorAspectsToCodecAspects( 227 int32_t range, int32_t standard, int32_t transfer, ColorAspects &aspects) { 228 status_t res1 = unwrapColorAspectsFromColorRange(range, &aspects.mRange); 229 status_t res2 = unwrapColorAspectsFromColorStandard( 230 standard, &aspects.mPrimaries, &aspects.mMatrixCoeffs); 231 status_t res3 = unwrapColorAspectsFromColorTransfer(transfer, &aspects.mTransfer); 232 return res1 != OK ? res1 : (res2 != OK ? res2 : res3); 233} 234 235// static 236status_t ColorUtils::convertCodecColorAspectsToPlatformAspects( 237 const ColorAspects &aspects, int32_t *range, int32_t *standard, int32_t *transfer) { 238 *range = wrapColorAspectsIntoColorRange(aspects.mRange); 239 *standard = wrapColorAspectsIntoColorStandard(aspects.mPrimaries, aspects.mMatrixCoeffs); 240 *transfer = wrapColorAspectsIntoColorTransfer(aspects.mTransfer); 241 if (isValid(aspects.mRange) && isValid(aspects.mPrimaries) 242 && isValid(aspects.mMatrixCoeffs) && isValid(aspects.mTransfer)) { 243 return OK; 244 } else { 245 return BAD_VALUE; 246 } 247} 248 249const static 250ALookup<int32_t, ColorAspects::Primaries> sIsoPrimaries { 251 { 252 { 1, ColorAspects::PrimariesBT709_5 }, 253 { 2, ColorAspects::PrimariesUnspecified }, 254 { 4, ColorAspects::PrimariesBT470_6M }, 255 { 5, ColorAspects::PrimariesBT601_6_625 }, 256 { 6, ColorAspects::PrimariesBT601_6_525 /* main */}, 257 { 7, ColorAspects::PrimariesBT601_6_525 }, 258 // -- ITU T.832 201201 ends here 259 { 8, ColorAspects::PrimariesGenericFilm }, 260 { 9, ColorAspects::PrimariesBT2020 }, 261 { 10, ColorAspects::PrimariesOther /* XYZ */ }, 262 } 263}; 264 265const static 266ALookup<int32_t, ColorAspects::Transfer> sIsoTransfers { 267 { 268 { 1, ColorAspects::TransferSMPTE170M /* main */}, 269 { 2, ColorAspects::TransferUnspecified }, 270 { 4, ColorAspects::TransferGamma22 }, 271 { 5, ColorAspects::TransferGamma28 }, 272 { 6, ColorAspects::TransferSMPTE170M }, 273 { 7, ColorAspects::TransferSMPTE240M }, 274 { 8, ColorAspects::TransferLinear }, 275 { 9, ColorAspects::TransferOther /* log 100:1 */ }, 276 { 10, ColorAspects::TransferOther /* log 316:1 */ }, 277 { 11, ColorAspects::TransferXvYCC }, 278 { 12, ColorAspects::TransferBT1361 }, 279 { 13, ColorAspects::TransferSRGB }, 280 // -- ITU T.832 201201 ends here 281 { 14, ColorAspects::TransferSMPTE170M }, 282 { 15, ColorAspects::TransferSMPTE170M }, 283 { 16, ColorAspects::TransferST2084 }, 284 { 17, ColorAspects::TransferST428 }, 285 } 286}; 287 288const static 289ALookup<int32_t, ColorAspects::MatrixCoeffs> sIsoMatrixCoeffs { 290 { 291 { 0, ColorAspects::MatrixOther }, 292 { 1, ColorAspects::MatrixBT709_5 }, 293 { 2, ColorAspects::MatrixUnspecified }, 294 { 4, ColorAspects::MatrixBT470_6M }, 295 { 6, ColorAspects::MatrixBT601_6 /* main */ }, 296 { 5, ColorAspects::MatrixBT601_6 }, 297 { 7, ColorAspects::MatrixSMPTE240M }, 298 { 8, ColorAspects::MatrixOther /* YCgCo */ }, 299 // -- ITU T.832 201201 ends here 300 { 9, ColorAspects::MatrixBT2020 }, 301 { 10, ColorAspects::MatrixBT2020Constant }, 302 } 303}; 304 305// static 306void ColorUtils::convertCodecColorAspectsToIsoAspects( 307 const ColorAspects &aspects, 308 int32_t *primaries, int32_t *transfer, int32_t *coeffs, bool *fullRange) { 309 if (aspects.mPrimaries == ColorAspects::PrimariesOther || 310 !sIsoPrimaries.map(aspects.mPrimaries, primaries)) { 311 CHECK(sIsoPrimaries.map(ColorAspects::PrimariesUnspecified, primaries)); 312 } 313 if (aspects.mTransfer == ColorAspects::TransferOther || 314 !sIsoTransfers.map(aspects.mTransfer, transfer)) { 315 CHECK(sIsoTransfers.map(ColorAspects::TransferUnspecified, transfer)); 316 } 317 if (aspects.mMatrixCoeffs == ColorAspects::MatrixOther || 318 !sIsoMatrixCoeffs.map(aspects.mMatrixCoeffs, coeffs)) { 319 CHECK(sIsoMatrixCoeffs.map(ColorAspects::MatrixUnspecified, coeffs)); 320 } 321 *fullRange = aspects.mRange == ColorAspects::RangeFull; 322} 323 324// static 325void ColorUtils::convertIsoColorAspectsToCodecAspects( 326 int32_t primaries, int32_t transfer, int32_t coeffs, bool fullRange, 327 ColorAspects &aspects) { 328 if (!sIsoPrimaries.map(primaries, &aspects.mPrimaries)) { 329 aspects.mPrimaries = ColorAspects::PrimariesUnspecified; 330 } 331 if (!sIsoTransfers.map(transfer, &aspects.mTransfer)) { 332 aspects.mTransfer = ColorAspects::TransferUnspecified; 333 } 334 if (!sIsoMatrixCoeffs.map(coeffs, &aspects.mMatrixCoeffs)) { 335 aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 336 } 337 aspects.mRange = fullRange ? ColorAspects::RangeFull : ColorAspects::RangeLimited; 338} 339 340// static 341void ColorUtils::setDefaultCodecColorAspectsIfNeeded( 342 ColorAspects &aspects, int32_t width, int32_t height) { 343 ColorAspects::MatrixCoeffs coeffs; 344 ColorAspects::Primaries primaries; 345 346 // Default to BT2020, BT709 or BT601 based on size. Allow 2.35:1 aspect ratio. Limit BT601 347 // to PAL or smaller, BT2020 to 4K or larger, leaving BT709 for all resolutions in between. 348 if (width >= 3840 || height >= 3840 || width * (int64_t)height >= 3840 * 1634) { 349 primaries = ColorAspects::PrimariesBT2020; 350 coeffs = ColorAspects::MatrixBT2020; 351 } else if ((width <= 720 && height > 480 && height <= 576) 352 || (height <= 720 && width > 480 && width <= 576)) { 353 primaries = ColorAspects::PrimariesBT601_6_625; 354 coeffs = ColorAspects::MatrixBT601_6; 355 } else if ((width <= 720 && height <= 480) || (height <= 720 && width <= 480)) { 356 primaries = ColorAspects::PrimariesBT601_6_525; 357 coeffs = ColorAspects::MatrixBT601_6; 358 } else { 359 primaries = ColorAspects::PrimariesBT709_5; 360 coeffs = ColorAspects::MatrixBT709_5; 361 } 362 363 if (aspects.mRange == ColorAspects::RangeUnspecified) { 364 aspects.mRange = ColorAspects::RangeLimited; 365 } 366 367 if (aspects.mPrimaries == ColorAspects::PrimariesUnspecified) { 368 aspects.mPrimaries = primaries; 369 } 370 if (aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified) { 371 aspects.mMatrixCoeffs = coeffs; 372 } 373 if (aspects.mTransfer == ColorAspects::TransferUnspecified) { 374 aspects.mTransfer = ColorAspects::TransferSMPTE170M; 375 } 376} 377 378// TODO: move this into a Video HAL 379ALookup<CU::ColorStandard, std::pair<CA::Primaries, CA::MatrixCoeffs>> sStandardFallbacks { 380 { 381 { CU::kColorStandardBT601_625, { CA::PrimariesBT709_5, CA::MatrixBT470_6M } }, 382 { CU::kColorStandardBT601_625, { CA::PrimariesBT709_5, CA::MatrixBT601_6 } }, 383 { CU::kColorStandardBT709, { CA::PrimariesBT709_5, CA::MatrixSMPTE240M } }, 384 { CU::kColorStandardBT709, { CA::PrimariesBT709_5, CA::MatrixBT2020 } }, 385 { CU::kColorStandardBT601_525, { CA::PrimariesBT709_5, CA::MatrixBT2020Constant } }, 386 387 { CU::kColorStandardBT2020Constant, 388 { CA::PrimariesBT470_6M, CA::MatrixBT2020Constant } }, 389 390 { CU::kColorStandardBT601_625, { CA::PrimariesBT601_6_625, CA::MatrixBT470_6M } }, 391 { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_625, CA::MatrixBT2020Constant } }, 392 393 { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT470_6M } }, 394 { CU::kColorStandardBT601_525, { CA::PrimariesBT601_6_525, CA::MatrixBT2020Constant } }, 395 396 { CU::kColorStandardBT2020Constant, 397 { CA::PrimariesGenericFilm, CA::MatrixBT2020Constant } }, 398 } 399}; 400 401ALookup<CU::ColorStandard, CA::Primaries> sStandardPrimariesFallbacks { 402 { 403 { CU::kColorStandardFilm, CA::PrimariesGenericFilm }, 404 { CU::kColorStandardBT470M, CA::PrimariesBT470_6M }, 405 { CU::kColorStandardBT2020, CA::PrimariesBT2020 }, 406 { CU::kColorStandardBT601_525_Unadjusted, CA::PrimariesBT601_6_525 }, 407 { CU::kColorStandardBT601_625_Unadjusted, CA::PrimariesBT601_6_625 }, 408 } 409}; 410 411static ALookup<android_dataspace, android_dataspace> sLegacyDataSpaceToV0 { 412 { 413 { HAL_DATASPACE_SRGB, HAL_DATASPACE_V0_SRGB }, 414 { HAL_DATASPACE_BT709, HAL_DATASPACE_V0_BT709 }, 415 { HAL_DATASPACE_SRGB_LINEAR, HAL_DATASPACE_V0_SRGB_LINEAR }, 416 { HAL_DATASPACE_BT601_525, HAL_DATASPACE_V0_BT601_525 }, 417 { HAL_DATASPACE_BT601_625, HAL_DATASPACE_V0_BT601_625 }, 418 { HAL_DATASPACE_JFIF, HAL_DATASPACE_V0_JFIF }, 419 } 420}; 421 422bool ColorUtils::convertDataSpaceToV0(android_dataspace &dataSpace) { 423 (void)sLegacyDataSpaceToV0.lookup(dataSpace, &dataSpace); 424 return (dataSpace & 0xC000FFFF) == 0; 425} 426 427bool ColorUtils::checkIfAspectsChangedAndUnspecifyThem( 428 ColorAspects &aspects, const ColorAspects &orig, bool usePlatformAspects) { 429 // remove changed aspects (change them to Unspecified) 430 bool changed = false; 431 if (aspects.mRange && aspects.mRange != orig.mRange) { 432 aspects.mRange = ColorAspects::RangeUnspecified; 433 changed = true; 434 } 435 if (aspects.mPrimaries && aspects.mPrimaries != orig.mPrimaries) { 436 aspects.mPrimaries = ColorAspects::PrimariesUnspecified; 437 if (usePlatformAspects) { 438 aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 439 } 440 changed = true; 441 } 442 if (aspects.mMatrixCoeffs && aspects.mMatrixCoeffs != orig.mMatrixCoeffs) { 443 aspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified; 444 if (usePlatformAspects) { 445 aspects.mPrimaries = ColorAspects::PrimariesUnspecified; 446 } 447 changed = true; 448 } 449 if (aspects.mTransfer && aspects.mTransfer != orig.mTransfer) { 450 aspects.mTransfer = ColorAspects::TransferUnspecified; 451 changed = true; 452 } 453 return changed; 454} 455 456// static 457android_dataspace ColorUtils::getDataSpaceForColorAspects(ColorAspects &aspects, bool mayExpand) { 458 // This platform implementation never expands color space (e.g. returns an expanded 459 // dataspace to use where the codec does in-the-background color space conversion) 460 mayExpand = false; 461 462 if (aspects.mRange == ColorAspects::RangeUnspecified 463 || aspects.mPrimaries == ColorAspects::PrimariesUnspecified 464 || aspects.mMatrixCoeffs == ColorAspects::MatrixUnspecified 465 || aspects.mTransfer == ColorAspects::TransferUnspecified) { 466 ALOGW("expected specified color aspects (%u:%u:%u:%u)", 467 aspects.mRange, aspects.mPrimaries, aspects.mMatrixCoeffs, aspects.mTransfer); 468 } 469 470 // default to video range and transfer 471 ColorRange range = kColorRangeLimited; 472 ColorTransfer transfer = kColorTransferSMPTE_170M; 473 (void)sRanges.map(aspects.mRange, &range); 474 (void)sTransfers.map(aspects.mTransfer, &transfer); 475 476 ColorStandard standard = kColorStandardBT709; 477 auto pair = std::make_pair(aspects.mPrimaries, aspects.mMatrixCoeffs); 478 if (!sStandards.map(pair, &standard)) { 479 if (!sStandardFallbacks.map(pair, &standard)) { 480 (void)sStandardPrimariesFallbacks.map(aspects.mPrimaries, &standard); 481 482 if (aspects.mMatrixCoeffs == ColorAspects::MatrixBT2020Constant) { 483 range = kColorRangeFull; 484 } 485 } 486 } 487 488 android_dataspace dataSpace = (android_dataspace)( 489 (range << HAL_DATASPACE_RANGE_SHIFT) | (standard << HAL_DATASPACE_STANDARD_SHIFT) | 490 (transfer << HAL_DATASPACE_TRANSFER_SHIFT)); 491 (void)sLegacyDataSpaceToV0.rlookup(dataSpace, &dataSpace); 492 493 if (!mayExpand) { 494 // update codec aspects based on dataspace 495 convertPlatformColorAspectsToCodecAspects(range, standard, transfer, aspects); 496 } 497 return dataSpace; 498} 499 500// static 501void ColorUtils::getColorConfigFromFormat( 502 const sp<AMessage> &format, int32_t *range, int32_t *standard, int32_t *transfer) { 503 if (!format->findInt32("color-range", range)) { 504 *range = kColorRangeUnspecified; 505 } 506 if (!format->findInt32("color-standard", standard)) { 507 *standard = kColorStandardUnspecified; 508 } 509 if (!format->findInt32("color-transfer", transfer)) { 510 *transfer = kColorTransferUnspecified; 511 } 512} 513 514// static 515void ColorUtils::copyColorConfig(const sp<AMessage> &source, sp<AMessage> &target) { 516 // 0 values are unspecified 517 int32_t value; 518 if (source->findInt32("color-range", &value)) { 519 target->setInt32("color-range", value); 520 } 521 if (source->findInt32("color-standard", &value)) { 522 target->setInt32("color-standard", value); 523 } 524 if (source->findInt32("color-transfer", &value)) { 525 target->setInt32("color-transfer", value); 526 } 527} 528 529// static 530void ColorUtils::getColorAspectsFromFormat(const sp<AMessage> &format, ColorAspects &aspects) { 531 int32_t range, standard, transfer; 532 getColorConfigFromFormat(format, &range, &standard, &transfer); 533 534 if (convertPlatformColorAspectsToCodecAspects( 535 range, standard, transfer, aspects) != OK) { 536 ALOGW("Ignoring illegal color aspects(R:%d(%s), S:%d(%s), T:%d(%s))", 537 range, asString((ColorRange)range), 538 standard, asString((ColorStandard)standard), 539 transfer, asString((ColorTransfer)transfer)); 540 // Invalid values were converted to unspecified !params!, but otherwise were not changed 541 // For encoders, we leave these as is. For decoders, we will use default values. 542 } 543 ALOGV("Got color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 544 "from format (out:R:%d(%s), S:%d(%s), T:%d(%s))", 545 aspects.mRange, asString(aspects.mRange), 546 aspects.mPrimaries, asString(aspects.mPrimaries), 547 aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 548 aspects.mTransfer, asString(aspects.mTransfer), 549 range, asString((ColorRange)range), 550 standard, asString((ColorStandard)standard), 551 transfer, asString((ColorTransfer)transfer)); 552} 553 554// static 555void ColorUtils::setColorAspectsIntoFormat( 556 const ColorAspects &aspects, sp<AMessage> &format, bool force) { 557 int32_t range = 0, standard = 0, transfer = 0; 558 convertCodecColorAspectsToPlatformAspects(aspects, &range, &standard, &transfer); 559 // save set values to base output format 560 // (encoder input format will read back actually supported values by the codec) 561 if (range != 0 || force) { 562 format->setInt32("color-range", range); 563 } 564 if (standard != 0 || force) { 565 format->setInt32("color-standard", standard); 566 } 567 if (transfer != 0 || force) { 568 format->setInt32("color-transfer", transfer); 569 } 570 ALOGV("Setting color aspects (R:%d(%s), P:%d(%s), M:%d(%s), T:%d(%s)) " 571 "into format (out:R:%d(%s), S:%d(%s), T:%d(%s))", 572 aspects.mRange, asString(aspects.mRange), 573 aspects.mPrimaries, asString(aspects.mPrimaries), 574 aspects.mMatrixCoeffs, asString(aspects.mMatrixCoeffs), 575 aspects.mTransfer, asString(aspects.mTransfer), 576 range, asString((ColorRange)range), 577 standard, asString((ColorStandard)standard), 578 transfer, asString((ColorTransfer)transfer)); 579} 580 581} // namespace android 582 583