Loading include/media/stagefright/MetaData.h +1 −2 Original line number Diff line number Diff line Loading @@ -194,8 +194,7 @@ enum { kKeyNalLengthSize = 'nals', // int32_t // HDR related kKeyMinLuminance = 'minL', // int32_t, min luminance of the content in cd/m2. kKeyMaxLuminance = 'maxL', // int32_t, max luminance of the content in cd/m2. kKeyHdrStaticInfo = 'hdrS', // HDRStaticInfo // color aspects kKeyColorRange = 'cRng', // int32_t, color range, value defined by ColorAspects.Range Loading media/libstagefright/Utils.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_ return OK; } #if 0 static void convertMetaDataToMessageInt32( const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) { int32_t value; Loading @@ -103,6 +104,7 @@ static void convertMetaDataToMessageInt32( msg->setInt32(name, value); } } #endif static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) { // 0 values are unspecified Loading Loading @@ -631,8 +633,14 @@ status_t convertMetaDataToMessage( msg->setInt32("rotation-degrees", rotationDegrees); } convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance"); convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance"); uint32_t type; const void *data; size_t size; if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size) && type == 'hdrS' && size == sizeof(HDRStaticInfo)) { ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg); } convertMetaDataToMessageColorAspects(meta, msg); } else if (!strncasecmp("audio/", mime, 6)) { int32_t numChannels, sampleRate; Loading Loading @@ -1146,6 +1154,7 @@ static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvcc return size; } #if 0 static void convertMessageToMetaDataInt32( const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) { int32_t value; Loading @@ -1153,6 +1162,7 @@ static void convertMessageToMetaDataInt32( meta->setInt32(key, value); } } #endif static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) { // 0 values are unspecified Loading Loading @@ -1237,8 +1247,13 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { meta->setInt32(kKeyRotation, rotationDegrees); } convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance"); convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance"); if (msg->contains("hdr-static-info")) { HDRStaticInfo info; if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) { meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); } } convertMessageToMetaDataColorAspects(msg, meta); } else if (mime.startsWith("audio/")) { int32_t numChannels; Loading media/libstagefright/matroska/MatroskaExtractor.cpp +107 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/DataSource.h> #include <media/stagefright/MediaBuffer.h> Loading Loading @@ -1058,6 +1059,109 @@ status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { return OK; } static inline bool isValidInt32ColourValue(long long value) { return value != mkvparser::Colour::kValueNotPresent && value >= INT32_MIN && value <= INT32_MAX; } static inline bool isValidUint16ColourValue(long long value) { return value != mkvparser::Colour::kValueNotPresent && value >= 0 && value <= UINT16_MAX; } static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) { return primary != NULL && primary->x >= 0 && primary->x <= 1 && primary->y >= 0 && primary->y <= 1; } void MatroskaExtractor::getColorInformation( const mkvparser::VideoTrack *vtrack, sp<MetaData> &meta) { const mkvparser::Colour *color = vtrack->GetColour(); if (color == NULL) { return; } // Color Aspects { int32_t primaries = 2; // ISO unspecified int32_t transfer = 2; // ISO unspecified int32_t coeffs = 2; // ISO unspecified bool fullRange = false; // default bool rangeSpecified = false; if (isValidInt32ColourValue(color->primaries)) { primaries = color->primaries; } if (isValidInt32ColourValue(color->transfer_characteristics)) { transfer = color->transfer_characteristics; } if (isValidInt32ColourValue(color->matrix_coefficients)) { coeffs = color->matrix_coefficients; } if (color->range != mkvparser::Colour::kValueNotPresent && color->range != 0 /* MKV unspecified */) { // We only support MKV broadcast range (== limited) and full range. // We treat all other value as the default limited range. fullRange = color->range == 2 /* MKV fullRange */; rangeSpecified = true; } ColorAspects aspects; ColorUtils::convertIsoColorAspectsToCodecAspects( primaries, transfer, coeffs, fullRange, aspects); meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); meta->setInt32(kKeyTransferFunction, aspects.mTransfer); meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); meta->setInt32( kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified); } // HDR Static Info { HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info memset(&info, 0, sizeof(info)); memset(&nullInfo, 0, sizeof(nullInfo)); if (isValidUint16ColourValue(color->max_cll)) { info.sType1.mMaxContentLightLevel = color->max_cll; } if (isValidUint16ColourValue(color->max_fall)) { info.sType1.mMaxFrameAverageLightLevel = color->max_fall; } const mkvparser::MasteringMetadata *mastering = color->mastering_metadata; if (mastering != NULL) { // Convert matroska values to HDRStaticInfo equivalent values for each fully specified // group. See CTA-681.3 section 3.2.1 for more info. if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) { info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5); } if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) { info.sType1.mMinDisplayLuminance = (uint16_t)(10000 * mastering->luminance_min + 0.5); } if (isValidPrimary(mastering->white_point)) { info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5); info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5); } if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g) && isValidPrimary(mastering->b)) { info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5); info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5); info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5); info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5); info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5); info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5); } } // Only advertise static info if at least one of the groups have been specified. if (memcmp(&info, &nullInfo, sizeof(info)) != 0) { info.mID = HDRStaticInfo::kType1; meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); } } } void MatroskaExtractor::addTracks() { const mkvparser::Tracks *tracks = mSegment->GetTracks(); Loading Loading @@ -1127,6 +1231,9 @@ void MatroskaExtractor::addTracks() { meta->setInt32(kKeyWidth, vtrack->GetWidth()); meta->setInt32(kKeyHeight, vtrack->GetHeight()); getColorInformation(vtrack, meta); break; } Loading media/libstagefright/matroska/MatroskaExtractor.h +2 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ namespace android { struct AMessage; class String8; class MetaData; struct DataSourceReader; struct MatroskaSource; Loading Loading @@ -80,7 +81,7 @@ private: status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); void addTracks(); void findThumbnails(); void getColorInformation(const mkvparser::VideoTrack *vtrack, sp<MetaData> &meta); bool isLiveStreaming() const; MatroskaExtractor(const MatroskaExtractor &); Loading media/libstagefright/webm/WebmConstants.h +18 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,24 @@ enum Mkv { kMkvDisplayHeight = 0x54BA, kMkvDisplayUnit = 0x54B2, kMkvAspectRatioType = 0x54B3, kMkvColour = 0x55B0, kMkvColourMatrixCoefficients = 0x55B1, kMkvColourRange = 0x55B9, kMkvColourTransferCharacteristics = 0x55BA, kMkvColourPrimaries = 0x55BB, kMkvColourMaxCll = 0x55BC, kMkvColourMaxFall = 0x55BD, kMkvMasteringMetadata = 0x55D0, kMkvMasteringPrimaryRChromaticityX = 0x55D1, kMkvMasteringPrimaryRChromaticityY = 0x55D2, kMkvMasteringPrimaryGChromaticityX = 0x55D3, kMkvMasteringPrimaryGChromaticityY = 0x55D4, kMkvMasteringPrimaryBChromaticityX = 0x55D5, kMkvMasteringPrimaryBChromaticityY = 0x55D6, kMkvMasteringWhitePointChromaticityX = 0x55D7, kMkvMasteringWhitePointChromaticityY = 0x55D8, kMkvMasteringLuminanceMax = 0x55D9, kMkvMasteringLuminanceMin = 0x55DA, kMkvFrameRate = 0x2383E3, kMkvAudio = 0xE1, kMkvSamplingFrequency = 0xB5, Loading Loading
include/media/stagefright/MetaData.h +1 −2 Original line number Diff line number Diff line Loading @@ -194,8 +194,7 @@ enum { kKeyNalLengthSize = 'nals', // int32_t // HDR related kKeyMinLuminance = 'minL', // int32_t, min luminance of the content in cd/m2. kKeyMaxLuminance = 'maxL', // int32_t, max luminance of the content in cd/m2. kKeyHdrStaticInfo = 'hdrS', // HDRStaticInfo // color aspects kKeyColorRange = 'cRng', // int32_t, color range, value defined by ColorAspects.Range Loading
media/libstagefright/Utils.cpp +19 −4 Original line number Diff line number Diff line Loading @@ -96,6 +96,7 @@ static status_t copyNALUToABuffer(sp<ABuffer> *buffer, const uint8_t *ptr, size_ return OK; } #if 0 static void convertMetaDataToMessageInt32( const sp<MetaData> &meta, sp<AMessage> &msg, uint32_t key, const char *name) { int32_t value; Loading @@ -103,6 +104,7 @@ static void convertMetaDataToMessageInt32( msg->setInt32(name, value); } } #endif static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) { // 0 values are unspecified Loading Loading @@ -631,8 +633,14 @@ status_t convertMetaDataToMessage( msg->setInt32("rotation-degrees", rotationDegrees); } convertMetaDataToMessageInt32(meta, msg, kKeyMinLuminance, "min-luminance"); convertMetaDataToMessageInt32(meta, msg, kKeyMaxLuminance, "max-luminance"); uint32_t type; const void *data; size_t size; if (meta->findData(kKeyHdrStaticInfo, &type, &data, &size) && type == 'hdrS' && size == sizeof(HDRStaticInfo)) { ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg); } convertMetaDataToMessageColorAspects(meta, msg); } else if (!strncasecmp("audio/", mime, 6)) { int32_t numChannels, sampleRate; Loading Loading @@ -1146,6 +1154,7 @@ static size_t reassembleHVCC(const sp<ABuffer> &csd0, uint8_t *hvcc, size_t hvcc return size; } #if 0 static void convertMessageToMetaDataInt32( const sp<AMessage> &msg, sp<MetaData> &meta, uint32_t key, const char *name) { int32_t value; Loading @@ -1153,6 +1162,7 @@ static void convertMessageToMetaDataInt32( meta->setInt32(key, value); } } #endif static void convertMessageToMetaDataColorAspects(const sp<AMessage> &msg, sp<MetaData> &meta) { // 0 values are unspecified Loading Loading @@ -1237,8 +1247,13 @@ void convertMessageToMetaData(const sp<AMessage> &msg, sp<MetaData> &meta) { meta->setInt32(kKeyRotation, rotationDegrees); } convertMessageToMetaDataInt32(msg, meta, kKeyMinLuminance, "min-luminance"); convertMessageToMetaDataInt32(msg, meta, kKeyMaxLuminance, "max-luminance"); if (msg->contains("hdr-static-info")) { HDRStaticInfo info; if (ColorUtils::getHDRStaticInfoFromFormat(msg, &info)) { meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); } } convertMessageToMetaDataColorAspects(msg, meta); } else if (mime.startsWith("audio/")) { int32_t numChannels; Loading
media/libstagefright/matroska/MatroskaExtractor.cpp +107 −0 Original line number Diff line number Diff line Loading @@ -24,6 +24,7 @@ #include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/foundation/AUtils.h> #include <media/stagefright/foundation/ABuffer.h> #include <media/stagefright/foundation/ColorUtils.h> #include <media/stagefright/foundation/hexdump.h> #include <media/stagefright/DataSource.h> #include <media/stagefright/MediaBuffer.h> Loading Loading @@ -1058,6 +1059,109 @@ status_t MatroskaExtractor::synthesizeAVCC(TrackInfo *trackInfo, size_t index) { return OK; } static inline bool isValidInt32ColourValue(long long value) { return value != mkvparser::Colour::kValueNotPresent && value >= INT32_MIN && value <= INT32_MAX; } static inline bool isValidUint16ColourValue(long long value) { return value != mkvparser::Colour::kValueNotPresent && value >= 0 && value <= UINT16_MAX; } static inline bool isValidPrimary(const mkvparser::PrimaryChromaticity *primary) { return primary != NULL && primary->x >= 0 && primary->x <= 1 && primary->y >= 0 && primary->y <= 1; } void MatroskaExtractor::getColorInformation( const mkvparser::VideoTrack *vtrack, sp<MetaData> &meta) { const mkvparser::Colour *color = vtrack->GetColour(); if (color == NULL) { return; } // Color Aspects { int32_t primaries = 2; // ISO unspecified int32_t transfer = 2; // ISO unspecified int32_t coeffs = 2; // ISO unspecified bool fullRange = false; // default bool rangeSpecified = false; if (isValidInt32ColourValue(color->primaries)) { primaries = color->primaries; } if (isValidInt32ColourValue(color->transfer_characteristics)) { transfer = color->transfer_characteristics; } if (isValidInt32ColourValue(color->matrix_coefficients)) { coeffs = color->matrix_coefficients; } if (color->range != mkvparser::Colour::kValueNotPresent && color->range != 0 /* MKV unspecified */) { // We only support MKV broadcast range (== limited) and full range. // We treat all other value as the default limited range. fullRange = color->range == 2 /* MKV fullRange */; rangeSpecified = true; } ColorAspects aspects; ColorUtils::convertIsoColorAspectsToCodecAspects( primaries, transfer, coeffs, fullRange, aspects); meta->setInt32(kKeyColorPrimaries, aspects.mPrimaries); meta->setInt32(kKeyTransferFunction, aspects.mTransfer); meta->setInt32(kKeyColorMatrix, aspects.mMatrixCoeffs); meta->setInt32( kKeyColorRange, rangeSpecified ? aspects.mRange : ColorAspects::RangeUnspecified); } // HDR Static Info { HDRStaticInfo info, nullInfo; // nullInfo is a fully unspecified static info memset(&info, 0, sizeof(info)); memset(&nullInfo, 0, sizeof(nullInfo)); if (isValidUint16ColourValue(color->max_cll)) { info.sType1.mMaxContentLightLevel = color->max_cll; } if (isValidUint16ColourValue(color->max_fall)) { info.sType1.mMaxFrameAverageLightLevel = color->max_fall; } const mkvparser::MasteringMetadata *mastering = color->mastering_metadata; if (mastering != NULL) { // Convert matroska values to HDRStaticInfo equivalent values for each fully specified // group. See CTA-681.3 section 3.2.1 for more info. if (mastering->luminance_max >= 0.5 && mastering->luminance_max < 65535.5) { info.sType1.mMaxDisplayLuminance = (uint16_t)(mastering->luminance_max + 0.5); } if (mastering->luminance_min >= 0.00005 && mastering->luminance_min < 6.55355) { info.sType1.mMinDisplayLuminance = (uint16_t)(10000 * mastering->luminance_min + 0.5); } if (isValidPrimary(mastering->white_point)) { info.sType1.mW.x = (uint16_t)(50000 * mastering->white_point->x + 0.5); info.sType1.mW.y = (uint16_t)(50000 * mastering->white_point->y + 0.5); } if (isValidPrimary(mastering->r) && isValidPrimary(mastering->g) && isValidPrimary(mastering->b)) { info.sType1.mR.x = (uint16_t)(50000 * mastering->r->x + 0.5); info.sType1.mR.y = (uint16_t)(50000 * mastering->r->y + 0.5); info.sType1.mG.x = (uint16_t)(50000 * mastering->g->x + 0.5); info.sType1.mG.y = (uint16_t)(50000 * mastering->g->y + 0.5); info.sType1.mB.x = (uint16_t)(50000 * mastering->b->x + 0.5); info.sType1.mB.y = (uint16_t)(50000 * mastering->b->y + 0.5); } } // Only advertise static info if at least one of the groups have been specified. if (memcmp(&info, &nullInfo, sizeof(info)) != 0) { info.mID = HDRStaticInfo::kType1; meta->setData(kKeyHdrStaticInfo, 'hdrS', &info, sizeof(info)); } } } void MatroskaExtractor::addTracks() { const mkvparser::Tracks *tracks = mSegment->GetTracks(); Loading Loading @@ -1127,6 +1231,9 @@ void MatroskaExtractor::addTracks() { meta->setInt32(kKeyWidth, vtrack->GetWidth()); meta->setInt32(kKeyHeight, vtrack->GetHeight()); getColorInformation(vtrack, meta); break; } Loading
media/libstagefright/matroska/MatroskaExtractor.h +2 −1 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ namespace android { struct AMessage; class String8; class MetaData; struct DataSourceReader; struct MatroskaSource; Loading Loading @@ -80,7 +81,7 @@ private: status_t synthesizeAVCC(TrackInfo *trackInfo, size_t index); void addTracks(); void findThumbnails(); void getColorInformation(const mkvparser::VideoTrack *vtrack, sp<MetaData> &meta); bool isLiveStreaming() const; MatroskaExtractor(const MatroskaExtractor &); Loading
media/libstagefright/webm/WebmConstants.h +18 −0 Original line number Diff line number Diff line Loading @@ -98,6 +98,24 @@ enum Mkv { kMkvDisplayHeight = 0x54BA, kMkvDisplayUnit = 0x54B2, kMkvAspectRatioType = 0x54B3, kMkvColour = 0x55B0, kMkvColourMatrixCoefficients = 0x55B1, kMkvColourRange = 0x55B9, kMkvColourTransferCharacteristics = 0x55BA, kMkvColourPrimaries = 0x55BB, kMkvColourMaxCll = 0x55BC, kMkvColourMaxFall = 0x55BD, kMkvMasteringMetadata = 0x55D0, kMkvMasteringPrimaryRChromaticityX = 0x55D1, kMkvMasteringPrimaryRChromaticityY = 0x55D2, kMkvMasteringPrimaryGChromaticityX = 0x55D3, kMkvMasteringPrimaryGChromaticityY = 0x55D4, kMkvMasteringPrimaryBChromaticityX = 0x55D5, kMkvMasteringPrimaryBChromaticityY = 0x55D6, kMkvMasteringWhitePointChromaticityX = 0x55D7, kMkvMasteringWhitePointChromaticityY = 0x55D8, kMkvMasteringLuminanceMax = 0x55D9, kMkvMasteringLuminanceMin = 0x55DA, kMkvFrameRate = 0x2383E3, kMkvAudio = 0xE1, kMkvSamplingFrequency = 0xB5, Loading