summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/OMXCodec.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'media/libstagefright/OMXCodec.cpp')
-rwxr-xr-xmedia/libstagefright/OMXCodec.cpp184
1 files changed, 78 insertions, 106 deletions
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index a6636a1..d0e306c 100755
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -147,12 +147,13 @@ static bool IsSoftwareCodec(const char *componentName) {
// A sort order in which OMX software codecs are first, followed
// by other (non-OMX) software codecs, followed by everything else.
static int CompareSoftwareCodecsFirst(
- const String8 *elem1, const String8 *elem2) {
- bool isOMX1 = !strncmp(elem1->string(), "OMX.", 4);
- bool isOMX2 = !strncmp(elem2->string(), "OMX.", 4);
+ const OMXCodec::CodecNameAndQuirks *elem1,
+ const OMXCodec::CodecNameAndQuirks *elem2) {
+ bool isOMX1 = !strncmp(elem1->mName.string(), "OMX.", 4);
+ bool isOMX2 = !strncmp(elem2->mName.string(), "OMX.", 4);
- bool isSoftwareCodec1 = IsSoftwareCodec(elem1->string());
- bool isSoftwareCodec2 = IsSoftwareCodec(elem2->string());
+ bool isSoftwareCodec1 = IsSoftwareCodec(elem1->mName.string());
+ bool isSoftwareCodec2 = IsSoftwareCodec(elem2->mName.string());
if (isSoftwareCodec1) {
if (!isSoftwareCodec2) { return -1; }
@@ -182,14 +183,9 @@ void OMXCodec::findMatchingCodecs(
const char *mime,
bool createEncoder, const char *matchComponentName,
uint32_t flags,
- Vector<String8> *matchingCodecs,
- Vector<uint32_t> *matchingCodecQuirks) {
+ Vector<CodecNameAndQuirks> *matchingCodecs) {
matchingCodecs->clear();
- if (matchingCodecQuirks) {
- matchingCodecQuirks->clear();
- }
-
const MediaCodecList *list = MediaCodecList::getInstance();
if (list == NULL) {
return;
@@ -221,11 +217,13 @@ void OMXCodec::findMatchingCodecs(
((flags & kHardwareCodecsOnly) && !IsSoftwareCodec(componentName)) ||
(!(flags & (kSoftwareCodecsOnly | kHardwareCodecsOnly)))) {
- matchingCodecs->push(String8(componentName));
+ ssize_t index = matchingCodecs->add();
+ CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index);
+ entry->mName = String8(componentName);
+ entry->mQuirks = getComponentQuirks(list, matchIndex);
- if (matchingCodecQuirks) {
- matchingCodecQuirks->push(getComponentQuirks(list, matchIndex));
- }
+ ALOGV("matching '%s' quirks 0x%08x",
+ entry->mName.string(), entry->mQuirks);
}
}
@@ -294,13 +292,14 @@ sp<MediaSource> OMXCodec::Create(
bool success = meta->findCString(kKeyMIMEType, &mime);
CHECK(success);
- Vector<String8> matchingCodecs;
- Vector<uint32_t> matchingCodecQuirks;
+ Vector<CodecNameAndQuirks> matchingCodecs;
findMatchingCodecs(
- mime, createEncoder, matchComponentName, flags,
- &matchingCodecs, &matchingCodecQuirks);
+ mime, createEncoder, matchComponentName, flags, &matchingCodecs);
if (matchingCodecs.isEmpty()) {
+ ALOGV("No matching codecs! (mime: %s, createEncoder: %s, "
+ "matchComponentName: %s, flags: 0x%x)",
+ mime, createEncoder ? "true" : "false", matchComponentName, flags);
return NULL;
}
@@ -308,8 +307,8 @@ sp<MediaSource> OMXCodec::Create(
IOMX::node_id node = 0;
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
- const char *componentNameBase = matchingCodecs[i].string();
- uint32_t quirks = matchingCodecQuirks[i];
+ const char *componentNameBase = matchingCodecs[i].mName.string();
+ uint32_t quirks = matchingCodecs[i].mQuirks;
const char *componentName = componentNameBase;
AString tmp;
@@ -569,6 +568,8 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) {
if ((mFlags & kClientNeedsFramebuffer)
&& !strncmp(mComponentName, "OMX.SEC.", 8)) {
+ // This appears to no longer be needed???
+
OMX_INDEXTYPE index;
status_t err =
@@ -1214,7 +1215,8 @@ status_t OMXCodec::setVideoOutputFormat(
|| format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
|| format.eColorFormat == OMX_COLOR_FormatCbYCrY
|| format.eColorFormat == OMX_TI_COLOR_FormatYUV420PackedSemiPlanar
- || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar);
+ || format.eColorFormat == OMX_QCOM_COLOR_FormatYVU420SemiPlanar
+ || format.eColorFormat == OMX_QCOM_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka);
err = mOMX->setParameter(
mNode, OMX_IndexParamVideoPortFormat,
@@ -1776,7 +1778,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
// Dequeue buffers and send them to OMX
for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) {
ANativeWindowBuffer* buf;
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (err != 0) {
ALOGE("dequeueBuffer failed: %s (%d)", strerror(-err), -err);
break;
@@ -1832,7 +1834,7 @@ status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
int err = mNativeWindow->cancelBuffer(
- mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get());
+ mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
if (err != 0) {
CODEC_LOGE("cancelBuffer failed w/ error 0x%08x", err);
@@ -1846,7 +1848,8 @@ status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
OMXCodec::BufferInfo* OMXCodec::dequeueBufferFromNativeWindow() {
// Dequeue the next buffer from the native window.
ANativeWindowBuffer* buf;
- int err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf);
+ int fenceFd = -1;
+ int err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &buf);
if (err != 0) {
CODEC_LOGE("dequeueBuffer failed w/ error 0x%08x", err);
@@ -1950,7 +1953,8 @@ status_t OMXCodec::pushBlankBuffersToNativeWindow() {
// on the screen and then been replaced, so an previous video frames are
// guaranteed NOT to be currently displayed.
for (int i = 0; i < numBufs + 1; i++) {
- err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &anb);
+ int fenceFd = -1;
+ err = native_window_dequeue_buffer_and_wait(mNativeWindow.get(), &anb);
if (err != NO_ERROR) {
ALOGE("error pushing blank frames: dequeueBuffer failed: %s (%d)",
strerror(-err), -err);
@@ -1958,13 +1962,6 @@ status_t OMXCodec::pushBlankBuffersToNativeWindow() {
}
sp<GraphicBuffer> buf(new GraphicBuffer(anb, false));
- err = mNativeWindow->lockBuffer(mNativeWindow.get(),
- buf->getNativeBuffer());
- if (err != NO_ERROR) {
- ALOGE("error pushing blank frames: lockBuffer failed: %s (%d)",
- strerror(-err), -err);
- goto error;
- }
// Fill the buffer with the a 1x1 checkerboard pattern ;)
uint32_t* img = NULL;
@@ -1985,7 +1982,7 @@ status_t OMXCodec::pushBlankBuffersToNativeWindow() {
}
err = mNativeWindow->queueBuffer(mNativeWindow.get(),
- buf->getNativeBuffer());
+ buf->getNativeBuffer(), -1);
if (err != NO_ERROR) {
ALOGE("error pushing blank frames: queueBuffer failed: %s (%d)",
strerror(-err), -err);
@@ -2000,7 +1997,7 @@ error:
if (err != NO_ERROR) {
// Clean up after an error.
if (anb != NULL) {
- mNativeWindow->cancelBuffer(mNativeWindow.get(), anb);
+ mNativeWindow->cancelBuffer(mNativeWindow.get(), anb, -1);
}
native_window_api_disconnect(mNativeWindow.get(),
@@ -2048,11 +2045,13 @@ int64_t OMXCodec::getDecodingTimeUs() {
}
void OMXCodec::on_message(const omx_message &msg) {
- // even in error state, we still need to process EMPTY_BUFFER_DONE
- // and FILL_BUFFER_DONE event, or we will run into mediaserver crash issue
if (mState == ERROR) {
+ /*
+ * only drop EVENT messages, EBD and FBD are still
+ * processed for bookkeeping purposes
+ */
if (msg.type == omx_message::EVENT) {
- ALOGW("Dropping OMX message - we're in ERROR state.");
+ ALOGW("Dropping OMX EVENT message - we're in ERROR state.");
return;
}
}
@@ -2090,13 +2089,6 @@ void OMXCodec::on_message(const omx_message &msg) {
// Buffer could not be released until empty buffer done is called.
if (info->mMediaBuffer != NULL) {
- if (mIsEncoder &&
- (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
- // If zero-copy mode is enabled this will send the
- // input buffer back to the upstream source.
- restorePatchedDataPointer(info);
- }
-
info->mMediaBuffer->release();
info->mMediaBuffer = NULL;
}
@@ -3069,39 +3061,24 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) {
}
bool releaseBuffer = true;
- if (mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames)) {
- CHECK(mOMXLivesLocally && offset == 0);
-
- OMX_BUFFERHEADERTYPE *header =
- (OMX_BUFFERHEADERTYPE *)info->mBuffer;
-
- CHECK(header->pBuffer == info->mData);
-
- header->pBuffer =
- (OMX_U8 *)srcBuffer->data() + srcBuffer->range_offset();
-
- releaseBuffer = false;
- info->mMediaBuffer = srcBuffer;
- } else {
- if (mFlags & kStoreMetaDataInVideoBuffers) {
+ if (mFlags & kStoreMetaDataInVideoBuffers) {
releaseBuffer = false;
info->mMediaBuffer = srcBuffer;
- }
+ }
- if (mFlags & kUseSecureInputBuffers) {
+ if (mFlags & kUseSecureInputBuffers) {
// Data in "info" is already provided at this time.
releaseBuffer = false;
CHECK(info->mMediaBuffer == NULL);
info->mMediaBuffer = srcBuffer;
- } else {
- CHECK(srcBuffer->data() != NULL) ;
- memcpy((uint8_t *)info->mData + offset,
- (const uint8_t *)srcBuffer->data()
- + srcBuffer->range_offset(),
- srcBuffer->range_length());
- }
+ } else {
+ CHECK(srcBuffer->data() != NULL) ;
+ memcpy((uint8_t *)info->mData + offset,
+ (const uint8_t *)srcBuffer->data()
+ + srcBuffer->range_offset(),
+ srcBuffer->range_length());
}
int64_t lastBufferTimeUs;
@@ -3203,23 +3180,6 @@ void OMXCodec::fillOutputBuffer(BufferInfo *info) {
return;
}
- if (info->mMediaBuffer != NULL) {
- sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
- if (graphicBuffer != 0) {
- // When using a native buffer we need to lock the buffer before
- // giving it to OMX.
- CODEC_LOGV("Calling lockBuffer on %p", info->mBuffer);
- int err = mNativeWindow->lockBuffer(mNativeWindow.get(),
- graphicBuffer.get());
- if (err != 0) {
- CODEC_LOGE("lockBuffer failed w/ error 0x%08x", err);
-
- setState(ERROR);
- return;
- }
- }
- }
-
CODEC_LOGV("Calling fillBuffer on buffer %p", info->mBuffer);
status_t err = mOMX->fillBuffer(mNode, info->mBuffer);
@@ -3639,11 +3599,6 @@ status_t OMXCodec::start(MetaData *meta) {
}
params->setInt64(kKeyTime, startTimeUs);
}
- status_t err = mSource->start(params.get());
-
- if (err != OK) {
- return err;
- }
mCodecSpecificDataIndex = 0;
mInitialBufferSubmit = true;
@@ -3656,13 +3611,42 @@ status_t OMXCodec::start(MetaData *meta) {
mFilledBuffers.clear();
mPaused = false;
+ status_t err;
+ if (mIsEncoder) {
+ // Calling init() before starting its source so that we can configure,
+ // if supported, the source to use exactly the same number of input
+ // buffers as requested by the encoder.
+ if ((err = init()) != OK) {
+ return err;
+ }
+
+ params->setInt32(kKeyNumBuffers, mPortBuffers[kPortIndexInput].size());
+ err = mSource->start(params.get());
+ if (err != OK) {
+ stopOmxComponent_l();
+ }
+ return err;
+ }
+
+ // Decoder case
+ if ((err = mSource->start(params.get())) != OK) {
+ return err;
+ }
return init();
}
status_t OMXCodec::stop() {
CODEC_LOGV("stop mState=%d", mState);
-
Mutex::Autolock autoLock(mLock);
+ status_t err = stopOmxComponent_l();
+ mSource->stop();
+
+ CODEC_LOGV("stopped in state %d", mState);
+ return err;
+}
+
+status_t OMXCodec::stopOmxComponent_l() {
+ CODEC_LOGV("stopOmxComponent_l mState=%d", mState);
while (isIntermediateState(mState)) {
mAsyncCompletion.wait(mLock);
@@ -3760,10 +3744,6 @@ status_t OMXCodec::stop() {
mLeftOverBuffer = NULL;
}
- mSource->stop();
-
- CODEC_LOGV("stopped in state %d", mState);
-
return OK;
}
@@ -4515,7 +4495,7 @@ status_t QueryCodecs(
const sp<IOMX> &omx,
const char *mime, bool queryDecoders, bool hwCodecOnly,
Vector<CodecCapabilities> *results) {
- Vector<String8> matchingCodecs;
+ Vector<OMXCodec::CodecNameAndQuirks> matchingCodecs;
results->clear();
OMXCodec::findMatchingCodecs(mime,
@@ -4525,7 +4505,7 @@ status_t QueryCodecs(
&matchingCodecs);
for (size_t c = 0; c < matchingCodecs.size(); c++) {
- const char *componentName = matchingCodecs.itemAt(c).string();
+ const char *componentName = matchingCodecs.itemAt(c).mName.string();
results->push();
CodecCapabilities *caps = &results->editItemAt(results->size() - 1);
@@ -4612,14 +4592,6 @@ status_t QueryCodecs(
return QueryCodecs(omx, mimeType, queryDecoders, false /*hwCodecOnly*/, results);
}
-void OMXCodec::restorePatchedDataPointer(BufferInfo *info) {
- CHECK(mIsEncoder && (mQuirks & kAvoidMemcopyInputRecordingFrames));
- CHECK(mOMXLivesLocally);
-
- OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)info->mBuffer;
- header->pBuffer = (OMX_U8 *)info->mData;
-}
-
// These are supposed be equivalent to the logic in
// "audio_channel_out_mask_from_count".
status_t getOMXChannelMapping(size_t numChannels, OMX_AUDIO_CHANNELTYPE map[]) {