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

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

Merge "Instantiate HDCP module, add PES_private_data for encrypted streams." into jb-mr1-dev

parents b88516c4 b8c7bd41
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ include $(CLEAR_VARS)

LOCAL_SRC_FILES:= \
        ANetworkSession.cpp             \
        Parameters.cpp                  \
        ParsedMessage.cpp               \
        sink/LinearRegression.cpp       \
        sink/RTPSink.cpp                \
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "Parameters.h"

#include <media/stagefright/MediaErrors.h>

namespace android {

// static
sp<Parameters> Parameters::Parse(const char *data, size_t size) {
    sp<Parameters> params = new Parameters;
    status_t err = params->parse(data, size);

    if (err != OK) {
        return NULL;
    }

    return params;
}

Parameters::Parameters() {}

Parameters::~Parameters() {}

status_t Parameters::parse(const char *data, size_t size) {
    size_t i = 0;
    while (i < size) {
        size_t nameStart = i;
        while (i < size && data[i] != ':') {
            ++i;
        }

        if (i == size || i == nameStart) {
            return ERROR_MALFORMED;
        }

        AString name(&data[nameStart], i - nameStart);
        name.trim();
        name.tolower();

        ++i;

        size_t valueStart = i;

        while (i + 1 < size && (data[i] != '\r' || data[i + 1] != '\n')) {
            ++i;
        }

        AString value(&data[valueStart], i - valueStart);
        value.trim();

        mDict.add(name, value);

        i += 2;
    }

    return OK;
}

bool Parameters::findParameter(const char *name, AString *value) const {
    AString key = name;
    key.tolower();

    ssize_t index = mDict.indexOfKey(key);

    if (index < 0) {
        value->clear();

        return false;
    }

    *value = mDict.valueAt(index);
    return true;
}

}  // namespace android
+41 −0
Original line number Diff line number Diff line
/*
 * Copyright 2012, The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <media/stagefright/foundation/ABase.h>
#include <media/stagefright/foundation/AString.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>

namespace android {

struct Parameters : public RefBase {
    static sp<Parameters> Parse(const char *data, size_t size);

    bool findParameter(const char *name, AString *value) const;

protected:
    virtual ~Parameters();

private:
    KeyedVector<AString, AString> mDict;

    Parameters();
    status_t parse(const char *data, size_t size);

    DISALLOW_EVIL_CONSTRUCTORS(Parameters);
};

}  // namespace android
+95 −4
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include <binder/IServiceManager.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <media/IHDCP.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -63,6 +64,7 @@ struct WifiDisplaySource::PlaybackSession::Track : public RefBase {
    Track(const sp<AMessage> &format);

    sp<AMessage> getFormat();
    bool isAudio() const;

    const sp<Converter> &converter() const;
    ssize_t packetizerTrackIndex() const;
@@ -83,6 +85,9 @@ private:
    sp<AMessage> mFormat;
    bool mStarted;
    ssize_t mPacketizerTrackIndex;
    bool mIsAudio;

    static bool IsAudioFormat(const sp<AMessage> &format);

    DISALLOW_EVIL_CONSTRUCTORS(Track);
};
@@ -97,18 +102,29 @@ WifiDisplaySource::PlaybackSession::Track::Track(
      mMediaPuller(mediaPuller),
      mConverter(converter),
      mStarted(false),
      mPacketizerTrackIndex(-1) {
      mPacketizerTrackIndex(-1),
      mIsAudio(IsAudioFormat(mConverter->getOutputFormat())) {
}

WifiDisplaySource::PlaybackSession::Track::Track(const sp<AMessage> &format)
    : mFormat(format),
      mPacketizerTrackIndex(-1) {
      mPacketizerTrackIndex(-1),
      mIsAudio(IsAudioFormat(mFormat)) {
}

WifiDisplaySource::PlaybackSession::Track::~Track() {
    stop();
}

// static
bool WifiDisplaySource::PlaybackSession::Track::IsAudioFormat(
        const sp<AMessage> &format) {
    AString mime;
    CHECK(format->findString("mime", &mime));

    return !strncasecmp(mime.c_str(), "audio/", 6);
}

sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
    if (mFormat != NULL) {
        return mFormat;
@@ -117,6 +133,10 @@ sp<AMessage> WifiDisplaySource::PlaybackSession::Track::getFormat() {
    return mConverter->getOutputFormat();
}

bool WifiDisplaySource::PlaybackSession::Track::isAudio() const {
    return mIsAudio;
}

const sp<Converter> &WifiDisplaySource::PlaybackSession::Track::converter() const {
    return mConverter;
}
@@ -172,11 +192,13 @@ WifiDisplaySource::PlaybackSession::PlaybackSession(
        const sp<ANetworkSession> &netSession,
        const sp<AMessage> &notify,
        const in_addr &interfaceAddr,
        bool legacyMode)
        bool legacyMode,
        const sp<IHDCP> &hdcp)
    : mNetSession(netSession),
      mNotify(notify),
      mInterfaceAddr(interfaceAddr),
      mLegacyMode(legacyMode),
      mHDCP(hdcp),
      mLastLifesignUs(),
      mVideoTrackIndex(-1),
      mTSQueue(new ABuffer(12 + kMaxNumTSPacketsPerRTPPacket * 188)),
@@ -644,6 +666,73 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(
                    sp<ABuffer> accessUnit;
                    CHECK(msg->findBuffer("accessUnit", &accessUnit));

                    bool isHDCPEncrypted = false;
                    uint64_t inputCTR;
                    uint8_t HDCP_private_data[16];
                    if (mHDCP != NULL && !track->isAudio()) {
                        isHDCPEncrypted = true;

                        status_t err = mHDCP->encrypt(
                                accessUnit->data(), accessUnit->size(),
                                trackIndex  /* streamCTR */,
                                &inputCTR,
                                accessUnit->data());

                        if (err != OK) {
                            ALOGI("Failed to HDCP-encrypt media data (err %d)",
                                  err);

                            // Inform WifiDisplaySource of our premature death
                            // (wish).
                            sp<AMessage> notify = mNotify->dup();
                            notify->setInt32("what", kWhatSessionDead);
                            notify->post();
                            break;
                        }

                        HDCP_private_data[0] = 0x00;

                        HDCP_private_data[1] =
                            (((trackIndex >> 30) & 3) << 1) | 1;

                        HDCP_private_data[2] = (trackIndex >> 22) & 0xff;

                        HDCP_private_data[3] =
                            (((trackIndex >> 15) & 0x7f) << 1) | 1;

                        HDCP_private_data[4] = (trackIndex >> 7) & 0xff;

                        HDCP_private_data[5] =
                            ((trackIndex & 0x7f) << 1) | 1;

                        HDCP_private_data[6] = 0x00;

                        HDCP_private_data[7] =
                            (((inputCTR >> 60) & 0x0f) << 1) | 1;

                        HDCP_private_data[8] = (inputCTR >> 52) & 0xff;

                        HDCP_private_data[9] =
                            (((inputCTR >> 45) & 0x7f) << 1) | 1;

                        HDCP_private_data[10] = (inputCTR >> 37) & 0xff;

                        HDCP_private_data[11] =
                            (((inputCTR >> 30) & 0x7f) << 1) | 1;

                        HDCP_private_data[12] = (inputCTR >> 22) & 0xff;

                        HDCP_private_data[13] =
                            (((inputCTR >> 15) & 0x7f) << 1) | 1;

                        HDCP_private_data[14] = (inputCTR >> 7) & 0xff;

                        HDCP_private_data[15] =
                            ((inputCTR & 0x7f) << 1) | 1;

                        flags |= TSPacketizer::IS_ENCRYPTED;
                    }

                    int64_t timeUs;
                    CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));

@@ -654,7 +743,9 @@ void WifiDisplaySource::PlaybackSession::onMessageReceived(

                    sp<ABuffer> packets;
                    mPacketizer->packetize(
                            packetizerTrackIndex, accessUnit, &packets, flags);
                            packetizerTrackIndex, accessUnit, &packets, flags,
                            isHDCPEncrypted ? NULL : HDCP_private_data,
                            isHDCPEncrypted ? 0 : sizeof(HDCP_private_data));

                    for (size_t offset = 0;
                            offset < packets->size(); offset += 188) {
+4 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ namespace android {

struct ABuffer;
struct BufferQueue;
struct IHDCP;
struct ISurfaceTexture;
struct MediaPuller;
struct MediaSource;
@@ -39,7 +40,8 @@ struct WifiDisplaySource::PlaybackSession : public AHandler {
            const sp<ANetworkSession> &netSession,
            const sp<AMessage> &notify,
            const struct in_addr &interfaceAddr,
            bool legacyMode);
            bool legacyMode,
            const sp<IHDCP> &hdcp);

    enum TransportMode {
        TRANSPORT_UDP,
@@ -98,6 +100,7 @@ private:
    sp<AMessage> mNotify;
    in_addr mInterfaceAddr;
    bool mLegacyMode;
    sp<IHDCP> mHDCP;

    int64_t mLastLifesignUs;

Loading