summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2014-01-08 06:03:49 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2014-01-08 06:03:49 -0800
commit90d6183b25834e32ff3e316c9f122e204a385ee6 (patch)
treedeff294b42ef91e73e97a9f7838072ea21fd6e76
parente51fdd934184ce9350300b8f682b779649fc0bdc (diff)
parent6e0dcf24fb42b79ce275fb48987307bf3ca9dc7c (diff)
downloadandroid_hardware_qcom_media-90d6183b25834e32ff3e316c9f122e204a385ee6.tar.gz
android_hardware_qcom_media-90d6183b25834e32ff3e316c9f122e204a385ee6.tar.bz2
android_hardware_qcom_media-90d6183b25834e32ff3e316c9f122e204a385ee6.zip
Merge "dashplayer: enable dynamic buffering"
-rw-r--r--dashplayer/DashCodec.cpp317
-rw-r--r--dashplayer/DashCodec.h15
2 files changed, 230 insertions, 102 deletions
diff --git a/dashplayer/DashCodec.cpp b/dashplayer/DashCodec.cpp
index 9f284270..8419d39f 100644
--- a/dashplayer/DashCodec.cpp
+++ b/dashplayer/DashCodec.cpp
@@ -247,6 +247,8 @@ private:
struct DashCodec::ExecutingState : public DashCodec::BaseState {
ExecutingState(DashCodec *codec);
+ void submitRegularOutputBuffers();
+ void submitOutputMetaBuffers();
void submitOutputBuffers();
// Submit output buffers to the decoder, submit input buffers to client
@@ -380,7 +382,9 @@ DashCodec::DashCodec()
mEncoderPadding(0),
mChannelMaskPresent(false),
mChannelMask(0),
- mSmoothStreaming(false) {
+ mDequeueCounter(0),
+ mStoreMetaDataInOutputBuffers(false),
+ mMetaDataBuffersToSubmit(0) {
mUninitializedState = new UninitializedState(this);
mLoadedState = new LoadedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
@@ -458,7 +462,11 @@ status_t DashCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
status_t err;
if (mNativeWindow != NULL && portIndex == kPortIndexOutput) {
+ if (mStoreMetaDataInOutputBuffers) {
+ err = allocateOutputMetaDataBuffers();
+ } else {
err = allocateOutputBuffersFromNativeWindow();
+ }
} else {
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
@@ -536,7 +544,9 @@ status_t DashCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
return OK;
}
-status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
+status_t DashCodec::configureOutputBuffersFromNativeWindow(
+OMX_U32 *bufferCount, OMX_U32 *bufferSize,
+ OMX_U32 *minUndequeuedBuffers) {
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = kPortIndexOutput;
@@ -601,10 +611,10 @@ status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
return err;
}
- int minUndequeuedBufs = 0;
+ *minUndequeuedBuffers = 0;
err = mNativeWindow->query(
mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &minUndequeuedBufs);
+ (int *)minUndequeuedBuffers);
if (err != 0) {
ALOGE("NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
@@ -615,15 +625,9 @@ status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
// XXX: Is this the right logic to use? It's not clear to me what the OMX
// buffer counts refer to - how do they account for the renderer holding on
// to buffers?
- if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
- OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
+ if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
+ OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
def.nBufferCountActual = newBufferCount;
-#ifdef ANDROID_JB_MR2
- //Keep an extra buffer for smooth streaming
- if (mSmoothStreaming) {
- def.nBufferCountActual += 1;
- }
-#endif
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
@@ -645,12 +649,24 @@ status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
return err;
}
+ *bufferCount = def.nBufferCountActual;
+ *bufferSize = def.nBufferSize;
+ return err;
+}
+
+status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
+ OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
+ status_t err = configureOutputBuffersFromNativeWindow(
+ &bufferCount, &bufferSize, &minUndequeuedBuffers);
+ if (err != 0)
+ return err;
+
ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
"output port",
- mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize);
+ mComponentName.c_str(), bufferCount, bufferSize);
// Dequeue buffers and send them to OMX
- for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
+ for (OMX_U32 i = 0; i < bufferCount; i++) {
ANativeWindowBuffer *buf;
err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (err != 0) {
@@ -661,7 +677,7 @@ status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false));
BufferInfo info;
info.mStatus = BufferInfo::OWNED_BY_US;
- info.mData = new ABuffer(0);
+ info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
info.mGraphicBuffer = graphicBuffer;
mBuffers[kPortIndexOutput].push(info);
@@ -690,9 +706,9 @@ status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
cancelStart = 0;
cancelEnd = mBuffers[kPortIndexOutput].size();
} else {
- // Return the last two buffers to the native window.
- cancelStart = def.nBufferCountActual - minUndequeuedBufs;
- cancelEnd = def.nBufferCountActual;
+ // Return the required minimum undequeued buffers to the native window.
+ cancelStart = bufferCount - minUndequeuedBuffers;
+ cancelEnd = bufferCount;
}
for (OMX_U32 i = cancelStart; i < cancelEnd; i++) {
@@ -703,6 +719,65 @@ status_t DashCodec::allocateOutputBuffersFromNativeWindow() {
return err;
}
+status_t DashCodec::allocateOutputMetaDataBuffers() {
+ OMX_U32 bufferCount, bufferSize, minUndequeuedBuffers;
+ status_t err = configureOutputBuffersFromNativeWindow(
+ &bufferCount, &bufferSize, &minUndequeuedBuffers);
+ if (err != 0)
+ return err;
+
+ ALOGV("[%s] Allocating %lu meta buffers on output port",
+ mComponentName.c_str(), bufferCount);
+
+ size_t totalSize = bufferCount * 8;
+ mDealer[kPortIndexOutput] = new MemoryDealer(totalSize, "DashCodec");
+
+ // Dequeue buffers and send them to OMX
+ for (OMX_U32 i = 0; i < bufferCount; i++) {
+ BufferInfo info;
+ info.mStatus = BufferInfo::OWNED_BY_NATIVE_WINDOW;
+ info.mGraphicBuffer = NULL;
+ info.mDequeuedAt = mDequeueCounter;
+
+ sp<IMemory> mem = mDealer[kPortIndexOutput]->allocate(
+ sizeof(struct VideoDecoderOutputMetaData));
+ CHECK(mem.get() != NULL);
+ info.mData = new ABuffer(mem->pointer(), mem->size());
+
+ // we use useBuffer for metadata regardless of quirks
+ err = mOMX->useBuffer(
+ mNode, kPortIndexOutput, mem, &info.mBufferID);
+
+ mBuffers[kPortIndexOutput].push(info);
+
+ ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
+ mComponentName.c_str(), info.mBufferID, mem->pointer());
+ }
+
+ mMetaDataBuffersToSubmit = bufferCount - minUndequeuedBuffers;
+ return err;
+}
+
+status_t DashCodec::submitOutputMetaDataBuffer() {
+ CHECK(mStoreMetaDataInOutputBuffers);
+ if (mMetaDataBuffersToSubmit == 0)
+ return OK;
+
+ BufferInfo *info = dequeueBufferFromNativeWindow();
+ if (info == NULL)
+ return ERROR_IO;
+
+ ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
+ mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
+
+ --mMetaDataBuffersToSubmit;
+ CHECK_EQ(mOMX->fillBuffer(mNode, info->mBufferID),
+ (status_t)OK);
+
+ info->mStatus = BufferInfo::OWNED_BY_COMPONENT;
+ return OK;
+}
+
status_t DashCodec::cancelBufferToNativeWindow(BufferInfo *info) {
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
@@ -722,16 +797,19 @@ status_t DashCodec::cancelBufferToNativeWindow(BufferInfo *info) {
DashCodec::BufferInfo *DashCodec::dequeueBufferFromNativeWindow() {
ANativeWindowBuffer *buf;
int fenceFd = -1;
+ CHECK(mNativeWindow.get() != NULL);
if (native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf) != 0) {
ALOGE("dequeueBuffer failed.");
return NULL;
}
+ BufferInfo *oldest = NULL;
for (size_t i = mBuffers[kPortIndexOutput].size(); i-- > 0;) {
BufferInfo *info =
&mBuffers[kPortIndexOutput].editItemAt(i);
- if (info->mGraphicBuffer->handle == buf->handle) {
+ if (info->mGraphicBuffer != NULL &&
+ info->mGraphicBuffer->handle == buf->handle) {
CHECK_EQ((int)info->mStatus,
(int)BufferInfo::OWNED_BY_NATIVE_WINDOW);
@@ -739,6 +817,38 @@ DashCodec::BufferInfo *DashCodec::dequeueBufferFromNativeWindow() {
return info;
}
+
+ if (info->mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW &&
+ (oldest == NULL ||
+ // avoid potential issues from counter rolling over
+ mDequeueCounter - info->mDequeuedAt >
+ mDequeueCounter - oldest->mDequeuedAt)) {
+ oldest = info;
+ }
+ }
+
+ if (oldest) {
+ CHECK(mStoreMetaDataInOutputBuffers);
+
+ // discard buffer in LRU info and replace with new buffer
+ oldest->mGraphicBuffer = new GraphicBuffer(buf, false);
+ oldest->mStatus = BufferInfo::OWNED_BY_US;
+
+ mOMX->updateGraphicBufferInMeta(
+ mNode, kPortIndexOutput, oldest->mGraphicBuffer,
+ oldest->mBufferID);
+ VideoDecoderOutputMetaData *metaData =
+ reinterpret_cast<VideoDecoderOutputMetaData *>(
+ oldest->mData->base());
+ CHECK_EQ(metaData->eType, kMetadataBufferTypeGrallocSource);
+
+ ALOGV("replaced oldest buffer #%u with age %u (%p/%p stored in %p)",
+ oldest - &mBuffers[kPortIndexOutput][0],
+ mDequeueCounter - oldest->mDequeuedAt,
+ metaData->pHandle,
+ oldest->mGraphicBuffer->handle, oldest->mData->base());
+
+ return oldest;
}
TRESPASS();
@@ -964,13 +1074,12 @@ status_t DashCodec::configureCodec(
// Always try to enable dynamic output buffers on native surface
int32_t video = !strncasecmp(mime, "video/", 6);
-#ifndef ANDROID_JB_MR2
sp<RefBase> obj;
int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
obj != NULL;
+ mStoreMetaDataInOutputBuffers = false;
if (!encoder && video && haveNativeWindow) {
- //err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
- err = INVALID_OPERATION;
+ err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
if (err != OK) {
ALOGE("[%s] storeMetaDataInBuffers failed w/ err %d",
@@ -1019,9 +1128,9 @@ status_t DashCodec::configureCodec(
err = OK;
} else {
ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
+ mStoreMetaDataInOutputBuffers = true;
}
}
-#endif
if (video) {
if (encoder) {
err = setupVideoEncoder(mime, msg);
@@ -1031,13 +1140,6 @@ status_t DashCodec::configureCodec(
|| !msg->findInt32("height", &height)) {
err = INVALID_OPERATION;
} else {
- //override height & width with max for smooth streaming
-#ifdef ANDROID_JB_MR2
- if (mSmoothStreaming) {
- width = MAX_WIDTH;
- height = MAX_HEIGHT;
- }
-#endif
err = setupVideoDecoder(mime, width, height);
}
}
@@ -2153,6 +2255,46 @@ size_t DashCodec::countBuffersOwnedByComponent(OMX_U32 portIndex) const {
return n;
}
+size_t DashCodec::countBuffersOwnedByNativeWindow() const {
+ size_t n = 0;
+
+ for (size_t i = 0; i < mBuffers[kPortIndexOutput].size(); ++i) {
+ const BufferInfo &info = mBuffers[kPortIndexOutput].itemAt(i);
+
+ if (info.mStatus == BufferInfo::OWNED_BY_NATIVE_WINDOW) {
+ ++n;
+ }
+ }
+
+ return n;
+}
+
+void DashCodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
+ if (mNativeWindow == NULL) {
+ return;
+ }
+
+ int minUndequeuedBufs = 0;
+ status_t err = mNativeWindow->query(
+ mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
+ &minUndequeuedBufs);
+
+ if (err != OK) {
+ ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
+ mComponentName.c_str(), strerror(-err), -err);
+
+ minUndequeuedBufs = 0;
+ }
+
+ while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
+ && dequeueBufferFromNativeWindow() != NULL) {
+ // these buffers will be submitted as regular buffers; account for this
+ if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
+ --mMetaDataBuffersToSubmit;
+ }
+ }
+}
+
bool DashCodec::allYourBuffersAreBelongToUs(
OMX_U32 portIndex) {
for (size_t i = 0; i < mBuffers[portIndex].size(); ++i) {
@@ -2295,20 +2437,6 @@ void DashCodec::sendFormatChange() {
CHECK_LE(rect->nLeft + rect->nWidth - 1, videoDef->nFrameWidth);
CHECK_LE(rect->nTop + rect->nHeight - 1, videoDef->nFrameHeight);
-#ifdef ANDROID_JB_MR2
- if( mSmoothStreaming ) {
- //call Update buffer geometry here
- ALOGE("Calling native window update buffer geometry");
- status_t err = mNativeWindow.get()->perform(mNativeWindow.get(),
- NATIVE_WINDOW_UPDATE_BUFFERS_GEOMETRY,
- videoDef->nFrameWidth, videoDef->nFrameHeight, def->format.video.eColorFormat);
- if( err != OK ) {
- ALOGE("native_window_update_buffers_geometry failed in SS mode %d", err);
- }
-
- }
-#endif
-
notify->setRect(
"crop",
rect->nLeft,
@@ -2380,18 +2508,6 @@ void DashCodec::sendFormatChange() {
mSentFormat = true;
}
-status_t DashCodec::InitSmoothStreaming() {
- status_t err = mOMX->setParameter(mNode, (OMX_INDEXTYPE)OMX_QcomIndexParamEnableSmoothStreaming,&err, sizeof(int32_t));
- if (err != OMX_ErrorNone) {
- ALOGE("InitSmoothStreaming setParam failed for extradata");
- return err;
- }
-
- ALOGW("InitSmoothStreaming - Smooth streaming mode enabled");
-
- return OK;
-}
-
void DashCodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", DashCodec::kWhatError);
@@ -2879,6 +2995,20 @@ void DashCodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
mCodec->mBufferStats.add(timeUs, stats);
#endif
+ if (mCodec->mStoreMetaDataInOutputBuffers) {
+ // try to submit an output buffer for each input buffer
+ PortMode outputMode = getPortMode(kPortIndexOutput);
+
+ ALOGV("MetaDataBuffersToSubmit=%u portMode=%s",
+ mCodec->mMetaDataBuffersToSubmit,
+ (outputMode == FREE_BUFFERS ? "FREE" :
+ outputMode == KEEP_BUFFERS ? "KEEP" : "RESUBMIT"));
+ if (outputMode == RESUBMIT_BUFFERS) {
+ CHECK_EQ(mCodec->submitOutputMetaDataBuffer(),
+ (status_t)OK);
+ }
+ }
+
CHECK_EQ(mCodec->mOMX->emptyBuffer(
mCodec->mNode,
bufferID,
@@ -2996,6 +3126,7 @@ bool DashCodec::BaseState::onOMXFillBufferDone(
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_COMPONENT);
+ info->mDequeuedAt = ++mCodec->mDequeueCounter;
info->mStatus = BufferInfo::OWNED_BY_US;
PortMode mode = getPortMode(kPortIndexOutput);
@@ -3029,11 +3160,8 @@ bool DashCodec::BaseState::onOMXFillBufferDone(
mCodec->mPortEOS[kPortIndexOutput] = true;
break;
}
-#ifdef ANDROID_JB_MR2
- if (!mCodec->mIsEncoder && !mCodec->mSentFormat && !mCodec->mSmoothStreaming) {
-#else
+
if (!mCodec->mIsEncoder && !mCodec->mSentFormat) {
-#endif
mCodec->sendFormatChange();
}
@@ -3059,13 +3187,6 @@ bool DashCodec::BaseState::onOMXFillBufferDone(
notify->setInt32("flags", flags);
sp<AMessage> reply =
new AMessage(kWhatOutputBufferDrained, mCodec->id());
-#ifdef ANDROID_JB_MR2
- if (!mCodec->mPostFormat && mCodec->mSmoothStreaming){
- ALOGV("Resolution will change from this buffer, set a flag");
- reply->setInt32("resChange", 1);
- mCodec->mPostFormat = true;
- }
-#endif
reply->setPointer("buffer-id", info->mBufferID);
@@ -3099,16 +3220,7 @@ void DashCodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
BufferInfo *info =
mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_DOWNSTREAM);
-#ifdef ANDROID_JB_MR2
- if (mCodec->mSmoothStreaming) {
- int32_t resChange = 0;
- if (msg->findInt32("resChange", &resChange) && resChange == 1) {
- ALOGV("Resolution change is sent to native window now ");
- mCodec->sendFormatChange();
- msg->setInt32("resChange", 0);
- }
- }
-#endif
+
int32_t render;
if (mCodec->mNativeWindow != NULL
&& msg->findInt32("render", &render) && render != 0) {
@@ -3350,6 +3462,9 @@ DashCodec::LoadedState::LoadedState(DashCodec *codec)
void DashCodec::LoadedState::stateEntered() {
ALOGV("[%s] Now Loaded", mCodec->mComponentName.c_str());
+mCodec->mDequeueCounter = 0;
+ mCodec->mMetaDataBuffersToSubmit = 0;
+
if (mCodec->mShutdownInProgress) {
bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
@@ -3423,27 +3538,6 @@ bool DashCodec::LoadedState::onConfigureComponent(
CHECK(mCodec->mNode != NULL);
int32_t value;
-#ifdef ANDROID_JB_MR2
- if (msg->findInt32("smooth-streaming", &value) && (value == 1) &&
- !strcmp("OMX.qcom.video.decoder.avc", mCodec->mComponentName.c_str())) {
-
- char value_ss[PROPERTY_VALUE_MAX];
- if (property_get("hls.disable.smooth.streaming", value_ss, NULL) &&
- (!strcasecmp(value_ss, "true") || !strcmp(value_ss, "1"))) {
-
- ALOGW("Dont enable Smooth streaming, disable property is set");
- } else {
- mCodec->mSmoothStreaming = true;
- status_t err = mCodec->InitSmoothStreaming();
- if (err != OK) {
- ALOGE("Error in enabling smooth streaming, ignore & disable ");
- mCodec->mSmoothStreaming = false;
- } else {
- ALOGI("Smooth streaming is enabled ");
- }
- }
- }
-#endif
if (msg->findInt32("secure-op", &value) && (value == 1)) {
mCodec->mFlags |= kFlagIsSecureOPOnly;
@@ -3615,7 +3709,20 @@ DashCodec::BaseState::PortMode DashCodec::ExecutingState::getPortMode(
return RESUBMIT_BUFFERS;
}
-void DashCodec::ExecutingState::submitOutputBuffers() {
+void DashCodec::ExecutingState::submitOutputMetaBuffers() {
+ // submit as many buffers as there are input buffers with the codec
+ // in case we are in port reconfiguring
+ for (size_t i = 0; i < mCodec->mBuffers[kPortIndexInput].size(); ++i) {
+ BufferInfo *info = &mCodec->mBuffers[kPortIndexInput].editItemAt(i);
+
+ if (info->mStatus == BufferInfo::OWNED_BY_COMPONENT) {
+ if (mCodec->submitOutputMetaDataBuffer() != OK)
+ break;
+ }
+ }
+}
+
+void DashCodec::ExecutingState::submitRegularOutputBuffers() {
for (size_t i = 0; i < mCodec->mBuffers[kPortIndexOutput].size(); ++i) {
BufferInfo *info = &mCodec->mBuffers[kPortIndexOutput].editItemAt(i);
@@ -3640,6 +3747,13 @@ void DashCodec::ExecutingState::submitOutputBuffers() {
}
}
+void DashCodec::ExecutingState::submitOutputBuffers() {
+ submitRegularOutputBuffers();
+ if (mCodec->mStoreMetaDataInOutputBuffers) {
+ submitOutputMetaBuffers();
+ }
+}
+
void DashCodec::ExecutingState::resume() {
if (mActive) {
ALOGV("[%s] We're already active, no need to resume.",
@@ -3747,6 +3861,7 @@ bool DashCodec::ExecutingState::onOMXEvent(
CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
+mCodec->mMetaDataBuffersToSubmit = 0;
ALOGV("Flush output port before disable");
CHECK_EQ(mCodec->mOMX->sendCommand(
mCodec->mNode, OMX_CommandFlush, kPortIndexOutput),
@@ -4143,6 +4258,10 @@ void DashCodec::FlushingState::changeStateIfWeOwnAllBuffers() {
if (mFlushComplete[kPortIndexInput]
&& mFlushComplete[kPortIndexOutput]
&& mCodec->allYourBuffersAreBelongToUs()) {
+ // We now own all buffers except possibly those still queued with
+ // the native window for rendering. Let's get those back as well.
+ mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
+
sp<AMessage> notify = mCodec->mNotify->dup();
notify->setInt32("what", DashCodec::kWhatFlushCompleted);
notify->post();
diff --git a/dashplayer/DashCodec.h b/dashplayer/DashCodec.h
index 39f717ef..692050a3 100644
--- a/dashplayer/DashCodec.h
+++ b/dashplayer/DashCodec.h
@@ -134,6 +134,7 @@ private:
IOMX::buffer_id mBufferID;
Status mStatus;
+ unsigned mDequeuedAt;
sp<ABuffer> mData;
sp<GraphicBuffer> mGraphicBuffer;
@@ -192,11 +193,19 @@ private:
bool mChannelMaskPresent;
int32_t mChannelMask;
+ unsigned mDequeueCounter;
+ bool mStoreMetaDataInOutputBuffers;
+ int32_t mMetaDataBuffersToSubmit;
status_t allocateBuffersOnPort(OMX_U32 portIndex);
status_t freeBuffersOnPort(OMX_U32 portIndex);
status_t freeBuffer(OMX_U32 portIndex, size_t i);
+ status_t configureOutputBuffersFromNativeWindow(
+ OMX_U32 *nBufferCount, OMX_U32 *nBufferSize,
+ OMX_U32 *nMinUndequeuedBuffers);
+ status_t allocateOutputMetaDataBuffers();
+ status_t submitOutputMetaDataBuffer();
status_t allocateOutputBuffersFromNativeWindow();
status_t cancelBufferToNativeWindow(BufferInfo *info);
status_t freeOutputBuffersNotOwnedByComponent();
@@ -266,7 +275,10 @@ private:
bool allYourBuffersAreBelongToUs();
+ void waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
+
size_t countBuffersOwnedByComponent(OMX_U32 portIndex) const;
+ size_t countBuffersOwnedByNativeWindow() const;
void deferMessage(const sp<AMessage> &msg);
void processDeferredMessages();
@@ -278,9 +290,6 @@ private:
status_t internalError = UNKNOWN_ERROR);
status_t requestIDRFrame();
-
- status_t InitSmoothStreaming();
- bool mSmoothStreaming;
Vector<OMX_PARAM_PORTDEFINITIONTYPE*> mFormats;
Vector<OMX_CONFIG_RECTTYPE*> mOutputCrops;
DISALLOW_EVIL_CONSTRUCTORS(DashCodec);