Loading media/codec2/components/aac/C2SoftAacDec.cpp +52 −1 Original line number Original line Diff line number Diff line Loading @@ -221,6 +221,12 @@ public: .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)}) .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)}) .withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps) .withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps) .build()); .build()); addParameter(DefineParam(mChannelMask, C2_PARAMKEY_CHANNEL_MASK) .withDefault(new C2StreamChannelMaskInfo::output(0u, 0)) .withFields({C2F(mChannelMask, value).inRange(0, 4294967292)}) .withSetter(Setter<decltype(*mChannelMask)>::StrictValueWithNoDeps) .build()); } } bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; } bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; } Loading Loading @@ -255,6 +261,7 @@ private: std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode; std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode; std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount; std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount; std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness; std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness; std::shared_ptr<C2StreamChannelMaskInfo::output> mChannelMask; // TODO Add : C2StreamAacSbrModeTuning // TODO Add : C2StreamAacSbrModeTuning }; }; Loading Loading @@ -829,9 +836,11 @@ void C2SoftAacDec::process( C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); C2StreamChannelMaskInfo::output channelMaskInfo(0u, maskFromCount(mStreamInfo->numChannels)); std::vector<std::unique_ptr<C2SettingResult>> failures; std::vector<std::unique_ptr<C2SettingResult>> failures; c2_status_t err = mIntf->config( c2_status_t err = mIntf->config( { &sampleRateInfo, &channelCountInfo }, { &sampleRateInfo, &channelCountInfo, &channelMaskInfo }, C2_MAY_BLOCK, C2_MAY_BLOCK, &failures); &failures); if (err == OK) { if (err == OK) { Loading @@ -840,6 +849,7 @@ void C2SoftAacDec::process( C2FrameData &output = work->worklets.front()->output; C2FrameData &output = work->worklets.front()->output; output.configUpdate.push_back(C2Param::Copy(sampleRateInfo)); output.configUpdate.push_back(C2Param::Copy(sampleRateInfo)); output.configUpdate.push_back(C2Param::Copy(channelCountInfo)); output.configUpdate.push_back(C2Param::Copy(channelCountInfo)); output.configUpdate.push_back(C2Param::Copy(channelMaskInfo)); } else { } else { ALOGE("Config Update failed"); ALOGE("Config Update failed"); mSignalledError = true; mSignalledError = true; Loading Loading @@ -1056,6 +1066,47 @@ void C2SoftAacDec::drainDecoder() { } } } } // definitions based on android.media.AudioFormat.CHANNEL_OUT_* #define CHANNEL_OUT_FL 0x4 #define CHANNEL_OUT_FR 0x8 #define CHANNEL_OUT_FC 0x10 #define CHANNEL_OUT_LFE 0x20 #define CHANNEL_OUT_BL 0x40 #define CHANNEL_OUT_BR 0x80 #define CHANNEL_OUT_SL 0x800 #define CHANNEL_OUT_SR 0x1000 uint32_t C2SoftAacDec::maskFromCount(uint32_t channelCount) { // KEY_CHANNEL_MASK expects masks formatted according to Java android.media.AudioFormat // where the two left-most bits are 0 for output channel mask switch (channelCount) { case 1: // mono is front left return (CHANNEL_OUT_FL); case 2: // stereo return (CHANNEL_OUT_FL | CHANNEL_OUT_FR); case 4: // 4.0 = stereo with backs return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_BL | CHANNEL_OUT_BR); case 5: // 5.0 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR); case 6: // 5.1 = 5.0 + LFE return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_LFE); case 7: // 7.0 = 5.0 + Sides return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_SL | CHANNEL_OUT_SR); case 8: // 7.1 = 7.0 + LFE return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_SL | CHANNEL_OUT_SR | CHANNEL_OUT_LFE); default: return 0; } } class C2SoftAacDecFactory : public C2ComponentFactory { class C2SoftAacDecFactory : public C2ComponentFactory { public: public: C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( Loading media/codec2/components/aac/C2SoftAacDec.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ private: int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples); int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples); int32_t outputDelayRingBufferSamplesAvailable(); int32_t outputDelayRingBufferSamplesAvailable(); int32_t outputDelayRingBufferSpaceLeft(); int32_t outputDelayRingBufferSpaceLeft(); uint32_t maskFromCount(uint32_t channelCount); C2_DO_NOT_COPY(C2SoftAacDec); C2_DO_NOT_COPY(C2SoftAacDec); }; }; Loading media/codec2/sfplugin/CCodec.cpp +15 −5 Original line number Original line Diff line number Diff line Loading @@ -1826,13 +1826,20 @@ void CCodec::start() { return; return; } } mCallback->onStartCompleted(); // preparation of input buffers may not succeed due to the lack of // memory; returning correct error code (NO_MEMORY) as an error allows err2 = mChannel->requestInitialInputBuffers(); // MediaCodec to try reclaim and restart codec gracefully. std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers; err2 = mChannel->prepareInitialInputBuffers(&clientInputBuffers); if (err2 != OK) { if (err2 != OK) { ALOGE("Initial request for Input Buffers failed"); ALOGE("Initial preparation for Input Buffers failed"); mCallback->onError(err2, ACTION_CODE_FATAL); mCallback->onError(err2, ACTION_CODE_FATAL); return; } } mCallback->onStartCompleted(); mChannel->requestInitialInputBuffers(std::move(clientInputBuffers)); } } void CCodec::initiateShutdown(bool keepComponentAllocated) { void CCodec::initiateShutdown(bool keepComponentAllocated) { Loading Loading @@ -2126,11 +2133,14 @@ void CCodec::signalResume() { state->set(RUNNING); state->set(RUNNING); } } status_t err = mChannel->requestInitialInputBuffers(); std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers; status_t err = mChannel->prepareInitialInputBuffers(&clientInputBuffers); if (err != OK) { if (err != OK) { ALOGE("Resume request for Input Buffers failed"); ALOGE("Resume request for Input Buffers failed"); mCallback->onError(err, ACTION_CODE_FATAL); mCallback->onError(err, ACTION_CODE_FATAL); return; } } mChannel->requestInitialInputBuffers(std::move(clientInputBuffers)); } } void CCodec::signalSetParameters(const sp<AMessage> &msg) { void CCodec::signalSetParameters(const sp<AMessage> &msg) { Loading media/codec2/sfplugin/CCodecBufferChannel.cpp +39 −40 Original line number Original line Diff line number Diff line Loading @@ -1470,54 +1470,47 @@ status_t CCodecBufferChannel::start( return OK; return OK; } } status_t CCodecBufferChannel::requestInitialInputBuffers() { status_t CCodecBufferChannel::prepareInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers) { if (mInputSurface) { if (mInputSurface) { return OK; return OK; } } C2StreamBufferTypeSetting::output oStreamFormat(0u); C2PrependHeaderModeSetting prepend(PREPEND_HEADER_TO_NONE); c2_status_t err = mComponent->query({ &oStreamFormat, &prepend }, {}, C2_DONT_BLOCK, nullptr); if (err != C2_OK && err != C2_BAD_INDEX) { return UNKNOWN_ERROR; } size_t numInputSlots = mInput.lock()->numSlots; size_t numInputSlots = mInput.lock()->numSlots; struct ClientInputBuffer { size_t index; sp<MediaCodecBuffer> buffer; size_t capacity; }; std::list<ClientInputBuffer> clientInputBuffers; { { Mutexed<Input>::Locked input(mInput); Mutexed<Input>::Locked input(mInput); while (clientInputBuffers.size() < numInputSlots) { while (clientInputBuffers->size() < numInputSlots) { ClientInputBuffer clientInputBuffer; size_t index; if (!input->buffers->requestNewBuffer(&clientInputBuffer.index, sp<MediaCodecBuffer> buffer; &clientInputBuffer.buffer)) { if (!input->buffers->requestNewBuffer(&index, &buffer)) { break; break; } } clientInputBuffer.capacity = clientInputBuffer.buffer->capacity(); clientInputBuffers->emplace(index, buffer); clientInputBuffers.emplace_back(std::move(clientInputBuffer)); } } } } if (clientInputBuffers.empty()) { if (clientInputBuffers->empty()) { ALOGW("[%s] start: cannot allocate memory at all", mName); ALOGW("[%s] start: cannot allocate memory at all", mName); return NO_MEMORY; return NO_MEMORY; } else if (clientInputBuffers.size() < numInputSlots) { } else if (clientInputBuffers->size() < numInputSlots) { ALOGD("[%s] start: cannot allocate memory for all slots, " ALOGD("[%s] start: cannot allocate memory for all slots, " "only %zu buffers allocated", "only %zu buffers allocated", mName, clientInputBuffers.size()); mName, clientInputBuffers->size()); } else { } else { ALOGV("[%s] %zu initial input buffers available", ALOGV("[%s] %zu initial input buffers available", mName, clientInputBuffers.size()); mName, clientInputBuffers->size()); } return OK; } status_t CCodecBufferChannel::requestInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers) { C2StreamBufferTypeSetting::output oStreamFormat(0u); C2PrependHeaderModeSetting prepend(PREPEND_HEADER_TO_NONE); c2_status_t err = mComponent->query({ &oStreamFormat, &prepend }, {}, C2_DONT_BLOCK, nullptr); if (err != C2_OK && err != C2_BAD_INDEX) { return UNKNOWN_ERROR; } } // Sort input buffers by their capacities in increasing order. clientInputBuffers.sort( [](const ClientInputBuffer& a, const ClientInputBuffer& b) { return a.capacity < b.capacity; }); std::list<std::unique_ptr<C2Work>> flushedConfigs; std::list<std::unique_ptr<C2Work>> flushedConfigs; mFlushedConfigs.lock()->swap(flushedConfigs); mFlushedConfigs.lock()->swap(flushedConfigs); Loading @@ -1539,25 +1532,31 @@ status_t CCodecBufferChannel::requestInitialInputBuffers() { } } } } if (oStreamFormat.value == C2BufferData::LINEAR && if (oStreamFormat.value == C2BufferData::LINEAR && (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) { (!prepend || prepend.value == PREPEND_HEADER_TO_NONE) && sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer; !clientInputBuffers.empty()) { size_t minIndex = clientInputBuffers.begin()->first; sp<MediaCodecBuffer> minBuffer = clientInputBuffers.begin()->second; for (const auto &[index, buffer] : clientInputBuffers) { if (minBuffer->capacity() > buffer->capacity()) { minIndex = index; minBuffer = buffer; } } // WORKAROUND: Some apps expect CSD available without queueing // WORKAROUND: Some apps expect CSD available without queueing // any input. Queue an empty buffer to get the CSD. // any input. Queue an empty buffer to get the CSD. buffer->setRange(0, 0); minBuffer->setRange(0, 0); buffer->meta()->clear(); minBuffer->meta()->clear(); buffer->meta()->setInt64("timeUs", 0); minBuffer->meta()->setInt64("timeUs", 0); if (queueInputBufferInternal(buffer) != OK) { if (queueInputBufferInternal(minBuffer) != OK) { ALOGW("[%s] Error while queueing an empty buffer to get CSD", ALOGW("[%s] Error while queueing an empty buffer to get CSD", mName); mName); return UNKNOWN_ERROR; return UNKNOWN_ERROR; } } clientInputBuffers.pop_front(); clientInputBuffers.erase(minIndex); } } for (const ClientInputBuffer& clientInputBuffer: clientInputBuffers) { for (const auto &[index, buffer] : clientInputBuffers) { mCallback->onInputBufferAvailable( mCallback->onInputBufferAvailable(index, buffer); clientInputBuffer.index, clientInputBuffer.buffer); } } return OK; return OK; Loading media/codec2/sfplugin/CCodecBufferChannel.h +16 −2 Original line number Original line Diff line number Diff line Loading @@ -130,9 +130,23 @@ public: bool buffersBoundToCodec); bool buffersBoundToCodec); /** /** * Request initial input buffers to be filled by client. * Prepare initial input buffers to be filled by client. * * \param clientInputBuffers[out] pointer to slot index -> buffer map. * On success, it contains prepared * initial input buffers. */ status_t prepareInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers); /** * Request initial input buffers as prepared in clientInputBuffers. * * \param clientInputBuffers[in] slot index -> buffer map with prepared * initial input buffers. */ */ status_t requestInitialInputBuffers(); status_t requestInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers); /** /** * Stop queueing buffers to the component. This object should never queue * Stop queueing buffers to the component. This object should never queue Loading Loading
media/codec2/components/aac/C2SoftAacDec.cpp +52 −1 Original line number Original line Diff line number Diff line Loading @@ -221,6 +221,12 @@ public: .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)}) .withFields({C2F(mDrcOutputLoudness, value).inRange(-57.75, 0.25)}) .withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps) .withSetter(Setter<decltype(*mDrcOutputLoudness)>::StrictValueWithNoDeps) .build()); .build()); addParameter(DefineParam(mChannelMask, C2_PARAMKEY_CHANNEL_MASK) .withDefault(new C2StreamChannelMaskInfo::output(0u, 0)) .withFields({C2F(mChannelMask, value).inRange(0, 4294967292)}) .withSetter(Setter<decltype(*mChannelMask)>::StrictValueWithNoDeps) .build()); } } bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; } bool isAdts() const { return mAacFormat->value == C2Config::AAC_PACKAGING_ADTS; } Loading Loading @@ -255,6 +261,7 @@ private: std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode; std::shared_ptr<C2StreamDrcAlbumModeTuning::input> mDrcAlbumMode; std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount; std::shared_ptr<C2StreamMaxChannelCountInfo::input> mMaxChannelCount; std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness; std::shared_ptr<C2StreamDrcOutputLoudnessTuning::output> mDrcOutputLoudness; std::shared_ptr<C2StreamChannelMaskInfo::output> mChannelMask; // TODO Add : C2StreamAacSbrModeTuning // TODO Add : C2StreamAacSbrModeTuning }; }; Loading Loading @@ -829,9 +836,11 @@ void C2SoftAacDec::process( C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); C2StreamSampleRateInfo::output sampleRateInfo(0u, mStreamInfo->sampleRate); C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); C2StreamChannelCountInfo::output channelCountInfo(0u, mStreamInfo->numChannels); C2StreamChannelMaskInfo::output channelMaskInfo(0u, maskFromCount(mStreamInfo->numChannels)); std::vector<std::unique_ptr<C2SettingResult>> failures; std::vector<std::unique_ptr<C2SettingResult>> failures; c2_status_t err = mIntf->config( c2_status_t err = mIntf->config( { &sampleRateInfo, &channelCountInfo }, { &sampleRateInfo, &channelCountInfo, &channelMaskInfo }, C2_MAY_BLOCK, C2_MAY_BLOCK, &failures); &failures); if (err == OK) { if (err == OK) { Loading @@ -840,6 +849,7 @@ void C2SoftAacDec::process( C2FrameData &output = work->worklets.front()->output; C2FrameData &output = work->worklets.front()->output; output.configUpdate.push_back(C2Param::Copy(sampleRateInfo)); output.configUpdate.push_back(C2Param::Copy(sampleRateInfo)); output.configUpdate.push_back(C2Param::Copy(channelCountInfo)); output.configUpdate.push_back(C2Param::Copy(channelCountInfo)); output.configUpdate.push_back(C2Param::Copy(channelMaskInfo)); } else { } else { ALOGE("Config Update failed"); ALOGE("Config Update failed"); mSignalledError = true; mSignalledError = true; Loading Loading @@ -1056,6 +1066,47 @@ void C2SoftAacDec::drainDecoder() { } } } } // definitions based on android.media.AudioFormat.CHANNEL_OUT_* #define CHANNEL_OUT_FL 0x4 #define CHANNEL_OUT_FR 0x8 #define CHANNEL_OUT_FC 0x10 #define CHANNEL_OUT_LFE 0x20 #define CHANNEL_OUT_BL 0x40 #define CHANNEL_OUT_BR 0x80 #define CHANNEL_OUT_SL 0x800 #define CHANNEL_OUT_SR 0x1000 uint32_t C2SoftAacDec::maskFromCount(uint32_t channelCount) { // KEY_CHANNEL_MASK expects masks formatted according to Java android.media.AudioFormat // where the two left-most bits are 0 for output channel mask switch (channelCount) { case 1: // mono is front left return (CHANNEL_OUT_FL); case 2: // stereo return (CHANNEL_OUT_FL | CHANNEL_OUT_FR); case 4: // 4.0 = stereo with backs return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_BL | CHANNEL_OUT_BR); case 5: // 5.0 return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR); case 6: // 5.1 = 5.0 + LFE return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_LFE); case 7: // 7.0 = 5.0 + Sides return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_SL | CHANNEL_OUT_SR); case 8: // 7.1 = 7.0 + LFE return (CHANNEL_OUT_FL | CHANNEL_OUT_FC | CHANNEL_OUT_FR | CHANNEL_OUT_BL | CHANNEL_OUT_BR | CHANNEL_OUT_SL | CHANNEL_OUT_SR | CHANNEL_OUT_LFE); default: return 0; } } class C2SoftAacDecFactory : public C2ComponentFactory { class C2SoftAacDecFactory : public C2ComponentFactory { public: public: C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( C2SoftAacDecFactory() : mHelper(std::static_pointer_cast<C2ReflectorHelper>( Loading
media/codec2/components/aac/C2SoftAacDec.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -101,6 +101,7 @@ private: int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples); int32_t outputDelayRingBufferGetSamples(INT_PCM *samples, int numSamples); int32_t outputDelayRingBufferSamplesAvailable(); int32_t outputDelayRingBufferSamplesAvailable(); int32_t outputDelayRingBufferSpaceLeft(); int32_t outputDelayRingBufferSpaceLeft(); uint32_t maskFromCount(uint32_t channelCount); C2_DO_NOT_COPY(C2SoftAacDec); C2_DO_NOT_COPY(C2SoftAacDec); }; }; Loading
media/codec2/sfplugin/CCodec.cpp +15 −5 Original line number Original line Diff line number Diff line Loading @@ -1826,13 +1826,20 @@ void CCodec::start() { return; return; } } mCallback->onStartCompleted(); // preparation of input buffers may not succeed due to the lack of // memory; returning correct error code (NO_MEMORY) as an error allows err2 = mChannel->requestInitialInputBuffers(); // MediaCodec to try reclaim and restart codec gracefully. std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers; err2 = mChannel->prepareInitialInputBuffers(&clientInputBuffers); if (err2 != OK) { if (err2 != OK) { ALOGE("Initial request for Input Buffers failed"); ALOGE("Initial preparation for Input Buffers failed"); mCallback->onError(err2, ACTION_CODE_FATAL); mCallback->onError(err2, ACTION_CODE_FATAL); return; } } mCallback->onStartCompleted(); mChannel->requestInitialInputBuffers(std::move(clientInputBuffers)); } } void CCodec::initiateShutdown(bool keepComponentAllocated) { void CCodec::initiateShutdown(bool keepComponentAllocated) { Loading Loading @@ -2126,11 +2133,14 @@ void CCodec::signalResume() { state->set(RUNNING); state->set(RUNNING); } } status_t err = mChannel->requestInitialInputBuffers(); std::map<size_t, sp<MediaCodecBuffer>> clientInputBuffers; status_t err = mChannel->prepareInitialInputBuffers(&clientInputBuffers); if (err != OK) { if (err != OK) { ALOGE("Resume request for Input Buffers failed"); ALOGE("Resume request for Input Buffers failed"); mCallback->onError(err, ACTION_CODE_FATAL); mCallback->onError(err, ACTION_CODE_FATAL); return; } } mChannel->requestInitialInputBuffers(std::move(clientInputBuffers)); } } void CCodec::signalSetParameters(const sp<AMessage> &msg) { void CCodec::signalSetParameters(const sp<AMessage> &msg) { Loading
media/codec2/sfplugin/CCodecBufferChannel.cpp +39 −40 Original line number Original line Diff line number Diff line Loading @@ -1470,54 +1470,47 @@ status_t CCodecBufferChannel::start( return OK; return OK; } } status_t CCodecBufferChannel::requestInitialInputBuffers() { status_t CCodecBufferChannel::prepareInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers) { if (mInputSurface) { if (mInputSurface) { return OK; return OK; } } C2StreamBufferTypeSetting::output oStreamFormat(0u); C2PrependHeaderModeSetting prepend(PREPEND_HEADER_TO_NONE); c2_status_t err = mComponent->query({ &oStreamFormat, &prepend }, {}, C2_DONT_BLOCK, nullptr); if (err != C2_OK && err != C2_BAD_INDEX) { return UNKNOWN_ERROR; } size_t numInputSlots = mInput.lock()->numSlots; size_t numInputSlots = mInput.lock()->numSlots; struct ClientInputBuffer { size_t index; sp<MediaCodecBuffer> buffer; size_t capacity; }; std::list<ClientInputBuffer> clientInputBuffers; { { Mutexed<Input>::Locked input(mInput); Mutexed<Input>::Locked input(mInput); while (clientInputBuffers.size() < numInputSlots) { while (clientInputBuffers->size() < numInputSlots) { ClientInputBuffer clientInputBuffer; size_t index; if (!input->buffers->requestNewBuffer(&clientInputBuffer.index, sp<MediaCodecBuffer> buffer; &clientInputBuffer.buffer)) { if (!input->buffers->requestNewBuffer(&index, &buffer)) { break; break; } } clientInputBuffer.capacity = clientInputBuffer.buffer->capacity(); clientInputBuffers->emplace(index, buffer); clientInputBuffers.emplace_back(std::move(clientInputBuffer)); } } } } if (clientInputBuffers.empty()) { if (clientInputBuffers->empty()) { ALOGW("[%s] start: cannot allocate memory at all", mName); ALOGW("[%s] start: cannot allocate memory at all", mName); return NO_MEMORY; return NO_MEMORY; } else if (clientInputBuffers.size() < numInputSlots) { } else if (clientInputBuffers->size() < numInputSlots) { ALOGD("[%s] start: cannot allocate memory for all slots, " ALOGD("[%s] start: cannot allocate memory for all slots, " "only %zu buffers allocated", "only %zu buffers allocated", mName, clientInputBuffers.size()); mName, clientInputBuffers->size()); } else { } else { ALOGV("[%s] %zu initial input buffers available", ALOGV("[%s] %zu initial input buffers available", mName, clientInputBuffers.size()); mName, clientInputBuffers->size()); } return OK; } status_t CCodecBufferChannel::requestInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers) { C2StreamBufferTypeSetting::output oStreamFormat(0u); C2PrependHeaderModeSetting prepend(PREPEND_HEADER_TO_NONE); c2_status_t err = mComponent->query({ &oStreamFormat, &prepend }, {}, C2_DONT_BLOCK, nullptr); if (err != C2_OK && err != C2_BAD_INDEX) { return UNKNOWN_ERROR; } } // Sort input buffers by their capacities in increasing order. clientInputBuffers.sort( [](const ClientInputBuffer& a, const ClientInputBuffer& b) { return a.capacity < b.capacity; }); std::list<std::unique_ptr<C2Work>> flushedConfigs; std::list<std::unique_ptr<C2Work>> flushedConfigs; mFlushedConfigs.lock()->swap(flushedConfigs); mFlushedConfigs.lock()->swap(flushedConfigs); Loading @@ -1539,25 +1532,31 @@ status_t CCodecBufferChannel::requestInitialInputBuffers() { } } } } if (oStreamFormat.value == C2BufferData::LINEAR && if (oStreamFormat.value == C2BufferData::LINEAR && (!prepend || prepend.value == PREPEND_HEADER_TO_NONE)) { (!prepend || prepend.value == PREPEND_HEADER_TO_NONE) && sp<MediaCodecBuffer> buffer = clientInputBuffers.front().buffer; !clientInputBuffers.empty()) { size_t minIndex = clientInputBuffers.begin()->first; sp<MediaCodecBuffer> minBuffer = clientInputBuffers.begin()->second; for (const auto &[index, buffer] : clientInputBuffers) { if (minBuffer->capacity() > buffer->capacity()) { minIndex = index; minBuffer = buffer; } } // WORKAROUND: Some apps expect CSD available without queueing // WORKAROUND: Some apps expect CSD available without queueing // any input. Queue an empty buffer to get the CSD. // any input. Queue an empty buffer to get the CSD. buffer->setRange(0, 0); minBuffer->setRange(0, 0); buffer->meta()->clear(); minBuffer->meta()->clear(); buffer->meta()->setInt64("timeUs", 0); minBuffer->meta()->setInt64("timeUs", 0); if (queueInputBufferInternal(buffer) != OK) { if (queueInputBufferInternal(minBuffer) != OK) { ALOGW("[%s] Error while queueing an empty buffer to get CSD", ALOGW("[%s] Error while queueing an empty buffer to get CSD", mName); mName); return UNKNOWN_ERROR; return UNKNOWN_ERROR; } } clientInputBuffers.pop_front(); clientInputBuffers.erase(minIndex); } } for (const ClientInputBuffer& clientInputBuffer: clientInputBuffers) { for (const auto &[index, buffer] : clientInputBuffers) { mCallback->onInputBufferAvailable( mCallback->onInputBufferAvailable(index, buffer); clientInputBuffer.index, clientInputBuffer.buffer); } } return OK; return OK; Loading
media/codec2/sfplugin/CCodecBufferChannel.h +16 −2 Original line number Original line Diff line number Diff line Loading @@ -130,9 +130,23 @@ public: bool buffersBoundToCodec); bool buffersBoundToCodec); /** /** * Request initial input buffers to be filled by client. * Prepare initial input buffers to be filled by client. * * \param clientInputBuffers[out] pointer to slot index -> buffer map. * On success, it contains prepared * initial input buffers. */ status_t prepareInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> *clientInputBuffers); /** * Request initial input buffers as prepared in clientInputBuffers. * * \param clientInputBuffers[in] slot index -> buffer map with prepared * initial input buffers. */ */ status_t requestInitialInputBuffers(); status_t requestInitialInputBuffers( std::map<size_t, sp<MediaCodecBuffer>> &&clientInputBuffers); /** /** * Stop queueing buffers to the component. This object should never queue * Stop queueing buffers to the component. This object should never queue Loading