summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--media/codec2/components/dav1d/C2SoftDav1dDec.cpp182
-rw-r--r--media/codec2/components/dav1d/C2SoftDav1dDec.h10
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp7
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;