diff options
-rw-r--r-- | media/codec2/components/dav1d/C2SoftDav1dDec.cpp | 182 | ||||
-rw-r--r-- | media/codec2/components/dav1d/C2SoftDav1dDec.h | 10 | ||||
-rw-r--r-- | media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp | 7 |
3 files changed, 85 insertions, 114 deletions
diff --git a/media/codec2/components/dav1d/C2SoftDav1dDec.cpp b/media/codec2/components/dav1d/C2SoftDav1dDec.cpp index 3f96cb3ad0..76680a3790 100644 --- a/media/codec2/components/dav1d/C2SoftDav1dDec.cpp +++ b/media/codec2/components/dav1d/C2SoftDav1dDec.cpp @@ -42,6 +42,8 @@ constexpr char COMPONENT_NAME[] = CODECNAME; constexpr size_t kMinInputBufferSize = 2 * 1024 * 1024; +constexpr uint32_t kOutputDelay = 4; + class C2SoftDav1dDec::IntfImpl : public SimpleInterface<void>::BaseParams { public: explicit IntfImpl(const std::shared_ptr<C2ReflectorHelper>& helper) @@ -239,6 +241,13 @@ class C2SoftDav1dDec::IntfImpl : public SimpleInterface<void>::BaseParams { .withFields({C2F(mPixelFormat, value).oneOf(pixelFormats)}) .withSetter((Setter<decltype(*mPixelFormat)>::StrictValueWithNoDeps)) .build()); + + addParameter( + DefineParam(mActualOutputDelay, C2_PARAMKEY_OUTPUT_DELAY) + .withDefault(new C2PortActualDelayTuning::output(kOutputDelay)) + .withFields({C2F(mActualOutputDelay, value).inRange(0, kOutputDelay)}) + .withSetter(Setter<decltype(*mActualOutputDelay)>::StrictValueWithNoDeps) + .build()); } static C2R SizeSetter(bool mayBlock, const C2P<C2StreamPictureSizeInfo::output>& oldMe, @@ -450,13 +459,6 @@ void C2SoftDav1dDec::flushDav1d() { if (mDav1dCtx) { Dav1dPicture p; - while (mDecodedPictures.size() > 0) { - p = mDecodedPictures.front(); - mDecodedPictures.pop_front(); - - dav1d_picture_unref(&p); - } - int res = 0; while (true) { memset(&p, 0, sizeof(p)); @@ -527,6 +529,8 @@ bool C2SoftDav1dDec::initDecoder() { android::base::GetIntProperty(NUM_THREADS_DAV1D_PROPERTY, NUM_THREADS_DAV1D_DEFAULT); if (numThreads > 0) lib_settings.n_threads = numThreads; + lib_settings.max_frame_delay = kOutputDelay; + int res = 0; if ((res = dav1d_open(&mDav1dCtx, &lib_settings))) { ALOGE("dav1d_open failed. status: %d.", res); @@ -540,15 +544,6 @@ bool C2SoftDav1dDec::initDecoder() { void C2SoftDav1dDec::destroyDecoder() { if (mDav1dCtx) { - Dav1dPicture p; - while (mDecodedPictures.size() > 0) { - memset(&p, 0, sizeof(p)); - p = mDecodedPictures.front(); - mDecodedPictures.pop_front(); - - dav1d_picture_unref(&p); - } - dav1d_close(&mDav1dCtx); mDav1dCtx = nullptr; mOutputBufferIndex = 0; @@ -572,19 +567,24 @@ void fillEmptyWork(const std::unique_ptr<C2Work>& work) { } void C2SoftDav1dDec::finishWork(uint64_t index, const std::unique_ptr<C2Work>& work, - const std::shared_ptr<C2GraphicBlock>& block) { + const std::shared_ptr<C2GraphicBlock>& block, + const Dav1dPicture &img) { 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) { + + auto fillWork = [buffer, index, img, this](const std::unique_ptr<C2Work>& work) { uint32_t flags = 0; if ((work->input.flags & C2FrameData::FLAG_END_OF_STREAM) && (c2_cntr64_t(index) == work->input.ordinal.frameIndex)) { flags |= C2FrameData::FLAG_END_OF_STREAM; ALOGV("signalling end_of_stream."); } + getHDRStaticParams(&img, work); + getHDR10PlusInfoData(&img, work); + work->worklets.front()->output.flags = (C2FrameData::flags_t)flags; work->worklets.front()->output.buffers.clear(); work->worklets.front()->output.buffers.push_back(buffer); @@ -598,10 +598,6 @@ void C2SoftDav1dDec::finishWork(uint64_t index, const std::unique_ptr<C2Work>& w } } -static void freeCallback(const uint8_t */*data*/, void */*cookie*/) { - return; -} - void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work, const std::shared_ptr<C2BlockPool>& pool) { work->result = C2_OK; @@ -652,19 +648,60 @@ void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work, if (res == 0) { ALOGV("dav1d found a sequenceHeader (%dx%d) for in_frameIndex=%ld.", seq.max_width, seq.max_height, (long)in_frameIndex); + if (seq.max_width != mWidth || seq.max_height != mHeight) { + drainInternal(DRAIN_COMPONENT_NO_EOS, pool, work); + mWidth = seq.max_width; + mHeight = seq.max_height; + + C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight); + std::vector<std::unique_ptr<C2SettingResult>> failures; + c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures); + if (err == C2_OK) { + work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(size)); + } else { + ALOGE("Config update size failed"); + mSignalledError = true; + work->result = C2_CORRUPTED; + work->workletsProcessed = 1u; + return; + } + } } + // insert OBU TD if it is not present. + // TODO: b/286852962 + uint8_t obu_type = (bitstream[0] >> 3) & 0xf; Dav1dData data; - res = dav1d_data_wrap(&data, bitstream, inSize, freeCallback, nullptr); - if (res != 0) { - ALOGE("Decoder wrap error %s!", strerror(DAV1D_ERR(res))); + uint8_t* ptr = (obu_type == DAV1D_OBU_TD) ? dav1d_data_create(&data, inSize) + : dav1d_data_create(&data, inSize + 2); + if (ptr == nullptr) { + ALOGE("dav1d_data_create failed!"); i_ret = -1; + } else { data.m.timestamp = in_frameIndex; - // ALOGV("inSize=%ld, in_frameIndex=%ld, timestamp=%ld", - // inSize, frameIndex, data.m.timestamp); + int new_Size; + if (obu_type != DAV1D_OBU_TD) { + new_Size = (int)(inSize + 2); + + // OBU TD + ptr[0] = 0x12; + ptr[1] = 0; + + memcpy(ptr + 2, bitstream, inSize); + } else { + new_Size = (int)(inSize); + // TODO: b/277797541 - investigate how to wrap this pointer in Dav1dData to + // avoid memcopy operations. + memcpy(ptr, bitstream, new_Size); + } + + // ALOGV("memcpy(ptr,bitstream,inSize=%ld,new_Size=%d,in_frameIndex=%ld,timestamp=%ld," + // "ptr[0,1,2,3,4]=%x,%x,%x,%x,%x)", + // inSize, new_Size, frameIndex, data.m.timestamp, ptr[0], ptr[1], ptr[2], + // ptr[3], ptr[4]); // Dump the bitstream data (inputBuffer) if dumping is enabled. #ifdef FILE_DUMP_ENABLE @@ -672,6 +709,7 @@ void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work, #endif bool b_draining = false; + int res; do { res = dav1d_send_data(mDav1dCtx, &data); @@ -685,39 +723,9 @@ void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work, break; } - bool b_output_error = false; - - do { - Dav1dPicture img; - memset(&img, 0, sizeof(img)); - - res = dav1d_get_picture(mDav1dCtx, &img); - if (res == 0) { - mDecodedPictures.push_back(img); - - if (!end_of_stream) break; - } else if (res == DAV1D_ERR(EAGAIN)) { - /* the decoder needs more data to be able to output something. - * if there is more data pending, continue the loop below or - * otherwise break */ - if (data.sz != 0) res = 0; - break; - } else { - ALOGE("warning! Decoder error %d!", res); - b_output_error = true; - break; - } - } while (res == 0); - - if (b_output_error) break; - - /* on drain, we must ignore the 1st EAGAIN */ - if (!b_draining && (res == DAV1D_ERR(EAGAIN) || res == 0) && - (end_of_stream)) { - b_draining = true; - res = 0; - } - } while (res == 0 && ((data.sz != 0) || b_draining)); + outputBuffer(pool, work); + + } while (res == DAV1D_ERR(EAGAIN)); if (data.sz > 0) { ALOGE("unexpected data.sz=%zu after dav1d_send_data", data.sz); @@ -739,8 +747,6 @@ void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work, } } - (void)outputBuffer(pool, work); - if (end_of_stream) { drainInternal(DRAIN_COMPONENT_WITH_EOS, pool, work); mSignalledOutputEos = true; @@ -749,7 +755,7 @@ void C2SoftDav1dDec::process(const std::unique_ptr<C2Work>& work, } } -void C2SoftDav1dDec::getHDRStaticParams(Dav1dPicture* picture, +void C2SoftDav1dDec::getHDRStaticParams(const Dav1dPicture* picture, const std::unique_ptr<C2Work>& work) { C2StreamHdrStaticMetadataInfo::output hdrStaticMetadataInfo{}; bool infoPresent = false; @@ -813,7 +819,7 @@ void C2SoftDav1dDec::getHDRStaticParams(Dav1dPicture* picture, } } -void C2SoftDav1dDec::getHDR10PlusInfoData(Dav1dPicture* picture, +void C2SoftDav1dDec::getHDR10PlusInfoData(const Dav1dPicture* picture, const std::unique_ptr<C2Work>& work) { if (picture != nullptr) { if (picture->itut_t35 != nullptr) { @@ -853,7 +859,7 @@ void C2SoftDav1dDec::getHDR10PlusInfoData(Dav1dPicture* picture, } } -void C2SoftDav1dDec::getVuiParams(Dav1dPicture* picture) { +void C2SoftDav1dDec::getVuiParams(const Dav1dPicture* picture) { VuiColorAspects vuiColorAspects; if (picture) { @@ -924,53 +930,16 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool, memset(&img, 0, sizeof(img)); int res = 0; - if (mDecodedPictures.size() > 0) { - img = mDecodedPictures.front(); - mDecodedPictures.pop_front(); - // ALOGD("Got a picture(out_frameIndex=%ld,timestamp=%ld) from the deque for - // outputBuffer.",img.m.timestamp,img.m.timestamp); - } else { - res = dav1d_get_picture(mDav1dCtx, &img); - if (res == 0) { - // ALOGD("Got a picture(out_frameIndex=%ld,timestamp=%ld) from dav1d for - // outputBuffer.",img.m.timestamp,img.m.timestamp); - } else { - ALOGE("failed to get a picture from dav1d for outputBuffer."); - } - } - + res = dav1d_get_picture(mDav1dCtx, &img); if (res == DAV1D_ERR(EAGAIN)) { - ALOGD("Not enough data to output a picture."); + ALOGV("Not enough data to output a picture."); return false; - } - if (res != 0) { + } else if (res != 0) { ALOGE("The AV1 decoder failed to get a picture (res=%s).", strerror(DAV1D_ERR(res))); return false; } - const int width = img.p.w; - const int height = img.p.h; - if (width != mWidth || height != mHeight) { - mWidth = width; - mHeight = height; - - C2StreamPictureSizeInfo::output size(0u, mWidth, mHeight); - std::vector<std::unique_ptr<C2SettingResult>> failures; - c2_status_t err = mIntf->config({&size}, C2_MAY_BLOCK, &failures); - if (err == C2_OK) { - work->worklets.front()->output.configUpdate.push_back(C2Param::Copy(size)); - } else { - ALOGE("Config update size failed"); - mSignalledError = true; - work->result = C2_CORRUPTED; - work->workletsProcessed = 1u; - return false; - } - } - getVuiParams(&img); - getHDRStaticParams(&img, work); - getHDR10PlusInfoData(&img, work); // out_frameIndex that the decoded picture returns from dav1d. int64_t out_frameIndex = img.m.timestamp; @@ -1156,9 +1125,8 @@ bool C2SoftDav1dDec::outputBuffer(const std::shared_ptr<C2BlockPool>& pool, convFormat); } + finishWork(out_frameIndex, work, std::move(block), img); dav1d_picture_unref(&img); - - finishWork(out_frameIndex, work, std::move(block)); block = nullptr; return true; } diff --git a/media/codec2/components/dav1d/C2SoftDav1dDec.h b/media/codec2/components/dav1d/C2SoftDav1dDec.h index e3d2a93189..5d2a725607 100644 --- a/media/codec2/components/dav1d/C2SoftDav1dDec.h +++ b/media/codec2/components/dav1d/C2SoftDav1dDec.h @@ -58,7 +58,6 @@ struct C2SoftDav1dDec : public SimpleC2Component { int mOutputBufferIndex = 0; Dav1dContext* mDav1dCtx = nullptr; - std::deque<Dav1dPicture> mDecodedPictures; // configurations used by component in process // (TODO: keep this in intf but make them internal only) @@ -101,12 +100,13 @@ struct C2SoftDav1dDec : public SimpleC2Component { nsecs_t mTimeEnd = 0; // Time at the end of decode() bool initDecoder(); - void getHDRStaticParams(Dav1dPicture* picture, const std::unique_ptr<C2Work>& work); - void getHDR10PlusInfoData(Dav1dPicture* picture, const std::unique_ptr<C2Work>& work); - void getVuiParams(Dav1dPicture* picture); + void getHDRStaticParams(const Dav1dPicture* picture, const std::unique_ptr<C2Work>& work); + void getHDR10PlusInfoData(const Dav1dPicture* picture, const std::unique_ptr<C2Work>& work); + void getVuiParams(const Dav1dPicture* picture); void destroyDecoder(); void finishWork(uint64_t index, const std::unique_ptr<C2Work>& work, - const std::shared_ptr<C2GraphicBlock>& block); + const std::shared_ptr<C2GraphicBlock>& block, + const Dav1dPicture &img); // Sets |work->result| and mSignalledError. Returns false. void setError(const std::unique_ptr<C2Work>& work, c2_status_t error); bool allocTmpFrameBuffer(size_t size); diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp index a4b3e2f434..14c3fa0875 100644 --- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp +++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp @@ -312,8 +312,11 @@ void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) { outHeader->nFilledLen = frameSize; List<BufferInfo *>::iterator it = outQueue.begin(); - while ((*it)->mHeader != outHeader) { - ++it; + while (it != outQueue.end() && (*it)->mHeader != outHeader) { + ++it; + } + if (it == outQueue.end()) { + return; } BufferInfo *outInfo = *it; |