1033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim/* 2033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Copyright (C) 2018 The Android Open Source Project 3033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 4033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Licensed under the Apache License, Version 2.0 (the "License"); 5033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * you may not use this file except in compliance with the License. 6033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * You may obtain a copy of the License at 7033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 8033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * http://www.apache.org/licenses/LICENSE-2.0 9033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * 10033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * Unless required by applicable law or agreed to in writing, software 11033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * distributed under the License is distributed on an "AS IS" BASIS, 12033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * See the License for the specific language governing permissions and 14033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim * limitations under the License. 15033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim */ 16033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 17d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar//#define LOG_NDEBUG 0 1872dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#define LOG_TAG "C2SoftVpxDec" 19d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <log/log.h> 20033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 21d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <media/stagefright/foundation/AUtils.h> 22d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <media/stagefright/foundation/MediaDefs.h> 23033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 24d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include <C2Debug.h> 25033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#include <C2PlatformSupport.h> 2672dc0b6eea5a305d58537dcd2ee28e23c72b6e44Lajos Molnar#include <SimpleC2Interface.h> 27033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 28d087ee640c4664516a25cec687a76b31bb62b2e1Lajos Molnar#include "C2SoftVpxDec.h" 29033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 30033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimnamespace android { 31033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 32033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef VP9 336f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajooconstexpr char COMPONENT_NAME[] = "c2.android.vp9.decoder"; 34033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else 356f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajooconstexpr char COMPONENT_NAME[] = "c2.android.vp8.decoder"; 36033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif 37033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 38aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarclass C2SoftVpxDec::IntfImpl : public SimpleInterface<void>::BaseParams { 396f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoopublic: 406f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper> &helper) 4149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo : SimpleInterface<void>::BaseParams( 4249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo helper, 4349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo COMPONENT_NAME, 4449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Component::KIND_DECODER, 4549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Component::DOMAIN_VIDEO, 4649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo#ifdef VP9 4749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo MEDIA_MIMETYPE_VIDEO_VP9 4849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo#else 4949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo MEDIA_MIMETYPE_VIDEO_VP8 5049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo#endif 5149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo ) { 5249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo noPrivateBuffers(); // TODO: account for our buffers here 5349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo noInputReferences(); 5449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo noOutputReferences(); 5549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo noInputLatency(); 5649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo noTimeStretch(); 576f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 5849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo // TODO: output latency and reordering 596f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 606f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo addParameter( 6149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo DefineParam(mAttrib, C2_PARAMKEY_COMPONENT_ATTRIBUTES) 6249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withConstValue(new C2ComponentAttributesSetting(C2Component::ATTRIB_IS_TEMPORAL)) 636f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo .build()); 646f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 656f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo addParameter( 6649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo DefineParam(mSize, C2_PARAMKEY_PICTURE_SIZE) 6749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withDefault(new C2StreamPictureSizeInfo::output(0u, 320, 240)) 6849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withFields({ 6949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2F(mSize, width).inRange(2, 2048, 2), 7049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2F(mSize, height).inRange(2, 2048, 2), 7149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo }) 7249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withSetter(SizeSetter) 736f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo .build()); 746f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 75033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef VP9 7649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo // TODO: Add C2Config::PROFILE_VP9_2HDR ?? 7749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo addParameter( 7849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL) 7949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withDefault(new C2StreamProfileLevelInfo::input(0u, 8049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::PROFILE_VP9_0, C2Config::LEVEL_VP9_5)) 8149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withFields({ 8249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2F(mProfileLevel, profile).oneOf({ 8349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::PROFILE_VP9_0, 8449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::PROFILE_VP9_2}), 8549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2F(mProfileLevel, level).oneOf({ 8649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_1, 8749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_1_1, 8849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_2, 8949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_2_1, 9049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_3, 9149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_3_1, 9249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_4, 9349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_4_1, 9449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2Config::LEVEL_VP9_5, 9549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo }) 9649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo }) 9749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withSetter(ProfileLevelSetter, mSize) 9849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .build()); 99aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar#else 100aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar addParameter( 101aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar DefineParam(mProfileLevel, C2_PARAMKEY_PROFILE_LEVEL) 102aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar .withConstValue(new C2StreamProfileLevelInfo::input(0u, 103aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar C2Config::PROFILE_UNUSED, C2Config::LEVEL_UNUSED)) 104aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar .build()); 105033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif 10649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo 10749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2ChromaOffsetStruct locations[1] = { C2ChromaOffsetStruct::ITU_YUV_420_0() }; 10849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo std::shared_ptr<C2StreamColorInfo::output> defaultColorInfo = 10949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2StreamColorInfo::output::AllocShared( 11049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo 1u, 0u, 8u /* bitDepth */, C2Color::YUV_420); 11149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo memcpy(defaultColorInfo->m.locations, locations, sizeof(locations)); 11249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo 11349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo defaultColorInfo = 11449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2StreamColorInfo::output::AllocShared( 11549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo { C2ChromaOffsetStruct::ITU_YUV_420_0() }, 11649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo 0u, 8u /* bitDepth */, C2Color::YUV_420); 117118d815d2cd1820dfaff033f5ff1217c4f57f033Lajos Molnar helper->addStructDescriptors<C2ChromaOffsetStruct>(); 1186f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 1196f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo addParameter( 12049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo DefineParam(mColorInfo, C2_PARAMKEY_CODED_COLOR_INFO) 12149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withConstValue(defaultColorInfo) 1226f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo .build()); 1236f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 12449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo // TODO: support more formats? 1256f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo addParameter( 12649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo DefineParam(mPixelFormat, C2_PARAMKEY_PIXEL_FORMAT) 12749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo .withConstValue(new C2StreamPixelFormatInfo::output( 12849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo 0u, HAL_PIXEL_FORMAT_YCBCR_420_888)) 1296f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo .build()); 1306f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo } 131033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 13249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo static C2R SizeSetter(bool mayBlock, const C2P<C2VideoSizeStreamInfo::output> &oldMe, 13349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2P<C2VideoSizeStreamInfo::output> &me) { 13449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo (void)mayBlock; 13549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo C2R res = C2R::Ok(); 13649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo if (!me.F(me.v.width).supportsAtAll(me.v.width)) { 13749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.width))); 13849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo me.set().width = oldMe.v.width; 13949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo } 14049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo if (!me.F(me.v.height).supportsAtAll(me.v.height)) { 14149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo res = res.plus(C2SettingResultBuilder::BadValue(me.F(me.v.height))); 14249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo me.set().height = oldMe.v.height; 14349c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo } 14449c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo return res; 14549c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo } 14649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo 14749c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo static C2R ProfileLevelSetter(bool mayBlock, C2P<C2StreamProfileLevelInfo::input> &me, 14849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo const C2P<C2StreamPictureSizeInfo::output> &size) { 1496f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo (void)mayBlock; 15049c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo (void)size; 15149c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo (void)me; // TODO: validate 15249c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo return C2R::Ok(); 1536f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo } 1546f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 1556f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajooprivate: 15649c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo std::shared_ptr<C2StreamProfileLevelInfo::input> mProfileLevel; 1576f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo std::shared_ptr<C2VideoSizeStreamInfo::output> mSize; 15849c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo std::shared_ptr<C2StreamColorInfo::output> mColorInfo; 15949c13f55d7e01ab2064a30a05b5ebf92b6e46b40Manisha Jajoo std::shared_ptr<C2StreamPixelFormatInfo::output> mPixelFormat; 1606f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo}; 1616f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 162aa9c743015a71323b4204320a44cc1f7802a1055Lajos MolnarC2SoftVpxDec::C2SoftVpxDec( 1636f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo const char *name, 1646f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo c2_node_id_t id, 1656f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo const std::shared_ptr<IntfImpl> &intfImpl) 1666f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo : SimpleC2Component(std::make_shared<SimpleInterface<IntfImpl>>(name, id, intfImpl)), 1676f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo mIntf(intfImpl), 168033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCodecCtx(nullptr) { 169033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 170033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 171aa9c743015a71323b4204320a44cc1f7802a1055Lajos MolnarC2SoftVpxDec::~C2SoftVpxDec() { 172033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim onRelease(); 173033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 174033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 175aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarc2_status_t C2SoftVpxDec::onInit() { 176033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim status_t err = initDecoder(); 177033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return err == OK ? C2_OK : C2_CORRUPTED; 178033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 179033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 180aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarc2_status_t C2SoftVpxDec::onStop() { 181033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = false; 182033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledOutputEos = false; 183033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 184033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 185033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 186033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 187aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarvoid C2SoftVpxDec::onReset() { 1880f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini (void)onStop(); 1890f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini c2_status_t err = onFlush_sm(); 1900f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini if (err != C2_OK) 1910f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini { 1920f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini ALOGW("Failed to flush decoder. Try to hard reset decoder"); 1930f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini destroyDecoder(); 1940f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini (void)initDecoder(); 1950f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini } 196033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 197033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 198aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarvoid C2SoftVpxDec::onRelease() { 199033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim destroyDecoder(); 200033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 201033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 202aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarc2_status_t C2SoftVpxDec::onFlush_sm() { 203033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mFrameParallelMode) { 204033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Flush decoder by passing nullptr data ptr and 0 size. 205033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Ideally, this should never fail. 206033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (vpx_codec_decode(mCodecCtx, nullptr, 0, nullptr, 0)) { 207033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("Failed to flush on2 decoder."); 208033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_CORRUPTED; 209033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 210033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 211033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 212033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Drop all the decoded frames in decoder. 213033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_iter_t iter = nullptr; 214033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while (vpx_codec_get_frame(mCodecCtx, &iter)) { 215033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 216033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 217033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = false; 218033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledOutputEos = false; 219033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 220033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 221033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 222033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatic int GetCPUCoreCount() { 223033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int cpuCoreCount = 1; 224033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#if defined(_SC_NPROCESSORS_ONLN) 225033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim cpuCoreCount = sysconf(_SC_NPROCESSORS_ONLN); 226033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else 227033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // _SC_NPROC_ONLN must be defined... 228033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim cpuCoreCount = sysconf(_SC_NPROC_ONLN); 229033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif 230033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(cpuCoreCount >= 1); 231033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("Number of CPU cores: %d", cpuCoreCount); 232033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return cpuCoreCount; 233033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 234033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 235aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarstatus_t C2SoftVpxDec::initDecoder() { 236033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#ifdef VP9 237033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mMode = MODE_VP9; 238033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#else 239033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mMode = MODE_VP8; 240033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim#endif 241033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 242033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mWidth = 320; 243033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mHeight = 240; 244033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mFrameParallelMode = false; 245033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledOutputEos = false; 246033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = false; 247033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 2480f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini if (!mCodecCtx) { 2490f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini mCodecCtx = new vpx_codec_ctx_t; 2500f3ea4c92c22f8f37baa8332c454cac8bc442237Umang Saini } 251033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 252033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_dec_cfg_t cfg; 253033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memset(&cfg, 0, sizeof(vpx_codec_dec_cfg_t)); 254033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim cfg.threads = GetCPUCoreCount(); 255033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 256033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_flags_t flags; 257033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memset(&flags, 0, sizeof(vpx_codec_flags_t)); 258033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mFrameParallelMode) flags |= VPX_CODEC_USE_FRAME_THREADING; 259033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 260033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_err_t vpx_err; 261033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if ((vpx_err = vpx_codec_dec_init( 262033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCodecCtx, mMode == MODE_VP8 ? &vpx_codec_vp8_dx_algo : &vpx_codec_vp9_dx_algo, 263033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim &cfg, flags))) { 264033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("on2 decoder failed to initialize. (%d)", vpx_err); 265033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return UNKNOWN_ERROR; 266033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 267033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 268033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 269033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 270033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 271aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarstatus_t C2SoftVpxDec::destroyDecoder() { 272033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mCodecCtx) { 273033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_destroy(mCodecCtx); 274033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim delete mCodecCtx; 275033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCodecCtx = nullptr; 276033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 277033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 278033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return OK; 279033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 280033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 281033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimvoid fillEmptyWork(const std::unique_ptr<C2Work> &work) { 282033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t flags = 0; 283033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work->input.flags & C2FrameData::FLAG_END_OF_STREAM) { 284033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flags |= C2FrameData::FLAG_END_OF_STREAM; 285033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("signalling eos"); 286033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 287033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.flags = (C2FrameData::flags_t)flags; 288033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.clear(); 289033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.ordinal = work->input.ordinal; 290033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 291033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 292033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 293aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarvoid C2SoftVpxDec::finishWork(uint64_t index, const std::unique_ptr<C2Work> &work, 294033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2GraphicBlock> &block) { 295033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Buffer> buffer = createGraphicBuffer(block, 296033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2Rect(mWidth, mHeight)); 297033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim auto fillWork = [buffer, index](const std::unique_ptr<C2Work> &work) { 298033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t flags = 0; 299033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) && 300033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) { 301033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim flags |= C2FrameData::FLAG_END_OF_STREAM; 302033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("signalling eos"); 303033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 304033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.flags = (C2FrameData::flags_t)flags; 305033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.clear(); 306033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.buffers.push_back(buffer); 307033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->worklets.front()->output.ordinal = work->input.ordinal; 308033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 1u; 309033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim }; 310033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (work && c2_cntr64_t(index) == work->input.ordinal.frameIndex) { 311033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillWork(work); 312033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 313033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim finish(index, fillWork); 314033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 315033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 316033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 317aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarvoid C2SoftVpxDec::process( 318033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work, 319033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool) { 320033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_OK; 321033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->workletsProcessed = 0u; 3226f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo work->worklets.front()->output.configUpdate.clear(); 323033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mSignalledError || mSignalledOutputEos) { 324033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_BAD_VALUE; 325033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 326033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 327033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 32845c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim size_t inOffset = 0u; 32945c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim size_t inSize = 0u; 33045c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim C2ReadView rView = mDummyReadView; 33145c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim if (!work->input.buffers.empty()) { 33245c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim rView = work->input.buffers[0]->data().linearBlocks().front().map().get(); 33345c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim inSize = rView.capacity(); 33445c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim if (inSize && rView.error()) { 33545c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim ALOGE("read view map failed %d", rView.error()); 33645c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim work->result = C2_CORRUPTED; 33745c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim return; 33845c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim } 339033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 340033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 341033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool codecConfig = ((work->input.flags & C2FrameData::FLAG_CODEC_CONFIG) !=0); 342033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bool eos = ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) != 0); 343033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 344033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in buffer attr. size %zu timestamp %d frameindex %d, flags %x", 345033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim inSize, (int)work->input.ordinal.timestamp.peeku(), 346033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (int)work->input.ordinal.frameIndex.peeku(), work->input.flags); 347033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 348033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Software VP9 Decoder does not need the Codec Specific Data (CSD) 349033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if 350033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // it was passed. 351033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (codecConfig) { 352033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Ignore CSD buffer for VP9. 353033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (mMode == MODE_VP9) { 354033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillEmptyWork(work); 355033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 356033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else { 357033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // Tolerate the CSD buffer for VP8. This is a workaround 358033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim // for b/28689536. continue 359033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("WARNING: Got CSD buffer for VP8. Continue"); 360033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 361033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 362033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 363033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int64_t frameIndex = work->input.ordinal.frameIndex.peekll(); 364033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 365033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (inSize) { 36645c52538eab8ff337687d374f657cff5d6c51912Wonsik Kim uint8_t *bitstream = const_cast<uint8_t *>(rView.data() + inOffset); 367033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_err_t err = vpx_codec_decode( 368033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mCodecCtx, bitstream, inSize, &frameIndex, 0); 369033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != VPX_CODEC_OK) { 370033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("on2 decoder failed to decode frame. err: %d", err); 371033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_CORRUPTED; 372033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledError = true; 373033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return; 374033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 375033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 376033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 377033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim (void)outputBuffer(pool, work); 378033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 379033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (eos) { 380033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work); 381033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim mSignalledOutputEos = true; 382033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } else if (!inSize) { 383033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillEmptyWork(work); 384033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 385033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 386033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 387033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimstatic void copyOutputBufferToYV12Frame(uint8_t *dst, 388033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *srcY, const uint8_t *srcU, const uint8_t *srcV, 389033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t srcYStride, size_t srcUStride, size_t srcVStride, 390033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t width, uint32_t height, int32_t bpp) { 391033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t dstYStride = align(width, 16) * bpp ; 392033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t dstUVStride = align(dstYStride / 2, 16); 393033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint8_t *dstStart = dst; 394033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 395033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < height; ++i) { 396033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memcpy(dst, srcY, width * bpp); 397033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim srcY += srcYStride; 398033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dst += dstYStride; 399033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 400033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 401033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dst = dstStart + dstYStride * height; 402033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < height / 2; ++i) { 403033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memcpy(dst, srcV, width / 2 * bpp); 404033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim srcV += srcVStride; 405033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dst += dstUVStride; 406033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 407033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 408033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dst = dstStart + (dstYStride * height) + (dstUVStride * height / 2); 409033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim for (size_t i = 0; i < height / 2; ++i) { 410033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim memcpy(dst, srcU, width / 2 * bpp); 411033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim srcU += srcUStride; 412033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim dst += dstUVStride; 413033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 414033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 415033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 416aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarbool C2SoftVpxDec::outputBuffer( 417033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 418033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work) 419033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim{ 420033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!(work && pool)) return false; 421033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 422033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_codec_iter_t iter = nullptr; 423033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim vpx_image_t *img = vpx_codec_get_frame(mCodecCtx, &iter); 424033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 425033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (!img) return false; 426033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 4276f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo if (img->d_w != mWidth || img->d_h != mHeight) { 4286f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo mWidth = img->d_w; 4296f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo mHeight = img->d_h; 4306f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 4316f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo C2VideoSizeStreamInfo::output size(0u, mWidth, mHeight); 4326f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo std::vector<std::unique_ptr<C2SettingResult>> failures; 4336f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures); 4346f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo if (err == C2_OK) { 4356f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo work->worklets.front()->output.configUpdate.push_back( 4366f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo C2Param::Copy(size)); 4376f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo } else { 4386f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo ALOGE("Config update size failed"); 4396f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo mSignalledError = true; 4406f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo work->result = C2_CORRUPTED; 4416f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo return false; 4426f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo } 443033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 4446f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo } 445033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim CHECK(img->fmt == VPX_IMG_FMT_I420 || img->fmt == VPX_IMG_FMT_I42016); 446033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim int32_t bpp = 1; 447033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (img->fmt == VPX_IMG_FMT_I42016) { 448033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim bpp = 2; 449033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 450033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 451033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2GraphicBlock> block; 452033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t format = HAL_PIXEL_FORMAT_YV12; 453033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2MemoryUsage usage = { C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE }; 454033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_status_t err = pool->fetchGraphicBlock(align(mWidth, 16) * bpp, mHeight, format, usage, &block); 455033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (err != C2_OK) { 456033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("fetchGraphicBlock for Output failed with status %d", err); 457033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = err; 458033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 459033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 460033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 461033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim C2GraphicView wView = block->map().get(); 462033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (wView.error()) { 463033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGE("graphic view map failed %d", wView.error()); 464033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work->result = C2_CORRUPTED; 465033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return false; 466033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 467033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 468033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("provided (%dx%d) required (%dx%d), out frameindex %d", 469033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim block->width(), block->height(), mWidth, mHeight, (int)*(int64_t *)img->user_priv); 470033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 471033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint8_t *dst = const_cast<uint8_t *>(wView.data()[C2PlanarLayout::PLANE_Y]); 472033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t srcYStride = img->stride[VPX_PLANE_Y]; 473033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t srcUStride = img->stride[VPX_PLANE_U]; 474033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim size_t srcVStride = img->stride[VPX_PLANE_V]; 475033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *srcY = (const uint8_t *)img->planes[VPX_PLANE_Y]; 476033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *srcU = (const uint8_t *)img->planes[VPX_PLANE_U]; 477033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const uint8_t *srcV = (const uint8_t *)img->planes[VPX_PLANE_V]; 478033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim copyOutputBufferToYV12Frame(dst, srcY, srcU, srcV, 479033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim srcYStride, srcUStride, srcVStride, mWidth, mHeight, bpp); 480033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 481033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim finishWork(*(int64_t *)img->user_priv, work, std::move(block)); 482033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return true; 483033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 484033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 485aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarc2_status_t C2SoftVpxDec::drainInternal( 486033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t drainMode, 487033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool, 488033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::unique_ptr<C2Work> &work) { 489033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == NO_DRAIN) { 490033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("drain with NO_DRAIN: no-op"); 491033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 492033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 493033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == DRAIN_CHAIN) { 494033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGW("DRAIN_CHAIN not supported"); 495033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OMITTED; 496033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 497033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 498033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim while ((outputBuffer(pool, work))) { 499033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 500033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 501033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim if (drainMode == DRAIN_COMPONENT_WITH_EOS && 502033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim work && work->workletsProcessed == 0u) { 503033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim fillEmptyWork(work); 504033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 505033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 506033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 507033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 508aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnarc2_status_t C2SoftVpxDec::drain( 509033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim uint32_t drainMode, 510033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim const std::shared_ptr<C2BlockPool> &pool) { 511033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return drainInternal(drainMode, pool, nullptr); 512033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 513033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 514033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimclass C2SoftVpxFactory : public C2ComponentFactory { 515033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimpublic: 5166f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo C2SoftVpxFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( 5176f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo GetCodec2PlatformComponentStore()->getParamReflector())) { 5186f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo } 5196f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 520033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual c2_status_t createComponent( 521033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_node_id_t id, 522033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2Component>* const component, 523033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(C2Component*)> deleter) override { 5246f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo *component = std::shared_ptr<C2Component>( 525aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar new C2SoftVpxDec(COMPONENT_NAME, id, 526aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar std::make_shared<C2SoftVpxDec::IntfImpl>(mHelper)), 5276f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo deleter); 528033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 529033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 530033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 531033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual c2_status_t createInterface( 532033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim c2_node_id_t id, 533033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::shared_ptr<C2ComponentInterface>* const interface, 534033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim std::function<void(C2ComponentInterface*)> deleter) override { 5356f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo *interface = std::shared_ptr<C2ComponentInterface>( 536aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar new SimpleInterface<C2SoftVpxDec::IntfImpl>( 5376f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo COMPONENT_NAME, id, 538aa9c743015a71323b4204320a44cc1f7802a1055Lajos Molnar std::make_shared<C2SoftVpxDec::IntfImpl>(mHelper)), 5396f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo deleter); 540033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return C2_OK; 541033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim } 542033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 543033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim virtual ~C2SoftVpxFactory() override = default; 5446f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo 5456f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajooprivate: 5466f709d0299c4b7b77fc06a5423122fb9859d62afManisha Jajoo std::shared_ptr<C2ReflectorHelper> mHelper; 547033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim}; 548033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 549033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} // namespace android 550033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 551033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" ::C2ComponentFactory* CreateCodec2Factory() { 552033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in %s", __func__); 553033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim return new ::android::C2SoftVpxFactory(); 554033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 555033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim 556033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kimextern "C" void DestroyCodec2Factory(::C2ComponentFactory* factory) { 557033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim ALOGV("in %s", __func__); 558033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim delete factory; 559033ea548eec7ec220082ea6b199bf6e77f67a40dWonsik Kim} 560