Loading media/codec2/components/gav1/C2SoftGav1Dec.cpp +116 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <C2Debug.h> #include <C2PlatformSupport.h> #include <Codec2Mapper.h> #include <SimpleC2Interface.h> #include <log/log.h> #include <media/stagefright/foundation/AUtils.h> Loading Loading @@ -156,6 +157,42 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { .withSetter(DefaultColorAspectsSetter) .build()); addParameter( DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS) .withDefault(new C2StreamColorAspectsInfo::input( 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED, C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED)) .withFields({ C2F(mCodedColorAspects, range).inRange( C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER), C2F(mCodedColorAspects, primaries).inRange( C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER), C2F(mCodedColorAspects, transfer).inRange( C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER), C2F(mCodedColorAspects, matrix).inRange( C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER) }) .withSetter(CodedColorAspectsSetter) .build()); addParameter( DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS) .withDefault(new C2StreamColorAspectsInfo::output( 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED, C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED)) .withFields({ C2F(mColorAspects, range).inRange( C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER), C2F(mColorAspects, primaries).inRange( C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER), C2F(mColorAspects, transfer).inRange( C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER), C2F(mColorAspects, matrix).inRange( C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER) }) .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects) .build()); // TODO: support more formats? addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT) .withConstValue(new C2StreamPixelFormatInfo::output( Loading Loading @@ -218,6 +255,37 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { return C2R::Ok(); } static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) { (void)mayBlock; if (me.v.range > C2Color::RANGE_OTHER) { me.set().range = C2Color::RANGE_OTHER; } if (me.v.primaries > C2Color::PRIMARIES_OTHER) { me.set().primaries = C2Color::PRIMARIES_OTHER; } if (me.v.transfer > C2Color::TRANSFER_OTHER) { me.set().transfer = C2Color::TRANSFER_OTHER; } if (me.v.matrix > C2Color::MATRIX_OTHER) { me.set().matrix = C2Color::MATRIX_OTHER; } return C2R::Ok(); } static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me, const C2P<C2StreamColorAspectsTuning::output> &def, const C2P<C2StreamColorAspectsInfo::input> &coded) { (void)mayBlock; // take default values for all unspecified fields, and coded values for specified ones me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range; me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED ? def.v.primaries : coded.v.primaries; me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED ? def.v.transfer : coded.v.transfer; me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix; return C2R::Ok(); } static C2R ProfileLevelSetter( bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me, const C2P<C2StreamPictureSizeInfo::output> &size) { Loading @@ -232,6 +300,10 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { return mDefaultColorAspects; } std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() { return mColorAspects; } static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) { (void)mayBlock; Loading @@ -254,6 +326,8 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { std::shared_ptr<C2StreamColorInfo::output> mColorInfo; std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat; std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects; std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects; std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects; std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput; std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput; }; Loading Loading @@ -371,6 +445,10 @@ void C2SoftGav1Dec::finishWork(uint64_t index, const std::shared_ptr<C2GraphicBlock> &block) { std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block, C2Rect(mWidth, mHeight)); { IntfImpl::Lock lock = mIntf->lock(); buffer->setInfo(mIntf->getColorAspects_l()); } auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) { uint32_t flags = 0; if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) && Loading Loading @@ -609,6 +687,38 @@ static void convertYUV420Planar16ToYUV420Planar( } } void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) { VuiColorAspects vuiColorAspects; vuiColorAspects.primaries = buffer->color_primary; vuiColorAspects.transfer = buffer->transfer_characteristics; vuiColorAspects.coeffs = buffer->matrix_coefficients; vuiColorAspects.fullRange = buffer->color_range; // convert vui aspects to C2 values if changed if (!(vuiColorAspects == mBitstreamColorAspects)) { mBitstreamColorAspects = vuiColorAspects; ColorAspects sfAspects; C2StreamColorAspectsInfo::input codedAspects = { 0u }; ColorUtils::convertIsoColorAspectsToCodecAspects( vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs, vuiColorAspects.fullRange, sfAspects); if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) { codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED; } if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) { codedAspects.range = C2Color::RANGE_UNSPECIFIED; } if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) { codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED; } if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) { codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED; } std::vector<std::unique_ptr<C2SettingResult>> failures; mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures); } } bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, const std::unique_ptr<C2Work> &work) { if (!(work && pool)) return false; Loading Loading @@ -651,6 +761,7 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, } } getVuiParams(buffer); if (!(buffer->image_format == libgav1::kImageFormatYuv420 || buffer->image_format == libgav1::kImageFormatMonochrome400)) { ALOGE("image_format %d not supported", buffer->image_format); Loading @@ -666,12 +777,12 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, uint32_t format = HAL_PIXEL_FORMAT_YV12; if (buffer->bitdepth == 10) { IntfImpl::Lock lock = mIntf->lock(); std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l(); std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects = mIntf->getColorAspects_l(); if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 && defaultColorAspects->matrix == C2Color::MATRIX_BT2020 && defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) { if (codedColorAspects->primaries == C2Color::PRIMARIES_BT2020 && codedColorAspects->matrix == C2Color::MATRIX_BT2020 && codedColorAspects->transfer == C2Color::TRANSFER_ST2084) { if (buffer->image_format != libgav1::kImageFormatYuv420) { ALOGE("Only YUV420 output is supported when targeting RGBA_1010102"); mSignalledError = true; Loading media/codec2/components/gav1/C2SoftGav1Dec.h +25 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,10 @@ #ifndef ANDROID_C2_SOFT_GAV1_DEC_H_ #define ANDROID_C2_SOFT_GAV1_DEC_H_ #include <media/stagefright/foundation/ColorUtils.h> #include <SimpleC2Component.h> #include <C2Config.h> #include "libgav1/src/gav1/decoder.h" #include "libgav1/src/gav1/decoder_settings.h" Loading Loading @@ -56,10 +59,32 @@ struct C2SoftGav1Dec : public SimpleC2Component { bool mSignalledOutputEos; bool mSignalledError; // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid // converting them to C2 values for each frame struct VuiColorAspects { uint8_t primaries; uint8_t transfer; uint8_t coeffs; uint8_t fullRange; // default color aspects VuiColorAspects() : primaries(C2Color::PRIMARIES_UNSPECIFIED), transfer(C2Color::TRANSFER_UNSPECIFIED), coeffs(C2Color::MATRIX_UNSPECIFIED), fullRange(C2Color::RANGE_UNSPECIFIED) { } bool operator==(const VuiColorAspects &o) { return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs && fullRange == o.fullRange; } } mBitstreamColorAspects; struct timeval mTimeStart; // Time at the start of decode() struct timeval mTimeEnd; // Time at the end of decode() bool initDecoder(); void getVuiParams(const libgav1::DecoderBuffer *buffer); void destroyDecoder(); void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work, const std::shared_ptr<C2GraphicBlock>& block); Loading Loading
media/codec2/components/gav1/C2SoftGav1Dec.cpp +116 −5 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ #include <C2Debug.h> #include <C2PlatformSupport.h> #include <Codec2Mapper.h> #include <SimpleC2Interface.h> #include <log/log.h> #include <media/stagefright/foundation/AUtils.h> Loading Loading @@ -156,6 +157,42 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { .withSetter(DefaultColorAspectsSetter) .build()); addParameter( DefineParam(mCodedColorAspects, C2_PARAMKEY_VUI_COLOR_ASPECTS) .withDefault(new C2StreamColorAspectsInfo::input( 0u, C2Color::RANGE_LIMITED, C2Color::PRIMARIES_UNSPECIFIED, C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED)) .withFields({ C2F(mCodedColorAspects, range).inRange( C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER), C2F(mCodedColorAspects, primaries).inRange( C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER), C2F(mCodedColorAspects, transfer).inRange( C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER), C2F(mCodedColorAspects, matrix).inRange( C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER) }) .withSetter(CodedColorAspectsSetter) .build()); addParameter( DefineParam(mColorAspects, C2_PARAMKEY_COLOR_ASPECTS) .withDefault(new C2StreamColorAspectsInfo::output( 0u, C2Color::RANGE_UNSPECIFIED, C2Color::PRIMARIES_UNSPECIFIED, C2Color::TRANSFER_UNSPECIFIED, C2Color::MATRIX_UNSPECIFIED)) .withFields({ C2F(mColorAspects, range).inRange( C2Color::RANGE_UNSPECIFIED, C2Color::RANGE_OTHER), C2F(mColorAspects, primaries).inRange( C2Color::PRIMARIES_UNSPECIFIED, C2Color::PRIMARIES_OTHER), C2F(mColorAspects, transfer).inRange( C2Color::TRANSFER_UNSPECIFIED, C2Color::TRANSFER_OTHER), C2F(mColorAspects, matrix).inRange( C2Color::MATRIX_UNSPECIFIED, C2Color::MATRIX_OTHER) }) .withSetter(ColorAspectsSetter, mDefaultColorAspects, mCodedColorAspects) .build()); // TODO: support more formats? addParameter(DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT) .withConstValue(new C2StreamPixelFormatInfo::output( Loading Loading @@ -218,6 +255,37 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { return C2R::Ok(); } static C2R CodedColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::input> &me) { (void)mayBlock; if (me.v.range > C2Color::RANGE_OTHER) { me.set().range = C2Color::RANGE_OTHER; } if (me.v.primaries > C2Color::PRIMARIES_OTHER) { me.set().primaries = C2Color::PRIMARIES_OTHER; } if (me.v.transfer > C2Color::TRANSFER_OTHER) { me.set().transfer = C2Color::TRANSFER_OTHER; } if (me.v.matrix > C2Color::MATRIX_OTHER) { me.set().matrix = C2Color::MATRIX_OTHER; } return C2R::Ok(); } static C2R ColorAspectsSetter(bool mayBlock, C2P<C2StreamColorAspectsInfo::output> &me, const C2P<C2StreamColorAspectsTuning::output> &def, const C2P<C2StreamColorAspectsInfo::input> &coded) { (void)mayBlock; // take default values for all unspecified fields, and coded values for specified ones me.set().range = coded.v.range == RANGE_UNSPECIFIED ? def.v.range : coded.v.range; me.set().primaries = coded.v.primaries == PRIMARIES_UNSPECIFIED ? def.v.primaries : coded.v.primaries; me.set().transfer = coded.v.transfer == TRANSFER_UNSPECIFIED ? def.v.transfer : coded.v.transfer; me.set().matrix = coded.v.matrix == MATRIX_UNSPECIFIED ? def.v.matrix : coded.v.matrix; return C2R::Ok(); } static C2R ProfileLevelSetter( bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me, const C2P<C2StreamPictureSizeInfo::output> &size) { Loading @@ -232,6 +300,10 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { return mDefaultColorAspects; } std::shared_ptr<C2StreamColorAspectsInfo::output> getColorAspects_l() { return mColorAspects; } static C2R Hdr10PlusInfoInputSetter(bool mayBlock, C2P<C2StreamHdr10PlusInfo::input> &me) { (void)mayBlock; Loading @@ -254,6 +326,8 @@ class C2SoftGav1Dec::IntfImpl : public SimpleInterface<void>::BaseParams { std::shared_ptr<C2StreamColorInfo::output> mColorInfo; std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat; std::shared_ptr<C2StreamColorAspectsTuning::output> mDefaultColorAspects; std::shared_ptr<C2StreamColorAspectsInfo::input> mCodedColorAspects; std::shared_ptr<C2StreamColorAspectsInfo::output> mColorAspects; std::shared_ptr<C2StreamHdr10PlusInfo::input> mHdr10PlusInfoInput; std::shared_ptr<C2StreamHdr10PlusInfo::output> mHdr10PlusInfoOutput; }; Loading Loading @@ -371,6 +445,10 @@ void C2SoftGav1Dec::finishWork(uint64_t index, const std::shared_ptr<C2GraphicBlock> &block) { std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block, C2Rect(mWidth, mHeight)); { IntfImpl::Lock lock = mIntf->lock(); buffer->setInfo(mIntf->getColorAspects_l()); } auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) { uint32_t flags = 0; if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) && Loading Loading @@ -609,6 +687,38 @@ static void convertYUV420Planar16ToYUV420Planar( } } void C2SoftGav1Dec::getVuiParams(const libgav1::DecoderBuffer *buffer) { VuiColorAspects vuiColorAspects; vuiColorAspects.primaries = buffer->color_primary; vuiColorAspects.transfer = buffer->transfer_characteristics; vuiColorAspects.coeffs = buffer->matrix_coefficients; vuiColorAspects.fullRange = buffer->color_range; // convert vui aspects to C2 values if changed if (!(vuiColorAspects == mBitstreamColorAspects)) { mBitstreamColorAspects = vuiColorAspects; ColorAspects sfAspects; C2StreamColorAspectsInfo::input codedAspects = { 0u }; ColorUtils::convertIsoColorAspectsToCodecAspects( vuiColorAspects.primaries, vuiColorAspects.transfer, vuiColorAspects.coeffs, vuiColorAspects.fullRange, sfAspects); if (!C2Mapper::map(sfAspects.mPrimaries, &codedAspects.primaries)) { codedAspects.primaries = C2Color::PRIMARIES_UNSPECIFIED; } if (!C2Mapper::map(sfAspects.mRange, &codedAspects.range)) { codedAspects.range = C2Color::RANGE_UNSPECIFIED; } if (!C2Mapper::map(sfAspects.mMatrixCoeffs, &codedAspects.matrix)) { codedAspects.matrix = C2Color::MATRIX_UNSPECIFIED; } if (!C2Mapper::map(sfAspects.mTransfer, &codedAspects.transfer)) { codedAspects.transfer = C2Color::TRANSFER_UNSPECIFIED; } std::vector<std::unique_ptr<C2SettingResult>> failures; mIntf->config({&codedAspects}, C2_MAY_BLOCK, &failures); } } bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, const std::unique_ptr<C2Work> &work) { if (!(work && pool)) return false; Loading Loading @@ -651,6 +761,7 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, } } getVuiParams(buffer); if (!(buffer->image_format == libgav1::kImageFormatYuv420 || buffer->image_format == libgav1::kImageFormatMonochrome400)) { ALOGE("image_format %d not supported", buffer->image_format); Loading @@ -666,12 +777,12 @@ bool C2SoftGav1Dec::outputBuffer(const std::shared_ptr<C2BlockPool> &pool, uint32_t format = HAL_PIXEL_FORMAT_YV12; if (buffer->bitdepth == 10) { IntfImpl::Lock lock = mIntf->lock(); std::shared_ptr<C2StreamColorAspectsTuning::output> defaultColorAspects = mIntf->getDefaultColorAspects_l(); std::shared_ptr<C2StreamColorAspectsInfo::output> codedColorAspects = mIntf->getColorAspects_l(); if (defaultColorAspects->primaries == C2Color::PRIMARIES_BT2020 && defaultColorAspects->matrix == C2Color::MATRIX_BT2020 && defaultColorAspects->transfer == C2Color::TRANSFER_ST2084) { if (codedColorAspects->primaries == C2Color::PRIMARIES_BT2020 && codedColorAspects->matrix == C2Color::MATRIX_BT2020 && codedColorAspects->transfer == C2Color::TRANSFER_ST2084) { if (buffer->image_format != libgav1::kImageFormatYuv420) { ALOGE("Only YUV420 output is supported when targeting RGBA_1010102"); mSignalledError = true; Loading
media/codec2/components/gav1/C2SoftGav1Dec.h +25 −0 Original line number Diff line number Diff line Loading @@ -17,7 +17,10 @@ #ifndef ANDROID_C2_SOFT_GAV1_DEC_H_ #define ANDROID_C2_SOFT_GAV1_DEC_H_ #include <media/stagefright/foundation/ColorUtils.h> #include <SimpleC2Component.h> #include <C2Config.h> #include "libgav1/src/gav1/decoder.h" #include "libgav1/src/gav1/decoder_settings.h" Loading Loading @@ -56,10 +59,32 @@ struct C2SoftGav1Dec : public SimpleC2Component { bool mSignalledOutputEos; bool mSignalledError; // Color aspects. These are ISO values and are meant to detect changes in aspects to avoid // converting them to C2 values for each frame struct VuiColorAspects { uint8_t primaries; uint8_t transfer; uint8_t coeffs; uint8_t fullRange; // default color aspects VuiColorAspects() : primaries(C2Color::PRIMARIES_UNSPECIFIED), transfer(C2Color::TRANSFER_UNSPECIFIED), coeffs(C2Color::MATRIX_UNSPECIFIED), fullRange(C2Color::RANGE_UNSPECIFIED) { } bool operator==(const VuiColorAspects &o) { return primaries == o.primaries && transfer == o.transfer && coeffs == o.coeffs && fullRange == o.fullRange; } } mBitstreamColorAspects; struct timeval mTimeStart; // Time at the start of decode() struct timeval mTimeEnd; // Time at the end of decode() bool initDecoder(); void getVuiParams(const libgav1::DecoderBuffer *buffer); void destroyDecoder(); void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work, const std::shared_ptr<C2GraphicBlock>& block); Loading