diff options
Diffstat (limited to 'media/libstagefright/OMXCodec.cpp')
-rw-r--r-- | media/libstagefright/OMXCodec.cpp | 293 |
1 files changed, 198 insertions, 95 deletions
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 625922f..a8806c8 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -14,8 +14,15 @@ * limitations under the License. */ +#include <inttypes.h> + //#define LOG_NDEBUG 0 #define LOG_TAG "OMXCodec" + +#ifdef __LP64__ +#define OMX_ANDROID_COMPILE_AS_32BIT_ON_64BIT_PLATFORMS +#endif + #include <utils/Log.h> #include "include/AACEncoder.h" @@ -28,6 +35,7 @@ #include <HardwareAPI.h> #include <media/stagefright/foundation/ADebug.h> #include <media/IMediaPlayerService.h> +#include <media/stagefright/ACodec.h> #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> #include <media/stagefright/MediaDefs.h> @@ -94,6 +102,7 @@ static sp<MediaSource> InstantiateSoftwareEncoder( #define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__) #define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__) +#define CODEC_LOGW(x, ...) ALOGW("[%s] "x, mComponentName, ##__VA_ARGS__) #define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__) struct OMXCodecObserver : public BnOMXObserver { @@ -127,6 +136,7 @@ private: template<class T> static void InitOMXParams(T *params) { + COMPILE_TIME_ASSERT_FUNCTION_SCOPE(sizeof(OMX_PTR) == 4); // check OMX_PTR is 4 bytes. params->nSize = sizeof(T); params->nVersion.s.nVersionMajor = 1; params->nVersion.s.nVersionMinor = 0; @@ -188,7 +198,7 @@ void OMXCodec::findMatchingCodecs( Vector<CodecNameAndQuirks> *matchingCodecs) { matchingCodecs->clear(); - const MediaCodecList *list = MediaCodecList::getInstance(); + const sp<IMediaCodecList> list = MediaCodecList::getInstance(); if (list == NULL) { return; } @@ -204,7 +214,9 @@ void OMXCodec::findMatchingCodecs( index = matchIndex + 1; - const char *componentName = list->getCodecName(matchIndex); + const sp<MediaCodecInfo> info = list->getCodecInfo(matchIndex); + CHECK(info != NULL); + const char *componentName = info->getCodecName(); // If a specific codec is requested, skip the non-matching ones. if (matchComponentName && strcmp(componentName, matchComponentName)) { @@ -222,7 +234,7 @@ void OMXCodec::findMatchingCodecs( ssize_t index = matchingCodecs->add(); CodecNameAndQuirks *entry = &matchingCodecs->editItemAt(index); entry->mName = String8(componentName); - entry->mQuirks = getComponentQuirks(list, matchIndex); + entry->mQuirks = getComponentQuirks(info); ALOGV("matching '%s' quirks 0x%08x", entry->mName.string(), entry->mQuirks); @@ -236,18 +248,15 @@ void OMXCodec::findMatchingCodecs( // static uint32_t OMXCodec::getComponentQuirks( - const MediaCodecList *list, size_t index) { + const sp<MediaCodecInfo> &info) { uint32_t quirks = 0; - if (list->codecHasQuirk( - index, "requires-allocate-on-input-ports")) { + if (info->hasQuirk("requires-allocate-on-input-ports")) { quirks |= kRequiresAllocateBufferOnInputPorts; } - if (list->codecHasQuirk( - index, "requires-allocate-on-output-ports")) { + if (info->hasQuirk("requires-allocate-on-output-ports")) { quirks |= kRequiresAllocateBufferOnOutputPorts; } - if (list->codecHasQuirk( - index, "output-buffers-are-unreadable")) { + if (info->hasQuirk("output-buffers-are-unreadable")) { quirks |= kOutputBuffersAreUnreadable; } @@ -256,8 +265,7 @@ uint32_t OMXCodec::getComponentQuirks( // static bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) { - const MediaCodecList *list = MediaCodecList::getInstance(); - + const sp<IMediaCodecList> list = MediaCodecList::getInstance(); if (list == NULL) { return false; } @@ -268,7 +276,9 @@ bool OMXCodec::findCodecQuirks(const char *componentName, uint32_t *quirks) { return false; } - *quirks = getComponentQuirks(list, index); + const sp<MediaCodecInfo> info = list->getCodecInfo(index); + CHECK(info != NULL); + *quirks = getComponentQuirks(info); return true; } @@ -372,6 +382,57 @@ sp<MediaSource> OMXCodec::Create( return NULL; } +status_t OMXCodec::parseHEVCCodecSpecificData( + const void *data, size_t size, + unsigned *profile, unsigned *level) { + const uint8_t *ptr = (const uint8_t *)data; + + // verify minimum size and configurationVersion == 1. + if (size < 7 || ptr[0] != 1) { + return ERROR_MALFORMED; + } + + *profile = (ptr[1] & 31); + *level = ptr[12]; + + ptr += 22; + size -= 22; + + size_t numofArrays = (char)ptr[0]; + ptr += 1; + size -= 1; + size_t j = 0, i = 0; + for (i = 0; i < numofArrays; i++) { + ptr += 1; + size -= 1; + + // Num of nals + size_t numofNals = U16_AT(ptr); + ptr += 2; + size -= 2; + + for (j = 0;j < numofNals;j++) { + if (size < 2) { + return ERROR_MALFORMED; + } + + size_t length = U16_AT(ptr); + + ptr += 2; + size -= 2; + + if (size < length) { + return ERROR_MALFORMED; + } + addCodecSpecificData(ptr, length); + + ptr += length; + size -= length; + } + } + return OK; +} + status_t OMXCodec::parseAVCCodecSpecificData( const void *data, size_t size, unsigned *profile, unsigned *level) { @@ -484,11 +545,32 @@ status_t OMXCodec::configureCodec(const sp<MetaData> &meta) { CODEC_LOGI( "AVC profile = %u (%s), level = %u", profile, AVCProfileToString(profile), level); + } else if (meta->findData(kKeyHVCC, &type, &data, &size)) { + // Parse the HEVCDecoderConfigurationRecord + + unsigned profile, level; + status_t err; + if ((err = parseHEVCCodecSpecificData( + data, size, &profile, &level)) != OK) { + ALOGE("Malformed HEVC codec specific data."); + return err; + } + + CODEC_LOGI( + "HEVC profile = %u , level = %u", + profile, level); } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) { addCodecSpecificData(data, size); CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size)); addCodecSpecificData(data, size); + } else if (meta->findData(kKeyOpusHeader, &type, &data, &size)) { + addCodecSpecificData(data, size); + + CHECK(meta->findData(kKeyOpusCodecDelay, &type, &data, &size)); + addCodecSpecificData(data, size); + CHECK(meta->findData(kKeyOpusSeekPreRoll, &type, &data, &size)); + addCodecSpecificData(data, size); } } @@ -679,7 +761,7 @@ status_t OMXCodec::setVideoPortFormatType( // CHECK_EQ(format.nIndex, index); #if 1 - CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d", + CODEC_LOGV("portIndex: %u, index: %u, eCompressionFormat=%d eColorFormat=%d", portIndex, index, format.eCompressionFormat, format.eColorFormat); #endif @@ -781,7 +863,7 @@ status_t OMXCodec::isColorFormatSupported( portFormat.nIndex = index; if (index >= kMaxColorFormatSupported) { - CODEC_LOGE("More than %ld color formats are supported???", index); + CODEC_LOGE("More than %u color formats are supported???", index); break; } } @@ -806,6 +888,8 @@ void OMXCodec::setVideoInputFormat( OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused; if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) { compressionFormat = OMX_VIDEO_CodingAVC; + } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) { + compressionFormat = OMX_VIDEO_CodingHEVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG4; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { @@ -910,7 +994,6 @@ static OMX_U32 setPFramesSpacing(int32_t iFramesInterval, int32_t frameRate) { return 0; } OMX_U32 ret = frameRate * iFramesInterval - 1; - CHECK(ret > 1); return ret; } @@ -1201,6 +1284,8 @@ status_t OMXCodec::setVideoOutputFormat( compressionFormat = OMX_VIDEO_CodingAVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) { compressionFormat = OMX_VIDEO_CodingMPEG4; + } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mime)) { + compressionFormat = OMX_VIDEO_CodingHEVC; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_H263, mime)) { compressionFormat = OMX_VIDEO_CodingH263; } else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_VP8, mime)) { @@ -1387,12 +1472,16 @@ void OMXCodec::setComponentRole( "audio_decoder.aac", "audio_encoder.aac" }, { MEDIA_MIMETYPE_AUDIO_VORBIS, "audio_decoder.vorbis", "audio_encoder.vorbis" }, + { MEDIA_MIMETYPE_AUDIO_OPUS, + "audio_decoder.opus", "audio_encoder.opus" }, { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "audio_decoder.g711mlaw", "audio_encoder.g711mlaw" }, { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "audio_decoder.g711alaw", "audio_encoder.g711alaw" }, { MEDIA_MIMETYPE_VIDEO_AVC, "video_decoder.avc", "video_encoder.avc" }, + { MEDIA_MIMETYPE_VIDEO_HEVC, + "video_decoder.hevc", "video_encoder.hevc" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "video_decoder.mpeg4", "video_encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_H263, @@ -1462,7 +1551,7 @@ OMXCodec::~OMXCodec() { status_t err = mOMX->freeNode(mNode); CHECK_EQ(err, (status_t)OK); - mNode = NULL; + mNode = 0; setState(DEAD); clearCodecSpecificData(); @@ -1615,15 +1704,15 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) { info.mMediaBuffer = NULL; if (portIndex == kPortIndexOutput) { - if (!(mOMXLivesLocally - && (mQuirks & kRequiresAllocateBufferOnOutputPorts) - && (mQuirks & kDefersOutputBufferAllocation))) { - // If the node does not fill in the buffer ptr at this time, - // we will defer creating the MediaBuffer until receiving - // the first FILL_BUFFER_DONE notification instead. - info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); - info.mMediaBuffer->setObserver(this); - } + // Fail deferred MediaBuffer creation until FILL_BUFFER_DONE; + // this legacy mode is no longer supported. + LOG_ALWAYS_FATAL_IF((mOMXLivesLocally + && (mQuirks & kRequiresAllocateBufferOnOutputPorts) + && (mQuirks & kDefersOutputBufferAllocation)), + "allocateBuffersOnPort cannot defer buffer allocation"); + + info.mMediaBuffer = new MediaBuffer(info.mData, info.mSize); + info.mMediaBuffer->setObserver(this); } mPortBuffers[portIndex].push(info); @@ -1794,21 +1883,42 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { strerror(-err), -err); return err; } - - // 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; + // FIXME: assume that surface is controlled by app (native window + // returns the number for the case when surface is not controlled by app) + // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported + // For now, try to allocate 1 more buffer, but don't fail if unsuccessful + + // Use conservative allocation while also trying to reduce starvation + // + // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the + // minimum needed for the consumer to be able to work + // 2. try to allocate two (2) additional buffers to reduce starvation from + // the consumer + // plus an extra buffer to account for incorrect minUndequeuedBufs + CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1", + def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); + + for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) { + OMX_U32 newBufferCount = + def.nBufferCountMin + minUndequeuedBufs + extraBuffers; def.nBufferCountActual = newBufferCount; err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); - if (err != OK) { - CODEC_LOGE("setting nBufferCountActual to %lu failed: %d", - newBufferCount, err); + + if (err == OK) { + minUndequeuedBufs += extraBuffers; + break; + } + + CODEC_LOGW("setting nBufferCountActual to %u failed: %d", + newBufferCount, err); + /* exit condition */ + if (extraBuffers == 0) { return err; } } + CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1", + def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs); err = native_window_set_buffer_count( mNativeWindow.get(), def.nBufferCountActual); @@ -1818,7 +1928,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { return err; } - CODEC_LOGV("allocating %lu buffers from a native window of size %lu on " + CODEC_LOGV("allocating %u buffers from a native window of size %u on " "output port", def.nBufferCountActual, def.nBufferSize); // Dequeue buffers and send them to OMX @@ -1851,7 +1961,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId; - CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)", + CODEC_LOGV("registered graphic buffer with ID %u (pointer = %p)", bufferId, graphicBuffer.get()); } @@ -1878,7 +1988,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) { CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US); - CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer); + CODEC_LOGV("Calling cancelBuffer on buffer %u", info->mBuffer); int err = mNativeWindow->cancelBuffer( mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1); if (err != 0) { @@ -2116,7 +2226,7 @@ void OMXCodec::on_message(const omx_message &msg) { { IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; - CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer); + CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %u)", buffer); Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput]; size_t i = 0; @@ -2126,7 +2236,7 @@ void OMXCodec::on_message(const omx_message &msg) { CHECK(i < buffers->size()); if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) { - ALOGW("We already own input buffer %p, yet received " + ALOGW("We already own input buffer %u, yet received " "an EMPTY_BUFFER_DONE.", buffer); } @@ -2140,7 +2250,7 @@ void OMXCodec::on_message(const omx_message &msg) { } if (mPortStatus[kPortIndexInput] == DISABLING) { - CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); + CODEC_LOGV("Port is disabled, freeing buffer %u", buffer); status_t err = freeBuffer(kPortIndexInput, i); CHECK_EQ(err, (status_t)OK); @@ -2162,7 +2272,7 @@ void OMXCodec::on_message(const omx_message &msg) { IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer; OMX_U32 flags = msg.u.extended_buffer_data.flags; - CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))", + CODEC_LOGV("FILL_BUFFER_DONE(buffer: %u, size: %u, flags: 0x%08x, timestamp: %lld us (%.2f secs))", buffer, msg.u.extended_buffer_data.range_length, flags, @@ -2179,14 +2289,14 @@ void OMXCodec::on_message(const omx_message &msg) { BufferInfo *info = &buffers->editItemAt(i); if (info->mStatus != OWNED_BY_COMPONENT) { - ALOGW("We already own output buffer %p, yet received " + ALOGW("We already own output buffer %u, yet received " "a FILL_BUFFER_DONE.", buffer); } info->mStatus = OWNED_BY_US; if (mPortStatus[kPortIndexOutput] == DISABLING) { - CODEC_LOGV("Port is disabled, freeing buffer %p", buffer); + CODEC_LOGV("Port is disabled, freeing buffer %u", buffer); status_t err = freeBuffer(kPortIndexOutput, i); CHECK_EQ(err, (status_t)OK); @@ -2201,22 +2311,6 @@ void OMXCodec::on_message(const omx_message &msg) { } else if (mPortStatus[kPortIndexOutput] != SHUTTING_DOWN) { CHECK_EQ((int)mPortStatus[kPortIndexOutput], (int)ENABLED); - if (info->mMediaBuffer == NULL) { - CHECK(mOMXLivesLocally); - CHECK(mQuirks & kRequiresAllocateBufferOnOutputPorts); - CHECK(mQuirks & kDefersOutputBufferAllocation); - - // The qcom video decoders on Nexus don't actually allocate - // output buffer memory on a call to OMX_AllocateBuffer - // the "pBuffer" member of the OMX_BUFFERHEADERTYPE - // structure is only filled in later. - - info->mMediaBuffer = new MediaBuffer( - msg.u.extended_buffer_data.data_ptr, - info->mSize); - info->mMediaBuffer->setObserver(this); - } - MediaBuffer *buffer = info->mMediaBuffer; bool isGraphicBuffer = buffer->graphicBuffer() != NULL; @@ -2251,11 +2345,7 @@ void OMXCodec::on_message(const omx_message &msg) { buffer->meta_data()->setInt32(kKeyIsUnreadable, true); } - buffer->meta_data()->setPointer( - kKeyPlatformPrivate, - msg.u.extended_buffer_data.platform_private); - - buffer->meta_data()->setPointer( + buffer->meta_data()->setInt32( kKeyBufferID, msg.u.extended_buffer_data.buffer); @@ -2397,7 +2487,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { case OMX_EventError: { - CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2); + CODEC_LOGE("OMX_EventError(0x%08x, %u)", data1, data2); setState(ERROR); break; @@ -2405,16 +2495,10 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { case OMX_EventPortSettingsChanged: { - CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)", + CODEC_LOGV("OMX_EventPortSettingsChanged(port=%u, data2=0x%08x)", data1, data2); if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) { - // There is no need to check whether mFilledBuffers is empty or not - // when the OMX_EventPortSettingsChanged is not meant for reallocating - // the output buffers. - if (data1 == kPortIndexOutput) { - CHECK(mFilledBuffers.empty()); - } onPortSettingsChanged(data1); } else if (data1 == kPortIndexOutput && (data2 == OMX_IndexConfigCommonOutputCrop || @@ -2445,7 +2529,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { // The scale is in 16.16 format. // scale 1.0 = 0x010000. When there is no // need to change the display, skip it. - ALOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx", + ALOGV("Get OMX_IndexConfigScale: 0x%x/0x%x", scale.xWidth, scale.xHeight); if (scale.xWidth != 0x010000) { @@ -2479,7 +2563,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) { default: { - CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2); + CODEC_LOGV("EVENT(%d, %u, %u)", event, data1, data2); break; } } @@ -2496,7 +2580,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { case OMX_CommandPortDisable: { OMX_U32 portIndex = data; - CODEC_LOGV("PORT_DISABLED(%ld)", portIndex); + CODEC_LOGV("PORT_DISABLED(%u)", portIndex); CHECK(mState == EXECUTING || mState == RECONFIGURING); CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING); @@ -2520,7 +2604,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { status_t err = enablePortAsync(portIndex); if (err != OK) { - CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err); + CODEC_LOGE("enablePortAsync(%u) failed (err = %d)", portIndex, err); setState(ERROR); } else { err = allocateBuffersOnPort(portIndex); @@ -2541,7 +2625,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { case OMX_CommandPortEnable: { OMX_U32 portIndex = data; - CODEC_LOGV("PORT_ENABLED(%ld)", portIndex); + CODEC_LOGV("PORT_ENABLED(%u)", portIndex); CHECK(mState == EXECUTING || mState == RECONFIGURING); CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING); @@ -2562,7 +2646,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) { { OMX_U32 portIndex = data; - CODEC_LOGV("FLUSH_DONE(%ld)", portIndex); + CODEC_LOGV("FLUSH_DONE(%u)", portIndex); CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN); mPortStatus[portIndex] = ENABLED; @@ -2808,7 +2892,7 @@ status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) { void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) { CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex); - CHECK_EQ((int)mState, (int)EXECUTING); + CHECK(mState == EXECUTING || mState == EXECUTING_TO_IDLE); CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput); CHECK(!mOutputPortSettingsChangedPending); @@ -2990,7 +3074,8 @@ bool OMXCodec::drainInputBuffer(BufferInfo *info) { size_t size = specific->mSize; - if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) + if ((!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mMIME) || + !strcasecmp(MEDIA_MIMETYPE_VIDEO_HEVC, mMIME)) && !(mQuirks & kWantsNALFragments)) { static const uint8_t kNALStartCode[4] = { 0x00, 0x00, 0x00, 0x01 }; @@ -3880,7 +3965,7 @@ status_t OMXCodec::read( return UNKNOWN_ERROR; } - CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); + CODEC_LOGV("seeking to %" PRId64 " us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6); mSignalledEOS = false; @@ -4125,6 +4210,7 @@ static const char *audioCodingTypeString(OMX_AUDIO_CODINGTYPE type) { "OMX_AUDIO_CodingMP3", "OMX_AUDIO_CodingSBC", "OMX_AUDIO_CodingVORBIS", + "OMX_AUDIO_CodingOPUS", "OMX_AUDIO_CodingWMA", "OMX_AUDIO_CodingRA", "OMX_AUDIO_CodingMIDI", @@ -4219,9 +4305,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput) || (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput)); - printf(" nBufferCountActual = %ld\n", def.nBufferCountActual); - printf(" nBufferCountMin = %ld\n", def.nBufferCountMin); - printf(" nBufferSize = %ld\n", def.nBufferSize); + printf(" nBufferCountActual = %" PRIu32 "\n", def.nBufferCountActual); + printf(" nBufferCountMin = %" PRIu32 "\n", def.nBufferCountMin); + printf(" nBufferSize = %" PRIu32 "\n", def.nBufferSize); switch (def.eDomain) { case OMX_PortDomainImage: @@ -4230,9 +4316,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { printf("\n"); printf(" // Image\n"); - printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth); - printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight); - printf(" nStride = %ld\n", imageDef->nStride); + printf(" nFrameWidth = %" PRIu32 "\n", imageDef->nFrameWidth); + printf(" nFrameHeight = %" PRIu32 "\n", imageDef->nFrameHeight); + printf(" nStride = %" PRIu32 "\n", imageDef->nStride); printf(" eCompressionFormat = %s\n", imageCompressionFormatString(imageDef->eCompressionFormat)); @@ -4249,9 +4335,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { printf("\n"); printf(" // Video\n"); - printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth); - printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight); - printf(" nStride = %ld\n", videoDef->nStride); + printf(" nFrameWidth = %" PRIu32 "\n", videoDef->nFrameWidth); + printf(" nFrameHeight = %" PRIu32 "\n", videoDef->nFrameHeight); + printf(" nStride = %" PRIu32 "\n", videoDef->nStride); printf(" eCompressionFormat = %s\n", videoCompressionFormatString(videoDef->eCompressionFormat)); @@ -4280,10 +4366,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); CHECK_EQ(err, (status_t)OK); - printf(" nSamplingRate = %ld\n", params.nSamplingRate); - printf(" nChannels = %ld\n", params.nChannels); + printf(" nSamplingRate = %" PRIu32 "\n", params.nSamplingRate); + printf(" nChannels = %" PRIu32 "\n", params.nChannels); printf(" bInterleaved = %d\n", params.bInterleaved); - printf(" nBitPerSample = %ld\n", params.nBitPerSample); + printf(" nBitPerSample = %" PRIu32 "\n", params.nBitPerSample); printf(" eNumData = %s\n", params.eNumData == OMX_NumericalDataSigned @@ -4299,7 +4385,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) { mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr)); CHECK_EQ(err, (status_t)OK); - printf(" nChannels = %ld\n", amr.nChannels); + printf(" nChannels = %" PRIu32 "\n", amr.nChannels); printf(" eAMRBandMode = %s\n", amrBandModeString(amr.eAMRBandMode)); printf(" eAMRFrameFormat = %s\n", @@ -4654,6 +4740,8 @@ status_t QueryCodec( } // Color format query + // return colors in the order reported by the OMX component + // prefix "flexible" standard ones with the flexible equivalent OMX_VIDEO_PARAM_PORTFORMATTYPE portFormat; InitOMXParams(&portFormat); portFormat.nPortIndex = !isEncoder ? 1 : 0; @@ -4664,6 +4752,21 @@ status_t QueryCodec( if (err != OK) { break; } + + OMX_U32 flexibleEquivalent; + if (ACodec::isFlexibleColorFormat( + omx, node, portFormat.eColorFormat, &flexibleEquivalent)) { + bool marked = false; + for (size_t i = 0; i < caps->mColorFormats.size(); i++) { + if (caps->mColorFormats.itemAt(i) == flexibleEquivalent) { + marked = true; + break; + } + } + if (!marked) { + caps->mColorFormats.push(flexibleEquivalent); + } + } caps->mColorFormats.push(portFormat.eColorFormat); } |