diff --git a/include/media/stagefright/ExtendedCodec.h b/include/media/stagefright/ExtendedCodec.h index 5ec73a78ac2..5cedee27d74 100644 --- a/include/media/stagefright/ExtendedCodec.h +++ b/include/media/stagefright/ExtendedCodec.h @@ -56,6 +56,12 @@ struct ExtendedCodec { kPortIndexInput = 0, kPortIndexOutput = 1 }; + + enum kHEVCCodecType{ + kCodecType_None, + kCodecType_SWHEVC, + kCodecType_HWHEVC + }; static status_t convertMetaDataToMessage( const sp &meta, sp *format); @@ -145,6 +151,8 @@ struct ExtendedCodec { static bool useHWAACDecoder(const char *mime, int channelCount); + static kHEVCCodecType useHEVCDecoder(const char *mime); + static bool isSourcePauseRequired(const char *componentName); #if defined(ENABLE_AV_ENHANCEMENTS) || defined(ENABLE_OFFLOAD_ENHANCEMENTS) diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h index b3920424510..9b7a6568417 100644 --- a/include/media/stagefright/OMXCodec.h +++ b/include/media/stagefright/OMXCodec.h @@ -320,6 +320,8 @@ struct OMXCodec : public MediaSource, status_t setDTSFormat(const sp &inputFormat); status_t setFFmpegAudioFormat(const sp &inputFormat); + status_t getPCMOutputFormat(const sp &meta); + status_t allocateBuffers(); status_t allocateBuffersOnPort(OMX_U32 portIndex); #ifdef USE_SAMSUNG_COLORFORMAT diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index 4b74208e798..bdf707d770e 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -608,6 +608,11 @@ int addSubEffect(cnode *root) return -EINVAL; } d = malloc(sizeof(effect_descriptor_t)); + if (!d) { + ALOGE("failed to allocate effect descriptor"); + return -EINVAL; + } + if (l->desc->get_descriptor(&uuid, d) != 0) { char s[40]; uuidToString(&uuid, s, 40); @@ -692,8 +697,12 @@ int loadEffect(cnode *root) ALOGW("loadEffect() invalid uuid %s", node->value); return -EINVAL; } - d = malloc(sizeof(effect_descriptor_t)); + if (!d) { + ALOGE("failed to allocate effect descriptor"); + return -EINVAL; + } + if (l->desc->get_descriptor(&uuid, d) != 0) { char s[40]; uuidToString(&uuid, s, 40); diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk index c43ddb108c8..c3964e34cf2 100644 --- a/media/libmedia/Android.mk +++ b/media/libmedia/Android.mk @@ -86,10 +86,6 @@ ifeq ($(BOARD_USES_QCOM_HARDWARE),true) endif endif -ifneq ($(AUDIO_FEATURE_ENABLED_ULTRA_LOW_LATENCY),true) - LOCAL_CFLAGS += -DNATIVE_FAST_TRACKS_ONLY -endif - # for LOCAL_CFLAGS += -DANDROID_SMP=$(if $(findstring true,$(TARGET_CPU_SMP)),1,0) LOCAL_SRC_FILES += SingleStateQueue.cpp @@ -101,7 +97,7 @@ endif #TARGET_ENABLE_AV_ENHANCEMENTS #QTI Resampler ifeq ($(call is-vendor-board-platform,QCOM),true) -ifeq ($(strip $(BOARD_USES_QCOM_RESAMPLER)),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true) LOCAL_CFLAGS += -DQTI_RESAMPLER endif endif diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp index e2d6985b9b2..c1ec876412a 100644 --- a/media/libmedia/AudioRecord.cpp +++ b/media/libmedia/AudioRecord.cpp @@ -203,17 +203,21 @@ status_t AudioRecord::set( ALOGE("Invalid format %d", format); return BAD_VALUE; } -#ifdef QCOM_HARDWARE +#if defined(QCOM_HARDWARE) && !defined(QCOM_DIRECTTRACK) if (format != AUDIO_FORMAT_PCM_16_BIT && !audio_is_compress_voip_format(format) && !audio_is_compress_capture_format(format)) { #else +#ifndef QCOM_DIRECTTRACK // Temporary restriction: AudioFlinger currently supports 16-bit PCM only if (format != AUDIO_FORMAT_PCM_16_BIT) { #endif +#endif +#ifndef QCOM_DIRECTTRACK ALOGE("Format %d is not supported", format); return BAD_VALUE; } +#endif mFormat = format; @@ -222,12 +226,7 @@ status_t AudioRecord::set( return BAD_VALUE; } mChannelMask = channelMask; - uint32_t channelCount = popcount(channelMask -#ifdef QCOM_HARDWARE - &(AUDIO_CHANNEL_IN_STEREO|AUDIO_CHANNEL_IN_MONO|AUDIO_CHANNEL_IN_5POINT1)); -#else - ); -#endif + uint32_t channelCount = popcount(channelMask); mChannelCount = channelCount; #ifdef QCOM_DIRECTTRACK diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp index 387d8f0b670..8b97020eae0 100644 --- a/media/libmedia/AudioTrack.cpp +++ b/media/libmedia/AudioTrack.cpp @@ -196,16 +196,6 @@ AudioTrack::~AudioTrack() mAudioTrack.clear(); IPCThreadState::self()->flushCommands(); AudioSystem::releaseAudioSessionId(mSessionId); - if (isOffloaded()) { - char propValue[PROPERTY_VALUE_MAX]; - bool prop_enabled = false; - - if (property_get("audio.offload.multiple.enabled", propValue, NULL)) - prop_enabled = atoi(propValue) || !strncmp("true", propValue, 4); - - if (prop_enabled) - AudioSystem::releaseOutput(mOutput); - } #endif } } @@ -420,6 +410,7 @@ status_t AudioTrack::set( } #endif +#ifndef QCOM_DIRECTTRACK if (audio_is_linear_pcm(format)) { mFrameSize = channelCount * audio_bytes_per_sample(format); mFrameSizeAF = channelCount * sizeof(int16_t); @@ -427,6 +418,7 @@ status_t AudioTrack::set( mFrameSize = sizeof(uint8_t); mFrameSizeAF = sizeof(uint8_t); } +#endif audio_io_handle_t output = AudioSystem::getOutput( streamType, @@ -1145,13 +1137,11 @@ status_t AudioTrack::createTrack_l( } ALOGV("createTrack_l() output %d afLatency %d", output, afLatency); -#ifdef NATIVE_FAST_TRACKS_ONLY if ((flags & AUDIO_OUTPUT_FLAG_FAST) && sampleRate != afSampleRate) { ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (%d vs %d)", sampleRate, afSampleRate); flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST); } -#endif // The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where // n = 1 fast track with single buffering; nBuffering is ignored @@ -1892,16 +1882,6 @@ nsecs_t AudioTrack::processAudioBuffer(const sp& thread) return NS_NEVER; } - if (mRetryOnPartialBuffer && !isOffloaded()) { - mRetryOnPartialBuffer = false; - if (avail < mRemainingFrames) { - int64_t myns = ((mRemainingFrames - avail) * 1100000000LL) / sampleRate; - if (ns < 0 || myns < ns) { - ns = myns; - } - return ns; - } - } // Divide buffer size by 2 to take into account the expansion // due to 8 to 16 bit conversion: the callback must fill only half diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index 8d46b1919bc..fce58e7bc79 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -1214,6 +1214,7 @@ status_t MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* ALOGV("decode(%s)", url); sp player; status_t status = BAD_VALUE; + status_t err = OK; // Protect our precious, precious DRMd ringtones by only allowing // decoding of http, but not filesystem paths or content Uris. @@ -1246,7 +1247,11 @@ status_t MediaPlayerService::decode(const char* url, uint32_t *pSampleRate, int* if (cache->wait() != NO_ERROR) goto Exit; ALOGV("start"); - player->start(); + err = player->start(); + if (err != NO_ERROR) { + ALOGE("Error: %d Starting player in decode", err); + goto Exit; + } ALOGV("wait for playback complete"); cache->wait(); @@ -1276,6 +1281,7 @@ status_t MediaPlayerService::decode(int fd, int64_t offset, int64_t length, ALOGV("decode(%d, %lld, %lld)", fd, offset, length); sp player; status_t status = BAD_VALUE; + status_t err = OK; player_type playerType = MediaPlayerFactory::getPlayerType(NULL /* client */, fd, @@ -1301,7 +1307,11 @@ status_t MediaPlayerService::decode(int fd, int64_t offset, int64_t length, if (cache->wait() != NO_ERROR) goto Exit; ALOGV("start"); - player->start(); + err = player->start(); + if (err != NO_ERROR) { + ALOGE("Error: %d Starting player in decode", err); + goto Exit; + } ALOGV("wait for playback complete"); cache->wait(); @@ -1852,102 +1862,6 @@ status_t MediaPlayerService::AudioOutput::attachAuxEffect(int effectId) } // static -#ifdef QCOM_DIRECTTRACK -void MediaPlayerService::AudioOutput::CallbackWrapper( - int event, void *cookie, void *info) { - //ALOGV("callbackwrapper"); - if (event == AudioTrack::EVENT_UNDERRUN) { - ALOGW("Event underrun"); - CallbackData *data = (CallbackData*)cookie; - data->lock(); - AudioOutput *me = data->getOutput(); - if (me == NULL) { - // no output set, likely because the track was scheduled to be reused - // by another player, but the format turned out to be incompatible. - data->unlock(); - return; - } - ALOGD("Callback!!!"); - (*me->mCallback)( - me, NULL, (size_t)AudioTrack::EVENT_UNDERRUN, me->mCallbackCookie, CB_EVENT_UNDERRUN); - data->unlock(); - return; - } - if (event == AudioTrack::EVENT_HW_FAIL) { - ALOGW("Event hardware failure"); - CallbackData *data = (CallbackData*)cookie; - if (data != NULL) { - data->lock(); - AudioOutput *me = data->getOutput(); - if (me == NULL) { - // no output set, likely because the track was - // scheduled to be reused - // by another player, but the format turned out - // to be incompatible. - data->unlock(); - return; - } - ALOGV("Callback!!!"); - (*me->mCallback)(me, NULL, (size_t)AudioTrack::EVENT_HW_FAIL, - me->mCallbackCookie, CB_EVENT_HW_FAIL); - data->unlock(); - } - return; - } - if (event == AudioTrack::EVENT_MORE_DATA) { - CallbackData *data = (CallbackData*)cookie; - data->lock(); - AudioOutput *me = data->getOutput(); - AudioTrack::Buffer *buffer = (AudioTrack::Buffer *)info; - if (me == NULL) { - // no output set, likely because the track was scheduled to be reused - // by another player, but the format turned out to be incompatible. - data->unlock(); - if (buffer != NULL) { - buffer->size = 0; - } - return; - } - - switch(event) { - case AudioTrack::EVENT_MORE_DATA: { - size_t actualSize = (*me->mCallback)( - me, buffer->raw, buffer->size, me->mCallbackCookie, - CB_EVENT_FILL_BUFFER); - - if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL) { - // We've reached EOS but the audio track is not stopped yet, - // keep playing silence. - - memset(buffer->raw, 0, buffer->size); - actualSize = buffer->size; - } - - buffer->size = actualSize; - } break; - - - case AudioTrack::EVENT_STREAM_END: - ALOGV("callbackwrapper: deliver EVENT_STREAM_END"); - (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, - me->mCallbackCookie, CB_EVENT_STREAM_END); - break; - - case AudioTrack::EVENT_NEW_IAUDIOTRACK : - ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN"); - (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, - me->mCallbackCookie, CB_EVENT_TEAR_DOWN); - break; - - default: - ALOGE("received unknown event type: %d inside CallbackWrapper !", event); - } - - data->unlock(); - } - return; -} -#else void MediaPlayerService::AudioOutput::CallbackWrapper( int event, void *cookie, void *info) { //ALOGV("callbackwrapper"); @@ -1966,13 +1880,31 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( } switch(event) { +#ifdef QCOM_DIRECTTRACK + case AudioTrack::EVENT_UNDERRUN: + ALOGW("Event underrun"); + (*me->mCallback)( + me, NULL, (size_t)AudioTrack::EVENT_UNDERRUN, me->mCallbackCookie, CB_EVENT_UNDERRUN); + break; + + case AudioTrack::EVENT_HW_FAIL: + ALOGW("Event hardware failure"); + (*me->mCallback)(me, NULL, (size_t)AudioTrack::EVENT_HW_FAIL, + me->mCallbackCookie, CB_EVENT_HW_FAIL); + break; +#endif + case AudioTrack::EVENT_MORE_DATA: { size_t actualSize = (*me->mCallback)( me, buffer->raw, buffer->size, me->mCallbackCookie, CB_EVENT_FILL_BUFFER); - if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL && - (me->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) { + if (actualSize == 0 && buffer->size > 0 && me->mNextOutput == NULL +#ifndef QCOM_DIRECTTRACK + && (me->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) { +#else + ) { +#endif // We've reached EOS but the audio track is not stopped yet, // keep playing silence. @@ -1989,7 +1921,7 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( me->mCallbackCookie, CB_EVENT_STREAM_END); break; - case AudioTrack::EVENT_NEW_IAUDIOTRACK : + case AudioTrack::EVENT_NEW_IAUDIOTRACK: ALOGV("callbackwrapper: deliver EVENT_TEAR_DOWN"); (*me->mCallback)(me, NULL /* buffer */, 0 /* size */, me->mCallbackCookie, CB_EVENT_TEAR_DOWN); @@ -2001,7 +1933,6 @@ void MediaPlayerService::AudioOutput::CallbackWrapper( data->unlock(); } -#endif int MediaPlayerService::AudioOutput::getSessionId() const { diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 7df93033622..51a2d9ff4eb 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -161,7 +161,8 @@ NuPlayer::NuPlayer() mNumFramesDropped(0ll), mVideoScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW), mStarted(false), - mSeeking(false) { + mSeeking(false), + isCodecSpecific(false) { } NuPlayer::~NuPlayer() { @@ -216,6 +217,13 @@ void NuPlayer::setDataSourceAsync( sp notify = new AMessage(kWhatSourceNotify, id()); + if (headers) { + ssize_t index = headers->indexOfKey(String8("codecspecific")); + if (index >= 0) { + isCodecSpecific = true; + } + } + sp source; if (IsHTTPLiveURL(url)) { source = new HTTPLiveSource(notify, url, headers, mUIDValid, mUID); @@ -922,6 +930,8 @@ status_t NuPlayer::instantiateDecoder(bool audio, sp *decoder) { AString mime; CHECK(format->findString("mime", &mime)); mVideoIsAVC = !strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime.c_str()); + if(isCodecSpecific) + format->setInt32("hardwarecodecOnly", 1); } sp notify = diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h index c7d83629801..9c6fdfe195f 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.h +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h @@ -160,6 +160,8 @@ struct NuPlayer : public AHandler { bool mStarted; bool mSeeking; + bool isCodecSpecific; + status_t instantiateDecoder(bool audio, sp *decoder); status_t feedDecoderInputData(bool audio, const sp &msg); diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp index aa0a53698ec..726f2ff6dc9 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp @@ -66,6 +66,13 @@ NuPlayer::RTSPSource::RTSPSource( mExtraHeaders.removeItemsAt(index); } + + index = mExtraHeaders.indexOfKey(String8("rtp.transport.TCP")); + + if (index >= 0) { + mFlags |= kFlagUseTCP; + mExtraHeaders.removeItemsAt(index); + } } } @@ -101,7 +108,7 @@ void NuPlayer::RTSPSource::prepareAsync() { mSDPLoader->load( mURL.c_str(), mExtraHeaders.isEmpty() ? NULL : &mExtraHeaders); } else { - mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID); + mHandler = new MyHandler(mURL.c_str(), notify, mUIDValid, mUID, (mFlags & kFlagUseTCP) ? true : false); mLooper->registerHandler(mHandler); mHandler->connect(); @@ -652,7 +659,7 @@ void NuPlayer::RTSPSource::onSDPLoaded(const sp &msg) { } else { sp notify = new AMessage(kWhatNotify, mReflector->id()); - mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID); + mHandler = new MyHandler(rtspUri.c_str(), notify, mUIDValid, mUID, (mFlags & kFlagUseTCP) ? true : false); mLooper->registerHandler(mHandler); mHandler->loadSDP(desc); diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.h b/media/libmediaplayerservice/nuplayer/RTSPSource.h index 849355ede06..1950d098f86 100644 --- a/media/libmediaplayerservice/nuplayer/RTSPSource.h +++ b/media/libmediaplayerservice/nuplayer/RTSPSource.h @@ -81,6 +81,7 @@ struct NuPlayer::RTSPSource : public NuPlayer::Source { enum Flags { // Don't log any URLs. kFlagIncognito = 1, + kFlagUseTCP = 2, }; struct TrackInfo { diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index a3d54a47c36..3ff1a63a792 100755 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -663,6 +663,14 @@ status_t ACodec::configureOutputBuffersFromNativeWindow( return err; } +#ifdef QCOM_HARDWARE + //add an extra buffer to display queue to get around dequeue+wait + //blocking too long (more than 1 Vsync) in case BufferQeuue is in + //sync-mode and advertizes only 1 buffer + (*minUndequeuedBuffers)++; + ALOGI("NOTE: Overriding minUndequeuedBuffers to %lu",*minUndequeuedBuffers); +#endif + // 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? @@ -1023,8 +1031,13 @@ status_t ACodec::setComponentRole( "video_decoder.vp9", "video_encoder.vp9" }, { MEDIA_MIMETYPE_AUDIO_RAW, "audio_decoder.raw", "audio_encoder.raw" }, +#ifdef QTI_FLAC_DECODER + { MEDIA_MIMETYPE_AUDIO_FLAC, + "audio_decoder.raw", NULL }, +#else { MEDIA_MIMETYPE_AUDIO_FLAC, "audio_decoder.flac", "audio_encoder.flac" }, +#endif { MEDIA_MIMETYPE_AUDIO_MSGSM, "audio_decoder.gsm", "audio_encoder.gsm" }, }; @@ -3729,7 +3742,11 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp &msg) { // about any notifications in the afterlife. mDeathNotifier.clear(); } - + int32_t hardwarecodecOnly = 0; + if (msg->findInt32("hardwarecodecOnly", &hardwarecodecOnly) + && hardwarecodecOnly == 1) { + ALOGV("use hardware codec only"); + } Vector matchingCodecs; AString mime; @@ -3764,7 +3781,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp &msg) { mime.c_str(), encoder, // createEncoder NULL, // matchComponentName - 0, // flags + hardwarecodecOnly ? OMXCodec::kHardwareCodecsOnly : 0, // flags &matchingCodecs); } diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk index 7ee91ec3221..b1f1246016e 100644 --- a/media/libstagefright/Android.mk +++ b/media/libstagefright/Android.mk @@ -154,6 +154,15 @@ LOCAL_SHARED_LIBRARIES := \ libz \ libpowermanager +#QTI FLAC Decoder +ifeq ($(call is-vendor-board-platform,QCOM),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_FLAC_DECODER)),true) +LOCAL_SRC_FILES += FLACDecoder.cpp +LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-flac +LOCAL_CFLAGS := -DQTI_FLAC_DECODER +endif +endif + LOCAL_STATIC_LIBRARIES := \ libstagefright_color_conversion \ libstagefright_aacenc \ diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp index 0a001619244..dc20fb12da1 100644 --- a/media/libstagefright/AudioPlayer.cpp +++ b/media/libstagefright/AudioPlayer.cpp @@ -44,6 +44,10 @@ #include "include/AwesomePlayer.h" +#ifdef ENABLE_AV_ENHANCEMENTS +#include "QCMetaData.h" +#endif + namespace android { AudioPlayer::AudioPlayer( @@ -647,7 +651,7 @@ size_t AudioPlayer::fillBuffer(void *data, size_t size) { Mutex::Autolock autoLock(mLock); - if (err != OK) { + if (err != OK && err != INFO_FORMAT_CHANGED) { if (!mReachedEOS) { if (useOffload()) { // After seek there is a possible race condition if diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index cc152d83856..4b494bdeb68 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -805,16 +805,18 @@ void AwesomePlayer::onVideoLagUpdate() { } mVideoLagEventPending = false; - int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs(); - int64_t videoLateByUs = audioTimeUs - mVideoTimeUs; + if (!(mFlags & AUDIO_AT_EOS)) { + int64_t audioTimeUs = mAudioPlayer->getMediaTimeUs(); + int64_t videoLateByUs = audioTimeUs - mVideoTimeUs; - if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) { - ALOGV("video late by %lld ms.", videoLateByUs / 1000ll); + if (!(mFlags & VIDEO_AT_EOS) && videoLateByUs > 300000ll) { + ALOGV("video late by %lld ms.", videoLateByUs / 1000ll); - notifyListener_l( - MEDIA_INFO, - MEDIA_INFO_VIDEO_TRACK_LAGGING, - videoLateByUs / 1000ll); + notifyListener_l( + MEDIA_INFO, + MEDIA_INFO_VIDEO_TRACK_LAGGING, + videoLateByUs / 1000ll); + } } postVideoLagEvent_l(); @@ -1931,7 +1933,9 @@ status_t AwesomePlayer::initAudioDecoder() { mAudioSource = mAudioTrack; #ifndef QCOM_DIRECTTRACK } else { - mOmxSource->getFormat()->setInt32(kKeySampleBits, 16); + if (mOmxSource != NULL) { + mOmxSource->getFormat()->setInt32(kKeySampleBits, 16); + } mAudioSource = mOmxSource; #endif } @@ -2429,6 +2433,7 @@ void AwesomePlayer::onVideoEvent() { } if (latenessUs > 500000ll + && !(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL && mAudioPlayer->getMediaTimeMapping( &realTimeUs, &mediaTimeUs)) { diff --git a/media/libstagefright/ExtendedCodec.cpp b/media/libstagefright/ExtendedCodec.cpp index 15cf12f59bf..b52da1bd1c4 100644 --- a/media/libstagefright/ExtendedCodec.cpp +++ b/media/libstagefright/ExtendedCodec.cpp @@ -1228,6 +1228,24 @@ bool ExtendedCodec::useHWAACDecoder(const char *mime, int channelCount) { return false; } +ExtendedCodec::kHEVCCodecType ExtendedCodec::useHEVCDecoder(const char *mime) { + char value[PROPERTY_VALUE_MAX] = {0}; + int sw_codectype = 0, hw_codectype = 0; + if (!strcmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) { + sw_codectype = property_get("media.swhevccodectype", value, NULL); + if (sw_codectype && !strncmp("1", value, 1)) { + ALOGI("Using SW HEVC Decoder"); + return ExtendedCodec::kCodecType_SWHEVC; + } + hw_codectype = property_get("media.hwhevccodectype", value, NULL); + if (hw_codectype && !strncmp("1", value, 1)) { + ALOGI("Using HW HEVC Decoder"); + return ExtendedCodec::kCodecType_HWHEVC; + } + } + return ExtendedCodec::kCodecType_None; +} + bool ExtendedCodec::isSourcePauseRequired(const char *componentName) { /* pause is required for hardware component to release adsp resources */ if (!strncmp(componentName, "OMX.qcom.", 9)) { @@ -1392,6 +1410,9 @@ bool ExtendedCodec::isSourcePauseRequired(const char *componentName) { return false; } + ExtendedCodec::kHEVCCodecType ExtendedCodec::useHEVCDecoder(const char *mime) { + return ExtendedCodec::kCodecType_None; + } void ExtendedCodec::enableSmoothStreaming( const sp &omx, IOMX::node_id nodeID, bool* isEnabled, const char* componentName) { diff --git a/media/libstagefright/ExtendedMediaDefs.cpp b/media/libstagefright/ExtendedMediaDefs.cpp index 92b8e581f53..4ddb8d387d1 100644 --- a/media/libstagefright/ExtendedMediaDefs.cpp +++ b/media/libstagefright/ExtendedMediaDefs.cpp @@ -52,6 +52,10 @@ const char *MEDIA_MIMETYPE_CONTAINER_QCMATROSKA = "video/qc-matroska"; const char *MEDIA_MIMETYPE_CONTAINER_QCOGG = "video/qc-ogg"; const char *MEDIA_MIMETYPE_CONTAINER_QCFLV = "video/qc-flv"; const char *MEDIA_MIMETYPE_VIDEO_VPX = "video/x-vnd.on2.vp8"; //backward compatibility +#ifdef QTI_FLAC_DECODER const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC = "audio/qti-flac"; +#else +const char *MEDIA_MIMETYPE_CONTAINER_QTIFLAC = "audio/flac"; +#endif } // namespace android diff --git a/media/libstagefright/ExtendedUtils.cpp b/media/libstagefright/ExtendedUtils.cpp index 587f4cfd15b..17fbb22e083 100644 --- a/media/libstagefright/ExtendedUtils.cpp +++ b/media/libstagefright/ExtendedUtils.cpp @@ -74,21 +74,29 @@ void ExtendedUtils::HFR::setHFRIfEnabled( int32_t hfr = -1; if ( hfr_str != NULL ) { hfr = atoi(hfr_str); - } - if (hfr < 0) { - ALOGW("Invalid hfr value(%d) set from app. Disabling HFR.", hfr); - hfr = 0; + if(hfr > 0) { + ALOGI("HFR enabled, %d value provided", hfr); + meta->setInt32(kKeyHFR, hfr); + return; + } else { + ALOGI("Invalid hfr value(%d) set from app. Disabling HFR.", hfr); + } } -#if 0 +#ifndef LEGACY_MEDIA const char *hsr_str = params.get("video-hsr"); - - if(hsr_str && !strncmp(hsr_str,"on",2)) { - ALOGI("HSR [%d] ON",hfr); - meta->setInt32(kKeyHSR, hfr); - } else + int32_t hsr = -1; + if(hsr_str != NULL ) { + hsr = atoi(hsr_str); + if(hsr > 0) { + ALOGI("HSR enabled, %d value provided", hsr); + meta->setInt32(kKeyHSR, hsr); + return; + } else { + ALOGI("Invalid hsr value(%d) set from app. Disabling HSR.", hsr); + } + } #endif - meta->setInt32(kKeyHFR, hfr); } status_t ExtendedUtils::HFR::initializeHFR( @@ -96,7 +104,7 @@ status_t ExtendedUtils::HFR::initializeHFR( int64_t &maxFileDurationUs, video_encoder videoEncoder) { status_t retVal = OK; -#if 0 +#ifndef LEGACY_MEDIA //Check HSR first, if HSR is enable set HSR to kKeyFrameRate int32_t hsr =0; if (meta->findInt32(kKeyHSR, &hsr)) { diff --git a/media/libstagefright/FLACDecoder.cpp b/media/libstagefright/FLACDecoder.cpp new file mode 100644 index 00000000000..78faf0ae9ef --- /dev/null +++ b/media/libstagefright/FLACDecoder.cpp @@ -0,0 +1,311 @@ +/*Copyright (c) 2014, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LOG_TAG "FLACDecoder" +//#define LOG_NDEBUG 0 +//#define VERY_VERY_VERBOSE_LOGGING +#ifdef VERY_VERY_VERBOSE_LOGGING +#define ALOGVV ALOGV +#else +#define ALOGVV(a...) do { } while (0) +#endif + +#include +#include + +#include +#include +#include +#include "include/FLACDecoder.h" +#ifdef ENABLE_AV_ENHANCEMENTS +#include "QCMetaData.h" +#endif + +namespace android { + +static const char* FLAC_DECODER_LIB = "libFlacSwDec.so"; + +FLACDecoder::FLACDecoder(const sp &source) + : mSource(source), + mInputBuffer(NULL), + mStarted(false), + mInitStatus(false), + mBufferGroup(NULL), + mNumFramesOutput(0), + mAnchorTimeUs(0), + mLibHandle(dlopen(FLAC_DECODER_LIB, RTLD_LAZY)), + mOutBuffer(NULL), + mDecoderInit(NULL), + mProcessData(NULL) { + ALOGD("qti_flac: Instantiate FLACDecoder"); + if (mLibHandle != NULL) { + mDecoderInit = (DecoderInit) dlsym (mLibHandle, "CFlacDecoderLib_Meminit"); + mProcessData = (DecoderLib_Process) dlsym (mLibHandle, "CFlacDecoderLib_Process"); + init(); + } +} + +FLACDecoder::~FLACDecoder() { + ALOGD("qti_flac: Destroy FLACDecoder"); + if (mStarted) { + stop(); + } + if (mLibHandle != NULL) { + dlclose(mLibHandle); + } + mLibHandle = NULL; +} + +void FLACDecoder::init() { + ALOGV("qti_flac: FLACDecoder::init"); + int result, bitWidth = 16; //currently, only 16 bit is supported + memset(&pFlacDecState,0,sizeof(CFlacDecState)); + (*mDecoderInit)(&pFlacDecState, &result, bitWidth); + + if (result != DEC_SUCCESS) { + ALOGE("qti_flac: CSIM decoder init failed! Result %d", result); + return; + } + else { + mInitStatus = true; + } + + sp srcFormat = mSource->getFormat(); + + mMeta = new MetaData; + + int32_t sampleBits, minBlkSize, maxBlkSize, minFrmSize, maxFrmSize; + CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels)); + CHECK(srcFormat->findInt32(kKeySampleRate, &mSampleRate)); + CHECK(srcFormat->findInt32(kKeySampleBits, &sampleBits)); + CHECK(srcFormat->findInt32(kKeyMinBlkSize, &minBlkSize)); + CHECK(srcFormat->findInt32(kKeyMaxBlkSize, &maxBlkSize)); + CHECK(srcFormat->findInt32(kKeyMinFrmSize, &minFrmSize)); + CHECK(srcFormat->findInt32(kKeyMaxFrmSize, &maxFrmSize)); + + parserInfoToPass.i32NumChannels = mNumChannels; + parserInfoToPass.i32SampleRate = mSampleRate; + parserInfoToPass.i32BitsPerSample = sampleBits; + parserInfoToPass.i32MinBlkSize = minBlkSize; + parserInfoToPass.i32MaxBlkSize = maxBlkSize; + parserInfoToPass.i32MinFrmSize = minFrmSize; + parserInfoToPass.i32MaxFrmSize = maxFrmSize; + + ALOGV("qti_flac: i32NumChannels = %d", parserInfoToPass.i32NumChannels); + ALOGV("qti_flac: i32SampleRate = %d", parserInfoToPass.i32SampleRate); + ALOGV("qti_flac: i32BitsPerSample = %d", parserInfoToPass.i32BitsPerSample); + ALOGV("qti_flac: i32MinBlkSize = %d", parserInfoToPass.i32MinBlkSize); + ALOGV("qti_flac: i32MaxBlkSize = %d", parserInfoToPass.i32MaxBlkSize); + ALOGV("qti_flac: i32MinFrmSize = %d", parserInfoToPass.i32MinFrmSize); + ALOGV("qti_flac: i32MaxFrmSize = %d", parserInfoToPass.i32MaxFrmSize); + + setMetaData(&pFlacDecState, &parserInfoToPass); + + mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW); + + int64_t durationUs; + if (srcFormat->findInt64(kKeyDuration, &durationUs)) { + mMeta->setInt64(kKeyDuration, durationUs); + } + + ALOGV("qti_flac: durationUs = %lld", durationUs); + mMeta->setCString(kKeyDecoderComponent, "FLACDecoder"); + mMeta->setInt32(kKeySampleRate, mSampleRate); + mMeta->setInt32(kKeyChannelCount, mNumChannels); + + mOutBuffer = (uint16_t *) malloc (FLAC_INSTANCE_SIZE); + mTmpBuf = (uint16_t *) malloc (FLAC_INSTANCE_SIZE); + ALOGV("qti_flac: FLACDecoder::init done"); +} + +void FLACDecoder::setMetaData(CFlacDecState* pFlacDecState, + FLACDec_ParserInfo* parserInfoToPass) { + ALOGV("qti_flac: FLACDecoder::setMetadata"); + stFLACDec* pstFLACDec=(stFLACDec*)(pFlacDecState->m_pFlacDecoder); + memcpy(&pstFLACDec->MetaDataBlocks.MetaDataStrmInfo,parserInfoToPass,sizeof(FLACDec_ParserInfo)); + pFlacDecState->m_bIsStreamInfoPresent=1; + + pFlacDecState->ui32MaxBlockSize=pstFLACDec->MetaDataBlocks.MetaDataStrmInfo.i32MaxBlkSize; + + memcpy(pFlacDecState->pFlacDecMetaDataStrmInfo,parserInfoToPass,sizeof(FLACDec_ParserInfo)); + ALOGV("qti_flac: FLACDecoder::setMetadata done"); + +} + +status_t FLACDecoder::start(MetaData *params) { + ALOGV("qti_flac: FLACDecoder::start"); + + CHECK(!mStarted); + CHECK(mInitStatus); + + mBufferGroup = new MediaBufferGroup; + mBufferGroup->add_buffer(new MediaBuffer(FLAC_INSTANCE_SIZE)); + + mSource->start(); + mAnchorTimeUs = 0; + mNumFramesOutput = 0; + mStarted = true; + + ALOGV("qti_flac: FLACDecoder::start done"); + return OK; +} + +status_t FLACDecoder::stop() { + ALOGV("qti_flac: FLACDecoder::stop"); + + CHECK(mStarted); + CHECK(mInitStatus); + + if (mInputBuffer) { + mInputBuffer->release(); + mInputBuffer = NULL; + } + + delete mBufferGroup; + mBufferGroup = NULL; + + mSource->stop(); + mStarted = false; + + free(mOutBuffer); + free(mTmpBuf); + + ALOGV("qti_flac: FLACDecoder::stop done"); + return OK; +} + +sp FLACDecoder::getFormat() { + ALOGV("qti_flac: FLACDecoder::getFormat"); + CHECK(mInitStatus); + ALOGV("qti_flac: FLACDecoder::getFormat done"); + return mMeta; +} + +status_t FLACDecoder::read(MediaBuffer **out, const ReadOptions* options) { + int err = 0; + *out = NULL; + uint32 blockSize, usedBitstream, availLength = 0; + uint32 flacOutputBufSize = FLAC_OUTPUT_BUFFER_SIZE; + int *status = 0; + + bool seekSource = false, eos = false; + + if (!mInitStatus) { + return NO_INIT; + } + + int64_t seekTimeUs; + ReadOptions::SeekMode mode; + if (options && options->getSeekTo(&seekTimeUs, &mode)) { + ALOGD("qti_flac: Seek to %lld", seekTimeUs); + CHECK(seekTimeUs >= 0); + mNumFramesOutput = 0; + seekSource = true; + + if (mInputBuffer) { + mInputBuffer->release(); + mInputBuffer = NULL; + } + } + else { + seekTimeUs = -1; + } + + if (mInputBuffer) { + mInputBuffer->release(); + mInputBuffer = NULL; + } + + if (!eos) { + err = mSource->read(&mInputBuffer, options); + if (err != OK) { + ALOGE("qti_flac: Parser returned %d", err); + eos = true; + return err; + } + } + + int64_t timeUs; + if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) { + mAnchorTimeUs = timeUs; + mNumFramesOutput = 0; + ALOGVV("qti_flac: mAnchorTimeUs %lld", mAnchorTimeUs); + } + else { + CHECK(seekTimeUs < 0); + } + + if (!eos) { + if (mInputBuffer) { + ALOGVV("qti_flac: Parser filled %d bytes", mInputBuffer->range_length()); + availLength = mInputBuffer->range_length(); + status = (*mProcessData)(&pFlacDecState, + (uint8*)mInputBuffer->data(), + availLength, + mOutBuffer, + &flacOutputBufSize, + &usedBitstream, + &blockSize); + } + + ALOGVV("qti_flac: status %d, availLength %d, usedBitstream %d, blockSize %d", + (int)status, availLength, usedBitstream, blockSize); + + MediaBuffer *buffer; + CHECK_EQ(mBufferGroup->acquire_buffer(&buffer), (status_t)OK); + + buffer->set_range(0, blockSize*mNumChannels*2); + + uint16_t *ptr = (uint16_t *) mOutBuffer; + + //Interleave the output from decoder for multichannel clips. + if (mNumChannels > 1) { + for (uint32_t k = 0; k < blockSize; k++) { + for (uint32_t i = k, j = mNumChannels*k; i < blockSize*mNumChannels; i += blockSize, j++) { + mTmpBuf[j] = ptr[i]; + } + } + memcpy((uint16_t *)buffer->data(), mTmpBuf, blockSize*mNumChannels*2); + } + else { + memcpy((uint16_t *)buffer->data(), mOutBuffer, blockSize*mNumChannels*2); + } + + int64_t time = 0; + time = mAnchorTimeUs + (mNumFramesOutput*1000000)/mSampleRate; + buffer->meta_data()->setInt64(kKeyTime, time); + mNumFramesOutput += blockSize; + ALOGVV("qti_flac: time = %lld", time); + + *out = buffer; + } + + return OK; +} + +} diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp index 7bc7da24251..c263d244d07 100644 --- a/media/libstagefright/NuMediaExtractor.cpp +++ b/media/libstagefright/NuMediaExtractor.cpp @@ -23,6 +23,9 @@ #include "include/ESDS.h" #include "include/NuCachedSource2.h" #include "include/WVMExtractor.h" +#ifdef QTI_FLAC_DECODER +#include "include/FLACDecoder.h" +#endif #include #include @@ -275,24 +278,29 @@ status_t NuMediaExtractor::selectTrack(size_t index) { return OK; } } - sp source = mImpl->getTrack(index); - - CHECK_EQ((status_t)OK, source->start()); - mSelectedTracks.push(); TrackInfo *info = &mSelectedTracks.editItemAt(mSelectedTracks.size() - 1); - info->mSource = source; + const char *mime; + CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime)); + if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_FLAC)) { +#ifdef QTI_FLAC_DECODER + sp mFlacSource = new FLACDecoder(source); + info->mSource = mFlacSource; + mFlacSource->start(); +#endif + } else { + CHECK_EQ((status_t)OK, source->start()); + info->mSource = source; + } + info->mTrackIndex = index; info->mFinalResult = OK; info->mSample = NULL; info->mSampleTimeUs = -1ll; info->mTrackFlags = 0; - const char *mime; - CHECK(source->getFormat()->findCString(kKeyMIMEType, &mime)); - if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_VORBIS)) { info->mTrackFlags |= kIsVorbis; } diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 71f6f8d7b45..269028a88d9 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2009 The Android Open Source Project - * Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved. * * Not a Contribution * @@ -76,6 +76,10 @@ #include #endif +#ifdef QTI_FLAC_DECODER +#include "include/FLACDecoder.h" +#endif + namespace android { #ifdef USE_SAMSUNG_COLORFORMAT @@ -120,9 +124,14 @@ static sp Make##name(const sp &source, const sp InstantiateSoftwareEncoder( @@ -146,7 +155,7 @@ static sp InstantiateSoftwareEncoder( return NULL; } -#ifdef QCOM_DIRECTTRACK +#if defined(QCOM_DIRECTTRACK) || defined (QTI_FLAC_DECODER) static sp InstantiateSoftwareDecoder( const char *name, const sp &source) { struct FactoryInfo { @@ -154,7 +163,12 @@ static sp InstantiateSoftwareDecoder( sp (*CreateFunc)(const sp &); }; static const FactoryInfo kFactoryInfo[] = { +#ifdef QCOM_DIRECTTRACK FACTORY_REF(MP3Decoder) +#endif +#ifdef QTI_FLAC_DECODER + FACTORY_REF(FLACDecoder) +#endif }; for (size_t i = 0; i < sizeof(kFactoryInfo) / sizeof(kFactoryInfo[0]); ++i) { @@ -165,6 +179,7 @@ static sp InstantiateSoftwareDecoder( return NULL; } #endif + #undef FACTORY_CREATE_ENCODER #undef FACTORY_REF @@ -460,10 +475,10 @@ sp OMXCodec::Create( const char *mime; bool success = meta->findCString(kKeyMIMEType, &mime); CHECK(success); - Vector matchingCodecs; #ifdef QCOM_HARDWARE + ExtendedCodec::kHEVCCodecType hevc_codectype = ExtendedCodec::useHEVCDecoder(mime); int channelCount = 0; int trackId = 0; meta->findInt32(kKeyChannelCount, &channelCount); @@ -472,6 +487,12 @@ sp OMXCodec::Create( && trackId > 1) { findMatchingCodecs(mime, createEncoder, "OMX.qcom.audio.decoder.multiaac", flags, &matchingCodecs); + } else if (hevc_codectype == ExtendedCodec::kCodecType_SWHEVC) { + findMatchingCodecs(mime, createEncoder, + "OMX.qcom.video.decoder.hevcswvdec", flags, &matchingCodecs); + } else if (hevc_codectype == ExtendedCodec::kCodecType_HWHEVC) { + findMatchingCodecs(mime, createEncoder, + "OMX.qcom.video.decoder.hevc", flags, &matchingCodecs); } else { #endif findMatchingCodecs( @@ -503,14 +524,20 @@ sp OMXCodec::Create( componentName = tmp.c_str(); } + sp softwareCodec; if (createEncoder) { - sp softwareCodec = - InstantiateSoftwareEncoder(componentName, source, meta); - if (softwareCodec != NULL) { - ALOGV("Successfully allocated software codec '%s'", componentName); + softwareCodec = InstantiateSoftwareEncoder(componentName, source, meta); + } +#ifdef QTI_FLAC_DECODER + else { + softwareCodec = InstantiateSoftwareDecoder(componentName, source); + } +#endif - return softwareCodec; - } + if (softwareCodec != NULL) { + ALOGV("Successfully allocated software codec '%s'", componentName); + + return softwareCodec; } #ifdef QCOM_HARDWARE @@ -771,10 +798,16 @@ status_t OMXCodec::configureCodec(const sp &meta) { CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); - if (!meta->findInt32(kKeyAACProfile, &aacProfile)) { + if (!meta->findInt32(kKeyAACAOT, &aacProfile)) { aacProfile = OMX_AUDIO_AACObjectNull; } + // Google's AAC decoder can't handle MAIN profile + if (!strncmp(mComponentName, "OMX.google.", 11) && + aacProfile == OMX_AUDIO_AACObjectMain) { + return ERROR_UNSUPPORTED; + } + int32_t isADTS; if (!meta->findInt32(kKeyIsADTS, &isADTS)) { isADTS = false; @@ -860,12 +893,6 @@ status_t OMXCodec::configureCodec(const sp &meta) { CODEC_LOGE("setAC3Format() failed (err = %d)", err); return err; } -#ifdef ENABLE_AV_ENHANCEMENTS - // FFMPEG will convert floating point to 24-bit PCM - if (ExtendedUtils::isHiresAudioEnabled()) { - meta->setInt32(kKeySampleBits, 24); - } -#endif } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_APE, mMIME)) { status_t err = setAPEFormat(meta); if (err != OK) { @@ -878,12 +905,6 @@ status_t OMXCodec::configureCodec(const sp &meta) { CODEC_LOGE("setDTSFormat() failed (err = %d)", err); return err; } -#ifdef ENABLE_AV_ENHANCEMENTS - // FFMPEG will convert DTS floating point to 24-bit PCM - if (ExtendedUtils::isHiresAudioEnabled()) { - meta->setInt32(kKeySampleBits, 24); - } -#endif } else if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_FFMPEG, mMIME)) { status_t err = setFFmpegAudioFormat(meta); if (err != OK) { @@ -891,6 +912,8 @@ status_t OMXCodec::configureCodec(const sp &meta) { return err; } } + getPCMOutputFormat(meta); + meta->dumpToLog(); #ifdef QCOM_HARDWARE } else { if (!mIsVideo && mIsEncoder) { @@ -2399,12 +2422,23 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { return err; } +#ifdef QCOM_HARDWARE + // Add extra buffer to display queue to get around dequeue+wait + // blocking too long in case BufferQueue is in sync-mode and advertises + // only 1 buffer. Also, restrict to 2 extra buffers for > 1080p + minUndequeuedBufs += + (def.format.video.nFrameWidth * def.format.video.nFrameHeight > 1088 * 1920) + ? 2 : 3; + ALOGI("NOTE: Overriding minUndequeuedBufs to %d",minUndequeuedBufs); +#endif + // 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; def.nBufferCountActual = newBufferCount; + ALOGI("NOTE: Allocating %lu buffers on output port",def.nBufferCountActual); err = mOMX->setParameter( mNode, OMX_IndexParamPortDefinition, &def, sizeof(def)); if (err != OK) { @@ -4360,6 +4394,28 @@ status_t OMXCodec::setFFmpegVideoFormat(const sp &meta) return err; } +status_t OMXCodec::getPCMOutputFormat(const sp &meta) +{ + int32_t bitsPerSample = 16; + status_t err = OK; + + OMX_AUDIO_PARAM_PCMMODETYPE params; + InitOMXParams(¶ms); + params.nPortIndex = kPortIndexOutput; + + err = mOMX->getParameter( + mNode, OMX_IndexParamAudioPcm, ¶ms, sizeof(params)); + + if (err == OK) { + ALOGI(" nSamplingRate = %ld\n", params.nSamplingRate); + ALOGI(" nChannels = %ld\n", params.nChannels); + ALOGI(" nBitPerSample = %ld\n", params.nBitPerSample); + + meta->setInt32(kKeySampleBits, params.nBitPerSample); + } + return err; +} + //audio status_t OMXCodec::setMP3Format(const sp &meta) { @@ -4427,7 +4483,13 @@ status_t OMXCodec::setWMAFormat(const sp &meta) CHECK(meta->findInt32(kKeyChannelCount, &numChannels)); CHECK(meta->findInt32(kKeySampleRate, &sampleRate)); CHECK(meta->findInt32(kKeyBitRate, &bitRate)); - CHECK(meta->findInt32(kKeyBlockAlign, &blockAlign)); + if (!meta->findInt32(kKeyBlockAlign, &blockAlign)) { + // we should be last on the codec list, but another sniffer may + // have handled it and there is no hardware codec. + if (!meta->findInt32(kKeyWMABlockAlign, &blockAlign)) { + return ERROR_UNSUPPORTED; + } + } CODEC_LOGV("Channels: %d, SampleRate: %d, BitRate: %d, blockAlign: %d", numChannels, sampleRate, bitRate, blockAlign); @@ -5816,7 +5878,7 @@ void OMXCodec::initOutputFormat(const sp &inputFormat) { CHECK_EQ(err, (status_t)OK); CHECK_EQ((int)params.eNumData, (int)OMX_NumericalDataSigned); - CHECK_EQ(params.nBitPerSample, 16u); + //CHECK_EQ(params.nBitPerSample, 16u); CHECK_EQ((int)params.ePCMMode, (int)OMX_AUDIO_PCMModeLinear); int32_t numChannels, sampleRate; diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp index e8402ad342e..3a8d7557ff7 100644 --- a/media/libstagefright/SurfaceMediaSource.cpp +++ b/media/libstagefright/SurfaceMediaSource.cpp @@ -469,7 +469,9 @@ void SurfaceMediaSource::onBuffersReleased() { Mutex::Autolock lock(mMutex); +#ifdef QCOM_HARDWARE mBuffersReleased = true; +#endif mFrameAvailableCondition.signal(); for (int i = 0; i < BufferQueue::NUM_BUFFER_SLOTS; i++) { diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp index 2313a161611..d43f5af9b18 100644 --- a/media/libstagefright/Utils.cpp +++ b/media/libstagefright/Utils.cpp @@ -509,6 +509,7 @@ status_t sendMetaDataToHal(sp& sink, int32_t delaySamples = 0; int32_t paddingSamples = 0; int32_t isADTS = 0; + int32_t minBlkSize, maxBlkSize, minFrmSize, maxFrmSize; //FLAC params AudioParameter param = AudioParameter(); @@ -530,6 +531,20 @@ status_t sendMetaDataToHal(sp& sink, if (meta->findInt32(kKeyIsADTS, &isADTS)) { param.addInt(String8(AUDIO_OFFLOAD_CODEC_FORMAT), 0x02 /*SND_AUDIOSTREAMFORMAT_MP4ADTS*/); } +#ifdef ENABLE_AV_ENHANCEMENTS + if (meta->findInt32(kKeyMinBlkSize, &minBlkSize)) { + param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MIN_BLK_SIZE), minBlkSize); + } + if (meta->findInt32(kKeyMaxBlkSize, &maxBlkSize)) { + param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MAX_BLK_SIZE), maxBlkSize); + } + if (meta->findInt32(kKeyMinFrmSize, &minFrmSize)) { + param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MIN_FRAME_SIZE), minFrmSize); + } + if (meta->findInt32(kKeyMaxFrmSize, &maxFrmSize)) { + param.addInt(String8(AUDIO_OFFLOAD_CODEC_FLAC_MAX_FRAME_SIZE), maxFrmSize); + } +#endif ALOGV("sendMetaDataToHal: bitRate %d, sampleRate %d, chanMask %d," "delaySample %d, paddingSample %d", bitRate, sampleRate, @@ -561,6 +576,9 @@ static const struct mime_conv_t mimeLookup[] = { { MEDIA_MIMETYPE_AUDIO_QCELP, AUDIO_FORMAT_QCELP }, { MEDIA_MIMETYPE_AUDIO_WMA, AUDIO_FORMAT_WMA }, { MEDIA_MIMETYPE_AUDIO_MPEG_LAYER_II, AUDIO_FORMAT_MP2 }, +#ifdef QTI_FLAC_DECODER + { MEDIA_MIMETYPE_CONTAINER_QTIFLAC, AUDIO_FORMAT_FLAC }, +#endif #endif { 0, AUDIO_FORMAT_INVALID } }; diff --git a/media/libstagefright/include/FLACDecoder.h b/media/libstagefright/include/FLACDecoder.h new file mode 100644 index 00000000000..2d14347b612 --- /dev/null +++ b/media/libstagefright/include/FLACDecoder.h @@ -0,0 +1,90 @@ +/*Copyright (c) 2014 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FLAC_DECODER +#define FLAC_DECODER +#include "FLACDec_Wrapper.h" +#include "FLACDec_BitStream.h" +#include "FLACDec_MetaData.h" +#include "FLACDec_Struct.h" +#include +#include + +#define FLAC_OUTPUT_BUFFER_SIZE (8192*8)*4*8 +#define FLAC_INSTANCE_SIZE 2048 + MAXINPBUFFER + 65536*8*4 + +namespace android { + +struct MediaBufferGroup; + +class FLACDecoder : public MediaSource { +public: + FLACDecoder(const sp &source); + ~FLACDecoder(); + void init(); + virtual status_t start(MetaData *params); + virtual status_t stop(); + virtual sp getFormat(); + virtual status_t read(MediaBuffer **buffer, const ReadOptions *options); + +private: + sp mSource; + sp mMeta; + MediaBuffer *mInputBuffer; + int32_t mNumChannels; + int32_t mSampleRate; + bool mStarted; + bool mInitStatus; + MediaBufferGroup *mBufferGroup; + int64_t mNumFramesOutput; + int64_t mAnchorTimeUs; + + CFlacDecState pFlacDecState; + FLACDec_ParserInfo parserInfoToPass; + + void *mLibHandle; + void *mOutBuffer; + uint16_t *mTmpBuf; + + void setMetaData(CFlacDecState* pFlacDecState, + FLACDec_ParserInfo* parserInfoToPass); + + typedef void* (*DecoderInit) (CFlacDecState* pFlacDecState, int* nRes, int bitWidth); + + typedef int* (*DecoderLib_Process) (CFlacDecState* pFlacDecState, uint8* pInBitStream, + uint32 nActualDataLen, void *pOutSamples, + uint32* uFlacOutputBufSize, uint32* usedBitstream, + uint32* blockSize); + + DecoderInit mDecoderInit; + DecoderLib_Process mProcessData; +}; + +} // namespace android + +#endif //FLAC_DECODER diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp index 022205dc2a8..fec682cce4b 100644 --- a/media/libstagefright/matroska/MatroskaExtractor.cpp +++ b/media/libstagefright/matroska/MatroskaExtractor.cpp @@ -41,6 +41,20 @@ namespace android { +typedef struct { + uint32_t biSize; + uint32_t biWidth; + uint32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + uint32_t biXPelsPerMeter; + uint32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +} BITMAPINFOHEADER; + struct DataSourceReader : public mkvparser::IMkvReader { DataSourceReader(const sp &source) : mSource(source) { @@ -974,6 +988,49 @@ void MatroskaExtractor::addTracks() { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8); } else if (!strcmp("V_VP9", codecID)) { meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9); + } else if (!strcmp("V_MS/VFW/FOURCC", codecID)) { + if (codecPrivateSize >= sizeof(BITMAPINFOHEADER)) { + char *fourcc = (char *) &((BITMAPINFOHEADER *) codecPrivate)->biCompression; + + switch (FOURCC(fourcc[0], fourcc[1], fourcc[2], fourcc[3])) { + case 'XVID': + case 'xvid': + case 'FMP4': + case 'fmp4': + case 'MP4V': + case 'mp4v': + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4); + break; + case 'H263': + case 'h263': + meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263); + break; + case 'DIV3': + case 'div3': + case 'DIV4': + case 'div4': + ALOGW("DivX 3.11 codec not supported"); + continue; + case 'DIVX': + case 'divx': + ALOGW("DivX 4 codec not supported"); + continue; + case 'DX50': + case 'dx50': + ALOGW("DivX 5 codec not supported"); + continue; + case 'MP42': + default: + ALOGW("fourcc id: %hhX%hhX%hhX%hhX is not supported\n", + fourcc[0], fourcc[1], fourcc[2], fourcc[3]); + continue; + } + + ALOGV("fourcc id: %.4s", fourcc); + } else { + ALOGW("fourcc size: %d is not supported\n", codecPrivateSize); + continue; + } } else { ALOGW("%s is not supported.", codecID); continue; diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h index f9c7fd53bfa..b1e57e181ce 100644 --- a/media/libstagefright/rtsp/MyHandler.h +++ b/media/libstagefright/rtsp/MyHandler.h @@ -102,7 +102,7 @@ struct MyHandler : public AHandler { MyHandler( const char *url, const sp ¬ify, - bool uidValid = false, uid_t uid = 0) + bool uidValid = false, uid_t uid = 0, bool tcptransport = false) : mNotify(notify), mUIDValid(uidValid), mUID(uid), @@ -122,7 +122,7 @@ struct MyHandler : public AHandler { mCheckPending(false), mCheckGeneration(0), mCheckTimeoutGeneration(0), - mTryTCPInterleaving(false), + mTryTCPInterleaving(tcptransport), mTryFakeRTCP(false), mReceivedFirstRTCPPacket(false), mReceivedFirstRTPPacket(false), @@ -138,10 +138,10 @@ struct MyHandler : public AHandler { PRIORITY_HIGHEST); char value[PROPERTY_VALUE_MAX] = {0}; - property_get("rtsp.transport.TCP", value, "false"); + property_get("rtsp.transport.TCP", value, "0"); if (!strcmp(value, "true")) { mTryTCPInterleaving = true; - } else { + } else if (!strcmp(value, "false")) { mTryTCPInterleaving = false; } diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk index 86940253365..d0b712d9f74 100644 --- a/services/audioflinger/Android.mk +++ b/services/audioflinger/Android.mk @@ -68,7 +68,7 @@ LOCAL_SHARED_LIBRARIES := \ #QTI Resampler ifeq ($(call is-vendor-board-platform,QCOM),true) -ifeq ($(strip $(BOARD_USES_QCOM_RESAMPLER)),true) +ifeq ($(strip $(AUDIO_FEATURE_ENABLED_EXTN_RESAMPLER)),true) LOCAL_SRC_FILES += AudioResamplerQTI.cpp.arm LOCAL_C_INCLUDES += $(TARGET_OUT_HEADERS)/mm-audio/audio-src LOCAL_SHARED_LIBRARIES += libqct_resampler @@ -93,10 +93,6 @@ ifeq ($(strip $(BOARD_USE_RESAMPLER_IN_PCM_OFFLOAD_PATH)),true) LOCAL_CFLAGS += -DENABLE_RESAMPLER_IN_PCM_OFFLOAD_PATH endif -ifneq ($(AUDIO_FEATURE_ENABLED_ULTRA_LOW_LATENCY),true) -LOCAL_CFLAGS += -DNATIVE_FAST_TRACKS_ONLY -endif - # Define ANDROID_SMP appropriately. Used to get inline tracing fast-path. ifeq ($(TARGET_CPU_SMP),true) LOCAL_CFLAGS += -DANDROID_SMP=1 diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp index 1e7a8818b70..b8d8aab33f4 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -1590,11 +1590,11 @@ sp AudioFlinger::openRecord( goto Exit; } #else -#if defined(QCOM_HARDWARE) +#ifdef QCOM_HARDWARE if (format != AUDIO_FORMAT_PCM_16_BIT && !audio_is_compress_voip_format(format) && !audio_is_compress_capture_format(format)) { -#else +#else if (format != AUDIO_FORMAT_PCM_16_BIT) { #endif ALOGE("openRecord() invalid format %d", format); diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 64103e0b957..bfeb5133aac 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -564,11 +564,7 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) (value == 48000 && devSampleRate == 44100))) { quality = AudioResampler::LOW_QUALITY; } else { -#ifdef QCOM_HARDWARE - quality = AudioResampler::VERY_HIGH_QUALITY; -#else quality = AudioResampler::DEFAULT_QUALITY; -#endif } resampler = AudioResampler::create( format, diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp index 32efa0affcc..a23d031284d 100644 --- a/services/audioflinger/AudioPolicyService.cpp +++ b/services/audioflinger/AudioPolicyService.cpp @@ -540,8 +540,9 @@ bool AudioPolicyService::isStreamActiveRemotely(audio_stream_type_t stream, uint } Mutex::Autolock _l(mLock); return mpAudioPolicy->is_stream_active_remotely(mpAudioPolicy, stream, inPastMs); -#endif +#else return 0; +#endif } bool AudioPolicyService::isSourceActive(audio_source_t source) const diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index f5aa5713562..f93bd1dada1 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1289,10 +1289,8 @@ sp AudioFlinger::PlaybackThread::createTrac // mono or stereo ( (channelMask == AUDIO_CHANNEL_OUT_MONO) || (channelMask == AUDIO_CHANNEL_OUT_STEREO) ) && -#ifdef NATIVE_FAST_TRACKS_ONLY // hardware sample rate (sampleRate == mSampleRate) && -#endif // normal mixer has an associated fast mixer hasFastMixer() && // there are sufficient fast track slots available @@ -3855,7 +3853,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::DirectOutputThread::prep tracksToRemove->add(track); // indicate to client process that the track was disabled because of underrun; // it will then automatically call start() when data is available -#if defined(QCOM_HARDWARE) && !defined(QCOM_DIRECTTRACK) +#ifdef QCOM_HARDWARE android_atomic_or(CBLK_DISABLED, &cblk->mFlags); #endif } else if (last) { @@ -5682,16 +5680,18 @@ void AudioFlinger::RecordThread::readInputParameters() mChannelMask = mInput->stream->common.get_channels(&mInput->stream->common); mChannelCount = (uint16_t)getInputChannelCount(mChannelMask); mFormat = mInput->stream->common.get_format(&mInput->stream->common); -#ifdef QCOM_HARDWARE +#if defined(QCOM_HARDWARE) && !defined(QCOM_DIRECTTRACK) if (mFormat != AUDIO_FORMAT_PCM_16_BIT && !audio_is_compress_voip_format(mFormat) && !audio_is_compress_capture_format(mFormat)) { ALOGE("HAL format %d not supported", mFormat); } #else +#ifndef QCOM_DIRECTTRACK if (mFormat != AUDIO_FORMAT_PCM_16_BIT) { ALOGE("HAL format %d not supported; must be AUDIO_FORMAT_PCM_16_BIT", mFormat); } +#endif #endif mFrameSize = audio_stream_frame_size(&mInput->stream->common); mBufferSize = mInput->stream->common.get_buffer_size(&mInput->stream->common); diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h index 1864fbb2ec1..67f27ee8179 100644 --- a/services/camera/libcameraservice/CameraService.h +++ b/services/camera/libcameraservice/CameraService.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include "hardware/camera.h" #include #include diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp index 67d40597447..1629e05af28 100644 --- a/services/camera/libcameraservice/api1/CameraClient.cpp +++ b/services/camera/libcameraservice/api1/CameraClient.cpp @@ -89,9 +89,7 @@ status_t CameraClient::initialize(camera_module_t *module) { // Enable zoom, error, focus, and metadata messages by default enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS -#ifndef CAMERA_MSG_MGMT | CAMERA_MSG_PREVIEW_METADATA -#endif #ifndef OMAP_ICS_CAMERA | CAMERA_MSG_FOCUS_MOVE #endif @@ -362,9 +360,6 @@ status_t CameraClient::setPreviewCallbackTarget( // start preview mode status_t CameraClient::startPreview() { Mutex::Autolock lock(mLock); -#ifdef CAMERA_MSG_MGMT - enableMsgType(CAMERA_MSG_PREVIEW_METADATA); -#endif LOG1("startPreview (pid %d)", getCallingPid()); return startCameraMode(CAMERA_PREVIEW_MODE); } @@ -457,9 +452,6 @@ status_t CameraClient::startRecordingMode() { void CameraClient::stopPreview() { LOG1("stopPreview (pid %d)", getCallingPid()); Mutex::Autolock lock(mLock); -#ifdef CAMERA_MSG_MGMT - disableMsgType(CAMERA_MSG_PREVIEW_METADATA); -#endif if (checkPidAndHardware() != NO_ERROR) return; #ifdef OMAP_ENHANCEMENT @@ -596,9 +588,6 @@ status_t CameraClient::takePicture(int msgType) { #if defined(OMAP_ICS_CAMERA) || defined(OMAP_ENHANCEMENT_BURST_CAPTURE) picMsgType |= CAMERA_MSG_COMPRESSED_BURST_IMAGE; -#endif -#ifdef CAMERA_MSG_MGMT - disableMsgType(CAMERA_MSG_PREVIEW_METADATA); #endif enableMsgType(picMsgType); #ifdef QCOM_HARDWARE diff --git a/services/camera/libcameraservice/device1/CameraHardwareInterface.h b/services/camera/libcameraservice/device1/CameraHardwareInterface.h index 6d051273b59..7e71c87017c 100644 --- a/services/camera/libcameraservice/device1/CameraHardwareInterface.h +++ b/services/camera/libcameraservice/device1/CameraHardwareInterface.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include "hardware/camera.h" #ifdef USE_MEMORY_HEAP_ION #include #endif