summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/libavextensions/Android.mk8
-rw-r--r--media/libavextensions/media/AVMediaExtensions.h5
-rw-r--r--media/libavextensions/mediaplayerservice/AVNuUtils.cpp257
-rw-r--r--media/libavextensions/stagefright/AVUtils.cpp267
-rw-r--r--media/libmediaplayerservice/Android.mk3
-rw-r--r--media/libmediaplayerservice/nuplayer/Android.mk2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp63
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h10
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp12
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp214
11 files changed, 693 insertions, 149 deletions
diff --git a/media/libavextensions/Android.mk b/media/libavextensions/Android.mk
index 0b01669..a39a76e 100644
--- a/media/libavextensions/Android.mk
+++ b/media/libavextensions/Android.mk
@@ -22,7 +22,7 @@ ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS),true)
endif
LOCAL_MODULE:= libavextensions
-LOCAL_CLANG := false
+LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE_TAGS := optional
@@ -41,6 +41,7 @@ LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/native/include/media/hardware \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/flac/include \
+ $(TOP)/system/media/audio_utils/include \
$(TOP)/$(call project-path-for,qcom-media)/mm-core/inc
LOCAL_CFLAGS += -Wno-multichar -Werror
@@ -50,7 +51,7 @@ ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS),true)
endif
LOCAL_MODULE:= libavmediaextentions
-LOCAL_CLANG := false
+LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE_TAGS := optional
@@ -75,6 +76,7 @@ LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/native/include/media/hardware \
$(TOP)/frameworks/native/include/media/openmax \
$(TOP)/external/flac/include \
+ $(TOP)/system/media/audio_utils/include \
$(TOP)/$(call project-path-for,qcom-media)/mm-core/inc
LOCAL_CFLAGS += -Wno-multichar -Werror
@@ -88,7 +90,7 @@ ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
endif
LOCAL_MODULE:= libavmediaserviceextensions
-LOCAL_CLANG := false
+LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE_TAGS := optional
diff --git a/media/libavextensions/media/AVMediaExtensions.h b/media/libavextensions/media/AVMediaExtensions.h
index 9161fae..d48feec 100644
--- a/media/libavextensions/media/AVMediaExtensions.h
+++ b/media/libavextensions/media/AVMediaExtensions.h
@@ -33,6 +33,7 @@
#include <common/AVExtensionsCommon.h>
#include <hardware/audio.h>
#include <media/AudioTrack.h>
+#include <audio_utils/format.h>
namespace android {
@@ -43,8 +44,8 @@ class Parcel;
*/
struct AVMediaUtils {
- virtual bool AudioTrackIsPcmOffloaded(const audio_format_t /*format*/) {
- return false;
+ virtual bool AudioTrackIsPcmOffloaded(const audio_format_t format) {
+ return audio_is_offload_pcm(format);
}
virtual status_t AudioTrackGetPosition(AudioTrack* /*track*/,
uint32_t* /*position*/) {
diff --git a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
index a8defee..8a78767 100644
--- a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
+++ b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
@@ -30,10 +30,18 @@
#define LOG_TAG "AVNuUtils"
#include <utils/Log.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ADebug.h>
-#include <media/stagefright/foundation/AMessage.h>
-
+#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/OMXCodec.h>
+#include <cutils/properties.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/MediaProfiles.h>
+#include <media/stagefright/Utils.h>
+
+#include <audio_utils/format.h>
#include <nuplayer/NuPlayer.h>
#include <nuplayer/NuPlayerDecoderBase.h>
@@ -46,12 +54,116 @@
namespace android {
+static bool is24bitPCMOffloadEnabled() {
+ char propPCMOfload[PROPERTY_VALUE_MAX] = {0};
+ property_get("audio.offload.pcm.24bit.enable", propPCMOfload, "0");
+ if (!strncmp(propPCMOfload, "true", 4) || atoi(propPCMOfload))
+ return true;
+ else
+ return false;
+}
+
+static bool is16bitPCMOffloadEnabled() {
+ char propPCMOfload[PROPERTY_VALUE_MAX] = {0};
+ property_get("audio.offload.pcm.16bit.enable", propPCMOfload, "0");
+ if (!strncmp(propPCMOfload, "true", 4) || atoi(propPCMOfload))
+ return true;
+ else
+ return false;
+}
+
sp<MetaData> AVNuUtils::createPCMMetaFromSource(const sp<MetaData> &sMeta) {
- return sMeta;
+ sp<MetaData> tPCMMeta = new MetaData;
+ //hard code as RAW
+ tPCMMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+
+ int32_t bits = 16;
+ sMeta->findInt32(kKeyBitsPerSample, &bits);
+ tPCMMeta->setInt32(kKeyBitsPerSample, bits > 24 ? 24 : bits);
+
+ if (sMeta == NULL) {
+ ALOGW("no meta returning dummy meta");
+ return tPCMMeta;
+ }
+
+ int32_t srate = -1;
+ if (!sMeta->findInt32(kKeySampleRate, &srate)) {
+ ALOGV("No sample rate");
+ }
+ tPCMMeta->setInt32(kKeySampleRate, srate);
+
+ int32_t cmask = 0;
+ if (!sMeta->findInt32(kKeyChannelMask, &cmask) || (cmask == 0)) {
+ ALOGI("No channel mask, try channel count");
+ }
+ int32_t channelCount = 0;
+ if (!sMeta->findInt32(kKeyChannelCount, &channelCount)) {
+ ALOGI("No channel count either");
+ } else {
+ //if channel mask is not set till now, use channel count
+ //to retrieve channel count
+ if (!cmask) {
+ cmask = audio_channel_out_mask_from_count(channelCount);
+ }
+ }
+ tPCMMeta->setInt32(kKeyChannelCount, channelCount);
+ tPCMMeta->setInt32(kKeyChannelMask, cmask);
+
+ int64_t duration = INT_MAX;
+ if (!sMeta->findInt64(kKeyDuration, &duration)) {
+ ALOGW("No duration in meta setting max duration");
+ }
+ tPCMMeta->setInt64(kKeyDuration, duration);
+
+ int32_t bitRate = -1;
+ if (!sMeta->findInt32(kKeyBitRate, &bitRate)) {
+ ALOGW("No bitrate info");
+ } else {
+ tPCMMeta->setInt32(kKeyBitRate, bitRate);
+ }
+
+ return tPCMMeta;
}
-bool AVNuUtils::pcmOffloadException(const sp<MetaData> &) {
- return true;
+bool AVNuUtils::pcmOffloadException(const sp<MetaData> &meta) {
+ bool decision = false;
+ const char *mime = {0};
+
+ if (meta == NULL) {
+ return true;
+ }
+ meta->findCString(kKeyMIMEType, &mime);
+
+ if (!mime) {
+ ALOGV("%s: no audio mime present, ignoring pcm offload", __func__);
+ return true;
+ }
+//#if defined (PCM_OFFLOAD_ENABLED) || defined (PCM_OFFLOAD_ENABLED_24)
+ const char * const ExceptionTable[] = {
+ MEDIA_MIMETYPE_AUDIO_AMR_NB,
+ MEDIA_MIMETYPE_AUDIO_AMR_WB,
+ MEDIA_MIMETYPE_AUDIO_QCELP,
+ MEDIA_MIMETYPE_AUDIO_G711_ALAW,
+ MEDIA_MIMETYPE_AUDIO_G711_MLAW,
+ MEDIA_MIMETYPE_AUDIO_EVRC
+ };
+ int countException = (sizeof(ExceptionTable) / sizeof(ExceptionTable[0]));
+
+ for(int i = 0; i < countException; i++) {
+ if (!strcasecmp(mime, ExceptionTable[i])) {
+ decision = true;
+ break;
+ }
+ }
+ ALOGI("decision %d mime %s", decision, mime);
+ return decision;
+#if 0
+ //if PCM offload flag is disabled, do not offload any sessions
+ //using pcm offload
+ decision = true;
+ ALOGI("decision %d mime %s", decision, mime);
+ return decision;
+#endif
}
bool AVNuUtils::isRAWFormat(const sp<MetaData> &meta) {
@@ -83,44 +195,145 @@ bool AVNuUtils::isVorbisFormat(const sp<MetaData> &) {
return false;
}
-int AVNuUtils::updateAudioBitWidth(audio_format_t /*audioFormat*/,
- const sp<AMessage> &){
- return 16;
+int AVNuUtils::updateAudioBitWidth(audio_format_t audioFormat,
+ const sp<AMessage> &format){
+ int bits = 16;
+ if (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat)) {
+ bits = audio_bytes_per_sample(audioFormat) * 8;
+ format->setInt32("bits-per-sample", bits);
+ }
+ return bits;
}
audio_format_t AVNuUtils::getKeyPCMFormat(const sp<MetaData> &meta) {
- int32_t pcmFormat = 0;
- if (meta->findInt32('pfmt', &pcmFormat))
- return (audio_format_t)pcmFormat;
-
- return AUDIO_FORMAT_PCM_16_BIT;
+ audio_format_t pcmFormat = AUDIO_FORMAT_INVALID;
+ meta->findInt32('pfmt', (int32_t *)&pcmFormat);
+ return pcmFormat;
}
void AVNuUtils::setKeyPCMFormat(const sp<MetaData> &meta, audio_format_t audioFormat) {
- if (audio_is_linear_pcm(audioFormat))
+ if (meta != NULL && audio_is_linear_pcm(audioFormat))
meta->setInt32('pfmt', audioFormat);
}
-audio_format_t AVNuUtils::getPCMFormat(const sp<AMessage> &/*format*/) {
- return AUDIO_FORMAT_PCM_16_BIT;
+audio_format_t AVNuUtils::getPCMFormat(const sp<AMessage> &format) {
+ audio_format_t pcmFormat = AUDIO_FORMAT_INVALID;
+ format->findInt32("pcm-format", (int32_t *)&pcmFormat);
+ return pcmFormat;
}
void AVNuUtils::setPCMFormat(const sp<AMessage> &format, audio_format_t audioFormat) {
- if (audio_is_linear_pcm(audioFormat))
+ if (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat))
format->setInt32("pcm-format", audioFormat);
}
-void AVNuUtils::setSourcePCMFormat(const sp<MetaData> &) {
-
+void AVNuUtils::setSourcePCMFormat(const sp<MetaData> &audioMeta) {
+ audio_format_t pcmFormat = getKeyPCMFormat(audioMeta);
+ ALOGI("setSourcePCMFormat fmt=%x", pcmFormat);
+ audioMeta->dumpToLog();
+ if (pcmFormat == AUDIO_FORMAT_INVALID) {
+ int32_t bits = 16;
+ if (audioMeta->findInt32(kKeyBitsPerSample, &bits)) {
+ if (bits == 8)
+ pcmFormat = AUDIO_FORMAT_PCM_8_BIT;
+ if (bits == 24)
+ pcmFormat = AUDIO_FORMAT_PCM_32_BIT;
+ if (bits == 32)
+ pcmFormat = AUDIO_FORMAT_PCM_FLOAT;
+ setKeyPCMFormat(audioMeta, pcmFormat);
+ }
+ }
}
void AVNuUtils::setDecodedPCMFormat(const sp<AMessage> &) {
}
-status_t AVNuUtils::convertToSinkFormatIfNeeded(const sp<ABuffer> &, sp<ABuffer> &,
- audio_format_t /*sinkFormat*/, bool /*isOffload*/) {
- return INVALID_OPERATION;
+status_t AVNuUtils::convertToSinkFormatIfNeeded(
+ const sp<ABuffer> &buffer, sp<ABuffer> &newBuffer,
+ audio_format_t sinkFormat, bool isOffload) {
+
+ audio_format_t srcFormat = AUDIO_FORMAT_INVALID;
+ if (!buffer->meta()->findInt32("pcm-format", (int32_t *)&srcFormat)) {
+ newBuffer = buffer;
+ return OK;
+ }
+
+ size_t bps = audio_bytes_per_sample(srcFormat);
+
+ if (bps <= 0) {
+ ALOGE("Invalid pcmformat %x given for conversion", srcFormat);
+ return INVALID_OPERATION;
+ }
+
+ size_t frames = buffer->size() / bps;
+
+ if (frames == 0) {
+ ALOGE("zero sized buffer, nothing to convert");
+ return BAD_VALUE;
+ }
+
+ ALOGV("convert %zu bytes (frames %d) of format %x",
+ buffer->size(), frames, srcFormat);
+
+ audio_format_t dstFormat;
+ if (isOffload) {
+ switch (sinkFormat) {
+ case AUDIO_FORMAT_PCM_16_BIT_OFFLOAD:
+ dstFormat = AUDIO_FORMAT_PCM_16_BIT;
+ break;
+ case AUDIO_FORMAT_PCM_24_BIT_OFFLOAD:
+ if (srcFormat != AUDIO_FORMAT_PCM_24_BIT_PACKED &&
+ srcFormat != AUDIO_FORMAT_PCM_8_24_BIT) {
+ ALOGE("Invalid src format for 24 bit conversion");
+ return INVALID_OPERATION;
+ }
+ dstFormat = AUDIO_FORMAT_PCM_24_BIT_OFFLOAD;
+ break;
+ case AUDIO_FORMAT_DEFAULT:
+ ALOGI("OffloadInfo not yet initialized, retry");
+ return NO_INIT;
+ default:
+ ALOGE("Invalid offload format %x given for conversion",
+ sinkFormat);
+ return INVALID_OPERATION;
+ }
+ } else {
+ if (sinkFormat == AUDIO_FORMAT_INVALID) {
+ ALOGD("PCM Info not yet initialized, drop buffer");
+ return INVALID_OPERATION;
+ }
+
+ dstFormat = sinkFormat;
+ }
+ if (srcFormat == dstFormat) {
+ ALOGV("same format");
+ newBuffer = buffer;
+ return OK;
+ }
+
+ size_t dstFrameSize = audio_bytes_per_sample(dstFormat);
+ size_t dstBytes = frames * dstFrameSize;
+
+ newBuffer = new ABuffer(dstBytes);
+
+ memcpy_by_audio_format(newBuffer->data(), dstFormat,
+ buffer->data(), srcFormat, frames);
+
+ ALOGV("convert to format %x newBuffer->size() %zu",
+ dstFormat, newBuffer->size());
+
+ // copy over some meta info
+ int64_t timeUs = 0;
+ buffer->meta()->findInt64("timeUs", &timeUs);
+ newBuffer->meta()->setInt64("timeUs", timeUs);
+
+ int32_t eos = false;
+ buffer->meta()->findInt32("eos", &eos);
+ newBuffer->meta()->setInt32("eos", eos);
+
+ newBuffer->meta()->setInt32("pcm-format", (int32_t)dstFormat);
+ return OK;
}
void AVNuUtils::printFileName(int) {}
diff --git a/media/libavextensions/stagefright/AVUtils.cpp b/media/libavextensions/stagefright/AVUtils.cpp
index 2d5208f..c36e0bb 100644
--- a/media/libavextensions/stagefright/AVUtils.cpp
+++ b/media/libavextensions/stagefright/AVUtils.cpp
@@ -39,52 +39,291 @@
#include <media/stagefright/ACodec.h>
#include <media/stagefright/MediaCodec.h>
+#ifdef QCOM_HARDWARE
+#include "QCMediaDefs.h"
+#include "QCMetaData.h"
+#endif
+
#include "common/ExtensionsLoader.hpp"
#include "stagefright/AVExtensions.h"
namespace android {
+enum MetaKeyType{
+ INT32, INT64, STRING, DATA, CSD
+};
+
+struct MetaKeyEntry{
+ int MetaKey;
+ const char* MsgKey;
+ MetaKeyType KeyType;
+};
+
+static const MetaKeyEntry MetaKeyTable[] {
+#ifdef QCOM_HARDWARE
+ {kKeyAacCodecSpecificData , "aac-codec-specific-data", CSD},
+ {kKeyDivXVersion , "divx-version" , INT32}, // int32_t
+ {kKeyDivXDrm , "divx-drm" , DATA}, // void *
+ {kKeyWMAEncodeOpt , "wma-encode-opt" , INT32}, // int32_t
+ {kKeyWMABlockAlign , "wma-block-align" , INT32}, // int32_t
+ {kKeyWMAAdvEncOpt1 , "wma-adv-enc-opt1" , INT32}, // int16_t
+ {kKeyWMAAdvEncOpt2 , "wma-adv-enc-opt2" , INT32}, // int32_t
+ {kKeyWMAFormatTag , "wma-format-tag" , INT32}, // int32_t
+ {kKeyWMABitspersample , "wma-bits-per-sample" , INT32}, // int32_t
+ {kKeyWMAVirPktSize , "wma-vir-pkt-size" , INT32}, // int32_t
+ {kKeyWMAChannelMask , "wma-channel-mask" , INT32}, // int32_t
+ {kKeyFileFormat , "file-format" , STRING}, // cstring
+
+ {kkeyAacFormatAdif , "aac-format-adif" , INT32}, // bool (int32_t)
+ {kkeyAacFormatLtp , "aac-format-ltp" , INT32},
+
+ //DTS subtype
+ {kKeyDTSSubtype , "dts-subtype" , INT32}, //int32_t
+
+ //Extractor sets this
+ {kKeyUseArbitraryMode , "use-arbitrary-mode" , INT32}, //bool (int32_t)
+ {kKeySmoothStreaming , "smooth-streaming" , INT32}, //bool (int32_t)
+ {kKeyHFR , "hfr" , INT32}, // int32_t
+#endif
+
+
+ {kKeyBitRate , "bitrate" , INT32},
+ {kKeySampleRate , "sample-rate" , INT32},
+ {kKeyChannelCount , "channel-count" , INT32},
+ {kKeyRawCodecSpecificData , "raw-codec-specific-data", CSD},
+
+ {kKeyBitsPerSample , "bits-per-sample" , INT32},
+ {kKeyCodecId , "codec-id" , INT32},
+ {kKeySampleFormat , "sample-format" , INT32},
+ {kKeyBlockAlign , "block-align" , INT32},
+ {kKeyCodedSampleBits , "coded-sample-bits" , INT32},
+ {kKeyAACAOT , "aac-profile" , INT32},
+ {kKeyRVVersion , "rv-version" , INT32},
+ {kKeyWMAVersion , "wma-version" , INT32}, // int32_t
+ {kKeyWMVVersion , "wmv-version" , INT32},
+};
+
status_t AVUtils::convertMetaDataToMessage(
- const sp<MetaData> &, sp<AMessage> *) {
+ const sp<MetaData> &meta, sp<AMessage> *format) {
+ const char * str_val;
+ int32_t int32_val;
+ int64_t int64_val;
+ uint32_t data_type;
+ const void * data;
+ size_t size;
+ static const size_t numMetaKeys =
+ sizeof(MetaKeyTable) / sizeof(MetaKeyTable[0]);
+ size_t i;
+ for (i = 0; i < numMetaKeys; ++i) {
+ if (MetaKeyTable[i].KeyType == INT32 &&
+ meta->findInt32(MetaKeyTable[i].MetaKey, &int32_val)) {
+ ALOGV("found metakey %s of type int32", MetaKeyTable[i].MsgKey);
+ format->get()->setInt32(MetaKeyTable[i].MsgKey, int32_val);
+ } else if (MetaKeyTable[i].KeyType == INT64 &&
+ meta->findInt64(MetaKeyTable[i].MetaKey, &int64_val)) {
+ ALOGV("found metakey %s of type int64", MetaKeyTable[i].MsgKey);
+ format->get()->setInt64(MetaKeyTable[i].MsgKey, int64_val);
+ } else if (MetaKeyTable[i].KeyType == STRING &&
+ meta->findCString(MetaKeyTable[i].MetaKey, &str_val)) {
+ ALOGV("found metakey %s of type string", MetaKeyTable[i].MsgKey);
+ format->get()->setString(MetaKeyTable[i].MsgKey, str_val);
+ } else if ( (MetaKeyTable[i].KeyType == DATA ||
+ MetaKeyTable[i].KeyType == CSD) &&
+ meta->findData(MetaKeyTable[i].MetaKey, &data_type, &data, &size)) {
+ ALOGV("found metakey %s of type data", MetaKeyTable[i].MsgKey);
+ if (MetaKeyTable[i].KeyType == CSD) {
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+ if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
+ sp<ABuffer> buffer = new ABuffer(size);
+ memcpy(buffer->data(), data, size);
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ format->get()->setBuffer("csd-0", buffer);
+ } else {
+ const uint8_t *ptr = (const uint8_t *)data;
+ CHECK(size >= 8);
+ int seqLength = 0, picLength = 0;
+ for (size_t i = 4; i < (size - 4); i++)
+ {
+ if ((*(ptr + i) == 0) && (*(ptr + i + 1) == 0) &&
+ (*(ptr + i + 2) == 0) && (*(ptr + i + 3) == 1))
+ seqLength = i;
+ }
+ sp<ABuffer> buffer = new ABuffer(seqLength);
+ memcpy(buffer->data(), data, seqLength);
+ buffer->meta()->setInt32("csd", true);
+ buffer->meta()->setInt64("timeUs", 0);
+ format->get()->setBuffer("csd-0", buffer);
+ picLength=size-seqLength;
+ sp<ABuffer> buffer1 = new ABuffer(picLength);
+ memcpy(buffer1->data(), (const uint8_t *)data + seqLength, picLength);
+ buffer1->meta()->setInt32("csd", true);
+ buffer1->meta()->setInt64("timeUs", 0);
+ format->get()->setBuffer("csd-1", buffer1);
+ }
+ } else {
+ sp<ABuffer> buffer = new ABuffer(size);
+ memcpy(buffer->data(), data, size);
+ format->get()->setBuffer(MetaKeyTable[i].MsgKey, buffer);
+ }
+ }
+ }
return OK;
}
+struct mime_conv_t {
+ const char* mime;
+ audio_format_t format;
+};
+
+static const struct mime_conv_t mimeLookup[] = {
+ { MEDIA_MIMETYPE_AUDIO_MPEG, AUDIO_FORMAT_MP3 },
+ { MEDIA_MIMETYPE_AUDIO_RAW, AUDIO_FORMAT_PCM_16_BIT },
+ { MEDIA_MIMETYPE_AUDIO_AMR_NB, AUDIO_FORMAT_AMR_NB },
+ { MEDIA_MIMETYPE_AUDIO_AMR_WB, AUDIO_FORMAT_AMR_WB },
+ { MEDIA_MIMETYPE_AUDIO_AAC, AUDIO_FORMAT_AAC },
+ { MEDIA_MIMETYPE_AUDIO_VORBIS, AUDIO_FORMAT_VORBIS },
+ { MEDIA_MIMETYPE_AUDIO_OPUS, AUDIO_FORMAT_OPUS},
+#ifdef QCOM_HARDWARE
+ { MEDIA_MIMETYPE_AUDIO_AC3, AUDIO_FORMAT_AC3 },
+ { MEDIA_MIMETYPE_AUDIO_AMR_WB_PLUS, AUDIO_FORMAT_AMR_WB_PLUS },
+ { MEDIA_MIMETYPE_AUDIO_DTS, AUDIO_FORMAT_DTS },
+ { MEDIA_MIMETYPE_AUDIO_EAC3, AUDIO_FORMAT_E_AC3 },
+ { MEDIA_MIMETYPE_AUDIO_EVRC, AUDIO_FORMAT_EVRC },
+ { MEDIA_MIMETYPE_AUDIO_QCELP, AUDIO_FORMAT_QCELP },
+ { MEDIA_MIMETYPE_AUDIO_WMA, AUDIO_FORMAT_WMA },
+ { MEDIA_MIMETYPE_AUDIO_FLAC, AUDIO_FORMAT_FLAC },
+ { MEDIA_MIMETYPE_CONTAINER_QTIFLAC, AUDIO_FORMAT_FLAC },
+#ifdef DOLBY_UDC
+ { MEDIA_MIMETYPE_AUDIO_EAC3_JOC, AUDIO_FORMAT_E_AC3_JOC },
+#endif
+#endif
+ { 0, AUDIO_FORMAT_INVALID }
+};
+
status_t AVUtils::mapMimeToAudioFormat(
- audio_format_t&, const char* ) {
- return OK;
+ audio_format_t& format, const char* mime) {
+ const struct mime_conv_t* p = &mimeLookup[0];
+ while (p->mime != NULL) {
+ if (0 == strcasecmp(mime, p->mime)) {
+ format = p->format;
+ return OK;
+ }
+ ++p;
+ }
+
+ return BAD_VALUE;
}
status_t AVUtils::sendMetaDataToHal(
- const sp<MetaData>&, AudioParameter *){
- return OK;
+ const sp<MetaData>& meta, AudioParameter *param){
+#ifdef FLAC_OFFLOAD_ENABLED
+ int32_t minBlkSize, maxBlkSize, minFrmSize, maxFrmSize; //FLAC params
+ 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);
+ }
+#else
+ (void)meta;
+ (void)param;
+#endif
+ return OK;
+}
+
+bool AVUtils::is24bitPCMOffloadEnabled() {
+ char propPCMOfload[PROPERTY_VALUE_MAX] = {0};
+ property_get("audio.offload.pcm.24bit.enable", propPCMOfload, "0");
+ if (!strncmp(propPCMOfload, "true", 4) || atoi(propPCMOfload))
+ return true;
+ else
+ return false;
+}
+
+bool AVUtils::is16bitPCMOffloadEnabled() {
+ char propPCMOfload[PROPERTY_VALUE_MAX] = {0};
+ property_get("audio.offload.pcm.16bit.enable", propPCMOfload, "0");
+ if (!strncmp(propPCMOfload, "true", 4) || atoi(propPCMOfload))
+ return true;
+ else
+ return false;
}
-bool AVUtils::is24bitPCMOffloadEnabled() {return false;}
-bool AVUtils::is16bitPCMOffloadEnabled() {return false;}
-int AVUtils::getAudioSampleBits(const sp<MetaData> &) {
- return 16;
+int AVUtils::getAudioSampleBits(const sp<MetaData> &meta) {
+ int32_t bits = 16;
+ audio_format_t audioFormat = AUDIO_FORMAT_INVALID;
+ if (meta->findInt32('pfmt', (int32_t *)&audioFormat)) {
+ bits = audio_bytes_per_sample(audioFormat) * 8;
+ } else if (meta->findInt32(kKeyBitsPerSample, &bits)) {
+ return bits;
+ }
+ return bits;
}
int AVUtils::getAudioSampleBits(const sp<AMessage> &format) {
int32_t bits = 16;
- format->findInt32("bits-per-sample", &bits);
+ audio_format_t audioFormat = AUDIO_FORMAT_INVALID;
+ if (format->findInt32("pcm-format", (int32_t *)&audioFormat)) {
+ bits = audio_bytes_per_sample(audioFormat) * 8;
+ } else if (format->findInt32("bits-per-sample", &bits)) {
+ return bits;
+ }
return bits;
}
-void AVUtils::setPcmSampleBits(const sp<AMessage> &, int32_t /*bitWidth*/) {
+void AVUtils::setPcmSampleBits(const sp<AMessage> &format, int32_t bitWidth) {
+ format->setInt32("bits-per-sample", bitWidth);
}
-void AVUtils::setPcmSampleBits(const sp<MetaData> &, int32_t /*bitWidth*/) {
+void AVUtils::setPcmSampleBits(const sp<MetaData> &meta, int32_t bitWidth) {
+ meta->setInt32(kKeyBitsPerSample, bitWidth);
}
audio_format_t AVUtils::updateAudioFormat(audio_format_t audioFormat,
- const sp<MetaData> &){
+ const sp<MetaData> &meta){
+ int32_t bits = getAudioSampleBits(meta);
+
+ ALOGV("updateAudioFormat %x %d", audioFormat, bits);
+ meta->dumpToLog();
+
+ // Override audio format for PCM offload
+ if (audio_is_linear_pcm(audioFormat)) {
+ if (bits > 16 && is24bitPCMOffloadEnabled()) {
+ audioFormat = AUDIO_FORMAT_PCM_24_BIT_OFFLOAD;
+ meta->setInt32(kKeyBitsPerSample, 24);
+ } else if (bits == 16 && is16bitPCMOffloadEnabled()) {
+ audioFormat = AUDIO_FORMAT_PCM_16_BIT_OFFLOAD;
+ }
+ }
+
return audioFormat;
}
audio_format_t AVUtils::updateAudioFormat(audio_format_t audioFormat,
- const sp<AMessage> &){
+ const sp<AMessage> &format){
+ int32_t bits = getAudioSampleBits(format);
+
+ ALOGV("updateAudioFormat %x %d %s", audioFormat, bits, format->debugString().c_str());
+
+ // Override audio format for PCM offload
+ if (audio_is_linear_pcm(audioFormat)) {
+ if (bits > 16 && is24bitPCMOffloadEnabled()) {
+ audioFormat = AUDIO_FORMAT_PCM_24_BIT_OFFLOAD;
+ format->setInt32("bits-per-sample", 24);
+ } else if (bits == 16 && is16bitPCMOffloadEnabled()) {
+ audioFormat = AUDIO_FORMAT_PCM_16_BIT_OFFLOAD;
+ }
+ }
+
return audioFormat;
}
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 7c4aa3d..6575625 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -40,6 +40,7 @@ LOCAL_SHARED_LIBRARIES := \
libstagefright_wfd \
libutils \
libvorbisidec \
+ libaudioutils \
LOCAL_STATIC_LIBRARIES := \
libstagefright_nuplayer \
@@ -57,7 +58,7 @@ LOCAL_C_INCLUDES := \
$(TOP)/external/tremolo/Tremolo \
$(TOP)/frameworks/av/media/libavextensions \
-LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall
+LOCAL_CFLAGS += -Werror -Wno-error=deprecated-declarations -Wall #-DLOG_NDEBUG=0
LOCAL_CLANG := true
LOCAL_MODULE:= libmediaplayerservice
diff --git a/media/libmediaplayerservice/nuplayer/Android.mk b/media/libmediaplayerservice/nuplayer/Android.mk
index cc1bdb4..fbb1276 100644
--- a/media/libmediaplayerservice/nuplayer/Android.mk
+++ b/media/libmediaplayerservice/nuplayer/Android.mk
@@ -27,7 +27,7 @@ LOCAL_C_INCLUDES := \
$(TOP)/frameworks/av/media/libavextensions \
$(TOP)/frameworks/av/include/media \
-LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CFLAGS += -Werror -Wall #-DLOG_NDEBUG=0
# enable experiments only in userdebug and eng builds
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index de507f1..678db8e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -189,6 +189,7 @@ NuPlayer::NuPlayer(pid_t pid)
mPID(pid),
mSourceFlags(0),
mOffloadAudio(false),
+ mOffloadDecodedPCM(false),
mAudioDecoderGeneration(0),
mVideoDecoderGeneration(0),
mRendererGeneration(0),
@@ -1133,10 +1134,12 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
mResetting = true;
- mDeferredActions.push_back(
- new FlushDecoderAction(
- FLUSH_CMD_SHUTDOWN /* audio */,
- FLUSH_CMD_SHUTDOWN /* video */));
+ if (mAudioDecoder != NULL && mFlushingAudio == NONE) {
+ mDeferredActions.push_back(
+ new FlushDecoderAction(
+ FLUSH_CMD_SHUTDOWN /* audio */,
+ FLUSH_CMD_SHUTDOWN /* video */));
+ }
mDeferredActions.push_back(
new SimpleAction(&NuPlayer::closeAudioSink));
@@ -1228,9 +1231,16 @@ void NuPlayer::onResume() {
} else {
ALOGW("resume called when source is gone or not set");
}
+ if (mOffloadAudio && !mOffloadDecodedPCM) {
+ // Resuming after a pause timed out event, check if can continue with offload
+ sp<AMessage> videoFormat = mSource->getFormat(false /* audio */);
+ sp<AMessage> format = mSource->getFormat(true /*audio*/);
+ const bool hasVideo = (videoFormat != NULL);
+ tryOpenAudioSinkForOffload(format, hasVideo);
+ }
// |mAudioDecoder| may have been released due to the pause timeout, so re-create it if
// needed.
- if (audioDecoderStillNeeded() && mAudioDecoder == NULL) {
+ if (audioDecoderStillNeeded() && mAudioDecoder == NULL && !mOffloadDecodedPCM) {
instantiateDecoder(true /* audio */, &mAudioDecoder);
}
if (mRenderer != NULL) {
@@ -1282,6 +1292,7 @@ void NuPlayer::onStart(int64_t startPositionUs) {
}
mOffloadAudio = false;
+ mOffloadDecodedPCM = false;
mAudioEOS = false;
mVideoEOS = false;
mStarted = true;
@@ -1292,8 +1303,10 @@ void NuPlayer::onStart(int64_t startPositionUs) {
flags |= Renderer::FLAG_REAL_TIME;
}
+ ALOGV("onStart");
sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
AVNuUtils::get()->setSourcePCMFormat(audioMeta);
+ audioMeta->dumpToLog();
audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
if (mAudioSink != NULL) {
streamType = mAudioSink->getAudioStreamType();
@@ -1690,6 +1703,18 @@ void NuPlayer::flushDecoder(bool audio, bool needShutdown) {
return;
}
+ FlushStatus *state = audio ? &mFlushingAudio : &mFlushingVideo;
+
+ bool inShutdown = *state != NONE &&
+ *state != FLUSHING_DECODER &&
+ *state != FLUSHED;
+
+ // Reject flush if the decoder state is not one of the above
+ if (inShutdown) {
+ ALOGI("flush %s called while in shutdown", audio ? "audio" : "video");
+ return;
+ }
+
// Make sure we don't continue to scan sources until we finish flushing.
++mScanSourcesGeneration;
if (mScanSourcesPending) {
@@ -2433,4 +2458,32 @@ void NuPlayer::performTearDown(const sp<AMessage> &msg) {
processDeferredActions();
}
+bool NuPlayer::ifDecodedPCMOffload() {
+ return mOffloadDecodedPCM;
+}
+
+void NuPlayer::setDecodedPcmOffload(bool decodePcmOffload) {
+ mOffloadDecodedPCM = decodePcmOffload;
+}
+
+bool NuPlayer::canOffloadDecodedPCMStream(const sp<MetaData> audioMeta,
+ bool hasVideo, bool isStreaming, audio_stream_type_t streamType) {
+ const char *mime = NULL;
+
+ //For offloading decoded content
+ if (!mOffloadAudio && (audioMeta != NULL)) {
+ audioMeta->findCString(kKeyMIMEType, &mime);
+ sp<MetaData> audioPCMMeta =
+ AVNuUtils::get()->createPCMMetaFromSource(audioMeta);
+
+ ALOGI("canOffloadDecodedPCMStream");
+ audioMeta->dumpToLog();
+ mOffloadDecodedPCM =
+ ((mime && !AVNuUtils::get()->pcmOffloadException(audioMeta)) &&
+ canOffloadStream(audioPCMMeta, hasVideo, isStreaming, streamType));
+ ALOGI("PCM offload decided: %d", mOffloadDecodedPCM);
+ }
+ return mOffloadDecodedPCM;
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index ee0f3e6..c093b0f 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -86,11 +86,12 @@ protected:
virtual ~NuPlayer();
virtual void onMessageReceived(const sp<AMessage> &msg);
- virtual bool ifDecodedPCMOffload() {return false;}
- virtual void setDecodedPcmOffload(bool /*decodePcmOffload*/) {}
- virtual bool canOffloadDecodedPCMStream(const sp<MetaData> /*meta*/,
- bool /*hasVideo*/, bool /*isStreaming*/, audio_stream_type_t /*streamType*/) {return false;}
+ virtual bool ifDecodedPCMOffload();
+ virtual void setDecodedPcmOffload(bool decodePcmOffload);
+ virtual bool canOffloadDecodedPCMStream(const sp<MetaData> meta,
+ bool hasVideo, bool isStreaming, audio_stream_type_t streamType);
static bool IsHTTPLiveURL(const char *url);
+
public:
struct NuPlayerStreamListener;
struct Source;
@@ -151,6 +152,7 @@ protected:
sp<MediaPlayerBase::AudioSink> mAudioSink;
sp<DecoderBase> mVideoDecoder;
bool mOffloadAudio;
+ bool mOffloadDecodedPCM;
sp<DecoderBase> mAudioDecoder;
sp<CCDecoder> mCCDecoder;
sp<Renderer> mRenderer;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 937936d..0b50d0d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -53,7 +53,8 @@ NuPlayer::DecoderPassThrough::DecoderPassThrough(
mPendingAudioErr(OK),
mPendingBuffersToDrain(0),
mCachedBytes(0),
- mComponentName("pass through decoder") {
+ mComponentName("pass through decoder"),
+ mPCMFormat(AUDIO_FORMAT_INVALID) {
ALOGW_IF(renderer == NULL, "expect a non-NULL renderer");
}
@@ -75,6 +76,15 @@ void NuPlayer::DecoderPassThrough::onConfigure(const sp<AMessage> &format) {
// The audio sink is already opened before the PassThrough decoder is created.
// Opening again might be relevant if decoder is instantiated after shutdown and
// format is different.
+ sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
+ if (AVNuUtils::get()->isRAWFormat(audioMeta)) {
+ mPCMFormat = AVNuUtils::get()->getKeyPCMFormat(audioMeta);
+ if (mPCMFormat != AUDIO_FORMAT_INVALID) {
+ AVNuUtils::get()->setPCMFormat(format, mPCMFormat);
+ AVNuUtils::get()->updateAudioBitWidth(mPCMFormat, format);
+ }
+ }
+
status_t err = mRenderer->openAudioSink(
format, true /* offloadOnly */, hasVideo,
AUDIO_OUTPUT_FLAG_NONE /* flags */, NULL /* isOffloaded */, mSource->isStreaming());
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
index 629e266..fbc4087 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.h
@@ -69,6 +69,7 @@ private:
size_t mPendingBuffersToDrain;
size_t mCachedBytes;
AString mComponentName;
+ audio_format_t mPCMFormat;
bool isStaleReply(const sp<AMessage> &msg);
bool isDoneFetching() const;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 049b79d..9cf6b62 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -1250,6 +1250,30 @@ void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
if (audio) {
Mutex::Autolock autoLock(mLock);
+#if 1
+ sp<ABuffer> newBuffer;
+ status_t err = AVNuUtils::get()->convertToSinkFormatIfNeeded(
+ buffer, newBuffer,
+ (offloadingAudio() ? mCurrentOffloadInfo.format : mCurrentPcmInfo.mFormat),
+ offloadingAudio());
+ switch (err) {
+ case NO_INIT:
+ // passthru decoder pushes some buffers before the audio sink
+ // is opened. Since the offload format is known only when the sink
+ // is opened, pcm conversions cannot take place. So, retry.
+ ALOGI("init pending, retrying in 10ms, this shouldn't happen");
+ msg->post(10000LL);
+ return;
+ case OK:
+ break;
+ default:
+ ALOGW("error 0x%x in converting to sink format, drop buffer", err);
+ notifyConsumed->post();
+ return;
+ }
+ CHECK(newBuffer != NULL);
+ entry.mBuffer = newBuffer;
+#endif
mAudioQueue.push_back(entry);
postDrainAudioQueue_l();
} else {
@@ -1727,108 +1751,106 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
AString mime;
CHECK(format->findString("mime", &mime));
- if (offloadingAudio()) {
- audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
- status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
+ audio_format_t audioFormat = AUDIO_FORMAT_PCM_16_BIT;
+ status_t err = mapMimeToAudioFormat(audioFormat, mime.c_str());
- if (err != OK) {
- ALOGE("Couldn't map mime \"%s\" to a valid "
- "audio_format", mime.c_str());
- onDisableOffloadAudio();
- } else {
- audioFormat = AVUtils::get()->updateAudioFormat(audioFormat, format);
-
- bitWidth = AVUtils::get()->getAudioSampleBits(format);
- int avgBitRate = -1;
- format->findInt32("bitrate", &avgBitRate);
-
- int32_t aacProfile = -1;
- if (audioFormat == AUDIO_FORMAT_AAC
- && format->findInt32("aac-profile", &aacProfile)) {
- // Redefine AAC format as per aac profile
- int32_t isADTSSupported;
- isADTSSupported = AVUtils::get()->mapAACProfileToAudioFormat(format,
- audioFormat,
- aacProfile);
- if (!isADTSSupported) {
- mapAACProfileToAudioFormat(audioFormat,
- aacProfile);
- } else {
- ALOGV("Format is AAC ADTS\n");
- }
+ if (err != OK) {
+ ALOGE("Couldn't map mime \"%s\" to a valid "
+ "audio_format", mime.c_str());
+ onDisableOffloadAudio();
+ } else {
+ audioFormat = AVUtils::get()->updateAudioFormat(audioFormat, format);
+
+ bitWidth = AVUtils::get()->getAudioSampleBits(format);
+ int avgBitRate = -1;
+ format->findInt32("bitrate", &avgBitRate);
+
+ int32_t aacProfile = -1;
+ if (audioFormat == AUDIO_FORMAT_AAC
+ && format->findInt32("aac-profile", &aacProfile)) {
+ // Redefine AAC format as per aac profile
+ int32_t isADTSSupported;
+ isADTSSupported = AVUtils::get()->mapAACProfileToAudioFormat(format,
+ audioFormat,
+ aacProfile);
+ if (!isADTSSupported) {
+ mapAACProfileToAudioFormat(audioFormat,
+ aacProfile);
+ } else {
+ ALOGV("Format is AAC ADTS\n");
}
+ }
- int32_t offloadBufferSize =
- AVUtils::get()->getAudioMaxInputBufferSize(
- audioFormat,
- format);
- audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
-
- offloadInfo.duration_us = -1;
- format->findInt64(
- "durationUs", &offloadInfo.duration_us);
- offloadInfo.sample_rate = sampleRate;
- offloadInfo.channel_mask = channelMask;
- offloadInfo.format = audioFormat;
- offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
- offloadInfo.bit_rate = avgBitRate;
- offloadInfo.has_video = hasVideo;
- offloadInfo.is_streaming = isStreaming;
- offloadInfo.bit_width = bitWidth;
- offloadInfo.offload_buffer_size = offloadBufferSize;
-
- if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
- ALOGV("openAudioSink: no change in offload mode");
- // no change from previous configuration, everything ok.
- return OK;
- }
- mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
+ int32_t offloadBufferSize =
+ AVUtils::get()->getAudioMaxInputBufferSize(
+ audioFormat,
+ format);
+ audio_offload_info_t offloadInfo = AUDIO_INFO_INITIALIZER;
+
+ offloadInfo.duration_us = -1;
+ format->findInt64(
+ "durationUs", &offloadInfo.duration_us);
+ offloadInfo.sample_rate = sampleRate;
+ offloadInfo.channel_mask = channelMask;
+ offloadInfo.format = audioFormat;
+ offloadInfo.stream_type = AUDIO_STREAM_MUSIC;
+ offloadInfo.bit_rate = avgBitRate;
+ offloadInfo.has_video = hasVideo;
+ offloadInfo.is_streaming = isStreaming;
+ offloadInfo.bit_width = bitWidth;
+ offloadInfo.offload_buffer_size = offloadBufferSize;
+
+ if (memcmp(&mCurrentOffloadInfo, &offloadInfo, sizeof(offloadInfo)) == 0) {
+ ALOGV("openAudioSink: no change in offload mode");
+ // no change from previous configuration, everything ok.
+ return OK;
+ }
+ mCurrentPcmInfo = AUDIO_PCMINFO_INITIALIZER;
- ALOGV("openAudioSink: try to open AudioSink in offload mode");
- uint32_t offloadFlags = flags;
- offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
- offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
- audioSinkChanged = true;
- mAudioSink->close();
+ ALOGV("openAudioSink: try to open AudioSink in offload mode");
+ uint32_t offloadFlags = flags;
+ offloadFlags |= AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD;
+ offloadFlags &= ~AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
+ audioSinkChanged = true;
+ mAudioSink->close();
- err = mAudioSink->open(
- sampleRate,
- numChannels,
- (audio_channel_mask_t)channelMask,
- audioFormat,
- 0 /* bufferCount - unused */,
- &NuPlayer::Renderer::AudioSinkCallback,
- this,
- (audio_output_flags_t)offloadFlags,
- &offloadInfo);
+ err = mAudioSink->open(
+ sampleRate,
+ numChannels,
+ (audio_channel_mask_t)channelMask,
+ audioFormat,
+ 0 /* bufferCount - unused */,
+ &NuPlayer::Renderer::AudioSinkCallback,
+ this,
+ (audio_output_flags_t)offloadFlags,
+ &offloadInfo);
- if (err == OK) {
- err = mAudioSink->setPlaybackRate(mPlaybackSettings);
- }
+ if (err == OK) {
+ err = mAudioSink->setPlaybackRate(mPlaybackSettings);
+ }
- if (err == OK) {
- // If the playback is offloaded to h/w, we pass
- // the HAL some metadata information.
- // We don't want to do this for PCM because it
- // will be going through the AudioFlinger mixer
- // before reaching the hardware.
- // TODO
- mCurrentOffloadInfo = offloadInfo;
- if (!mPaused) { // for preview mode, don't start if paused
- err = mAudioSink->start();
- }
- ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
- }
- if (err != OK) {
- // Clean up, fall back to non offload mode.
- mAudioSink->close();
- onDisableOffloadAudio();
- mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
- ALOGV("openAudioSink: offload failed");
- } else {
- mUseAudioCallback = true; // offload mode transfers data through callback
- ++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message.
+ if (err == OK) {
+ // If the playback is offloaded to h/w, we pass
+ // the HAL some metadata information.
+ // We don't want to do this for PCM because it
+ // will be going through the AudioFlinger mixer
+ // before reaching the hardware.
+ // TODO
+ mCurrentOffloadInfo = offloadInfo;
+ if (!mPaused) { // for preview mode, don't start if paused
+ err = mAudioSink->start();
}
+ ALOGV_IF(err == OK, "openAudioSink: offload succeeded");
+ }
+ if (err != OK) {
+ // Clean up, fall back to non offload mode.
+ mAudioSink->close();
+ onDisableOffloadAudio();
+ mCurrentOffloadInfo = AUDIO_INFO_INITIALIZER;
+ ALOGV("openAudioSink: offload failed");
+ } else {
+ mUseAudioCallback = true; // offload mode transfers data through callback
+ ++mAudioDrainGeneration; // discard pending kWhatDrainAudioQueue message.
}
}
if (!offloadOnly && !offloadingAudio()) {
@@ -1839,7 +1861,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
const PcmInfo info = {
(audio_channel_mask_t)channelMask,
(audio_output_flags_t)pcmFlags,
- getPCMFormat(format),
+ AVNuUtils::get()->getPCMFormat(format),
numChannels,
sampleRate
};
@@ -1874,7 +1896,7 @@ status_t NuPlayer::Renderer::onOpenAudioSink(
sampleRate,
numChannels,
(audio_channel_mask_t)channelMask,
- getPCMFormat(format),
+ AVNuUtils::get()->getPCMFormat(format),
0 /* bufferCount - unused */,
mUseAudioCallback ? &NuPlayer::Renderer::AudioSinkCallback : NULL,
mUseAudioCallback ? this : NULL,