Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f53c36c6 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Respect channel mask in ACodec and NuPlayer." into jb-dev

parents ef7f3794 9806555d
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -121,8 +121,6 @@ private:
    sp<ExecutingToIdleState> mExecutingToIdleState;
    sp<IdleToLoadedState> mIdleToLoadedState;
    sp<FlushingState> mFlushingState;
    int32_t mEncoderDelay;
    int32_t mEncoderPadding;
    sp<SkipCutBuffer> mSkipCutBuffer;

    AString mComponentName;
@@ -149,6 +147,12 @@ private:
    // and do not release the component instance.
    bool mKeepComponentAllocated;

    int32_t mEncoderDelay;
    int32_t mEncoderPadding;

    bool mChannelMaskPresent;
    int32_t mChannelMask;

    status_t allocateBuffersOnPort(OMX_U32 portIndex);
    status_t freeBuffersOnPort(OMX_U32 portIndex);
    status_t freeBuffer(OMX_U32 portIndex, size_t i);
+7 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@
#define UTILS_H_

#include <stdint.h>
#include <utils/Errors.h>
#include <utils/RefBase.h>

namespace android {

@@ -36,6 +38,11 @@ uint64_t U64LE_AT(const uint8_t *ptr);
uint64_t ntoh64(uint64_t x);
uint64_t hton64(uint64_t x);

struct MetaData;
struct AMessage;
status_t convertMetaDataToMessage(
        const sp<MetaData> &meta, sp<AMessage> *format);

}  // namespace android

#endif  // UTILS_H_
+6 −1
Original line number Diff line number Diff line
@@ -375,10 +375,15 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
                        flags = AUDIO_OUTPUT_FLAG_NONE;
                    }

                    int32_t channelMask;
                    if (!codecRequest->findInt32("channel-mask", &channelMask)) {
                        channelMask = CHANNEL_MASK_USE_CHANNEL_ORDER;
                    }

                    CHECK_EQ(mAudioSink->open(
                                sampleRate,
                                numChannels,
                                CHANNEL_MASK_USE_CHANNEL_ORDER,
                                (audio_channel_mask_t)channelMask,
                                AUDIO_FORMAT_PCM_16_BIT,
                                8 /* bufferCount */,
                                NULL,
+7 −147
Original line number Diff line number Diff line
@@ -103,157 +103,17 @@ void NuPlayer::Decoder::onMessageReceived(const sp<AMessage> &msg) {
sp<AMessage> NuPlayer::Decoder::makeFormat(const sp<MetaData> &meta) {
    CHECK(mCSD.isEmpty());

    const char *mime;
    CHECK(meta->findCString(kKeyMIMEType, &mime));

    sp<AMessage> msg = new AMessage;
    msg->setString("mime", mime);

    if (!strncasecmp("video/", mime, 6)) {
        int32_t width, height;
        CHECK(meta->findInt32(kKeyWidth, &width));
        CHECK(meta->findInt32(kKeyHeight, &height));

        msg->setInt32("width", width);
        msg->setInt32("height", height);
    } else if (!strncasecmp("audio/", mime, 6)) {
        int32_t numChannels, sampleRate;
        CHECK(meta->findInt32(kKeyChannelCount, &numChannels));
        CHECK(meta->findInt32(kKeySampleRate, &sampleRate));

        msg->setInt32("channel-count", numChannels);
        msg->setInt32("sample-rate", sampleRate);

        int32_t delay = 0;
        if (meta->findInt32(kKeyEncoderDelay, &delay)) {
            msg->setInt32("encoder-delay", delay);
        }
        int32_t padding = 0;
        if (meta->findInt32(kKeyEncoderPadding, &padding)) {
            msg->setInt32("encoder-padding", padding);
        }

        int32_t isADTS;
        if (meta->findInt32(kKeyIsADTS, &isADTS) && isADTS != 0) {
            msg->setInt32("is-adts", true);
        }
    }

    int32_t maxInputSize;
    if (meta->findInt32(kKeyMaxInputSize, &maxInputSize)) {
        msg->setInt32("max-input-size", maxInputSize);
    }
    sp<AMessage> msg;
    CHECK_EQ(convertMetaDataToMessage(meta, &msg), (status_t)OK);

    mCSDIndex = 0;

    uint32_t type;
    const void *data;
    size_t size;
    if (meta->findData(kKeyAVCC, &type, &data, &size)) {
        // Parse the AVCDecoderConfigurationRecord

        const uint8_t *ptr = (const uint8_t *)data;

        CHECK(size >= 7);
        CHECK_EQ((unsigned)ptr[0], 1u);  // configurationVersion == 1
        uint8_t profile = ptr[1];
        uint8_t level = ptr[3];

        // There is decodable content out there that fails the following
        // assertion, let's be lenient for now...
        // CHECK((ptr[4] >> 2) == 0x3f);  // reserved

        size_t lengthSize = 1 + (ptr[4] & 3);

        // commented out check below as H264_QVGA_500_NO_AUDIO.3gp
        // violates it...
        // CHECK((ptr[5] >> 5) == 7);  // reserved

        size_t numSeqParameterSets = ptr[5] & 31;

        ptr += 6;
        size -= 6;

        sp<ABuffer> buffer = new ABuffer(1024);
        buffer->setRange(0, 0);

        for (size_t i = 0; i < numSeqParameterSets; ++i) {
            CHECK(size >= 2);
            size_t length = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            CHECK(size >= length);

            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
            buffer->setRange(0, buffer->size() + 4 + length);

            ptr += length;
            size -= length;
        }

        buffer->meta()->setInt32("csd", true);
        mCSD.push(buffer);

        buffer = new ABuffer(1024);
        buffer->setRange(0, 0);

        CHECK(size >= 1);
        size_t numPictureParameterSets = *ptr;
        ++ptr;
        --size;

        for (size_t i = 0; i < numPictureParameterSets; ++i) {
            CHECK(size >= 2);
            size_t length = U16_AT(ptr);

            ptr += 2;
            size -= 2;

            CHECK(size >= length);

            memcpy(buffer->data() + buffer->size(), "\x00\x00\x00\x01", 4);
            memcpy(buffer->data() + buffer->size() + 4, ptr, length);
            buffer->setRange(0, buffer->size() + 4 + length);

            ptr += length;
            size -= length;
    for (size_t i = 0;; ++i) {
        sp<ABuffer> csd;
        if (!msg->findBuffer(StringPrintf("csd-%d", i).c_str(), &csd)) {
            break;
        }

        buffer->meta()->setInt32("csd", true);
        mCSD.push(buffer);
    } else if (meta->findData(kKeyESDS, &type, &data, &size)) {
        ESDS esds((const char *)data, size);
        CHECK_EQ(esds.InitCheck(), (status_t)OK);

        const void *codec_specific_data;
        size_t codec_specific_data_size;
        esds.getCodecSpecificInfo(
                &codec_specific_data, &codec_specific_data_size);

        sp<ABuffer> buffer = new ABuffer(codec_specific_data_size);

        memcpy(buffer->data(), codec_specific_data,
               codec_specific_data_size);

        buffer->meta()->setInt32("csd", true);
        mCSD.push(buffer);
    } else if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
        sp<ABuffer> buffer = new ABuffer(size);
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        mCSD.push(buffer);

        CHECK(meta->findData(kKeyVorbisBooks, &type, &data, &size));

        buffer = new ABuffer(size);
        memcpy(buffer->data(), data, size);

        buffer->meta()->setInt32("csd", true);
        mCSD.push(buffer);
        mCSD.push(csd);
    }

    return msg;
+17 −1
Original line number Diff line number Diff line
@@ -333,7 +333,11 @@ ACodec::ACodec()
      mNode(NULL),
      mSentFormat(false),
      mIsEncoder(false),
      mShutdownInProgress(false) {
      mShutdownInProgress(false),
      mEncoderDelay(0),
      mEncoderPadding(0),
      mChannelMaskPresent(false),
      mChannelMask(0) {
    mUninitializedState = new UninitializedState(this);
    mLoadedState = new LoadedState(this);
    mLoadedToIdleState = new LoadedToIdleState(this);
@@ -892,10 +896,17 @@ status_t ACodec::configureCodec(
    if (!msg->findInt32("encoder-delay", &mEncoderDelay)) {
        mEncoderDelay = 0;
    }

    if (!msg->findInt32("encoder-padding", &mEncoderPadding)) {
        mEncoderPadding = 0;
    }

    if (msg->findInt32("channel-mask", &mChannelMask)) {
        mChannelMaskPresent = true;
    } else {
        mChannelMaskPresent = false;
    }

    int32_t maxInputSize;
    if (msg->findInt32("max-input-size", &maxInputSize)) {
        err = setMinBufferSize(kPortIndexInput, (size_t)maxInputSize);
@@ -2021,6 +2032,11 @@ void ACodec::sendFormatChange() {
                mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay * frameSize,
                                                   mEncoderPadding * frameSize);
            }

            if (mChannelMaskPresent) {
                notify->setInt32("channel-mask", mChannelMask);
            }

            break;
        }

Loading