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

Commit 3de157dd authored by Chong Zhang's avatar Chong Zhang
Browse files

some fixes for crash when extractor creation fails

- prefetch data for sniffing

- notify error instead of crashing if extractor is NULL

Bug: 16818302

Change-Id: I56ff4996d99ac2811d19d141f7ff7acdd7c1da17
parent 92ce4715
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
namespace android {

struct AMessage;
struct AString;
struct IMediaHTTPService;
class String8;

@@ -46,7 +47,8 @@ public:
    static sp<DataSource> CreateFromURI(
            const sp<IMediaHTTPService> &httpService,
            const char *uri,
            const KeyedVector<String8, String8> *headers = NULL);
            const KeyedVector<String8, String8> *headers = NULL,
            AString *sniffedMIME = NULL);

    DataSource() {}

@@ -100,6 +102,10 @@ protected:
    virtual ~DataSource() {}

private:
    enum {
        kDefaultMetaSize = 200000,
    };

    static Mutex gSnifferMutex;
    static List<SnifferFunc> gSniffers;
    static bool gSniffersRegistered;
+2 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ public:
    virtual char* getDrmTrackInfo(size_t trackID, int *len) {
        return NULL;
    }
    virtual void setUID(uid_t uid) {
    }

protected:
    MediaExtractor() : mIsDrm(false) {}
+33 −27
Original line number Diff line number Diff line
@@ -37,10 +37,6 @@ namespace android {

NuPlayer::GenericSource::GenericSource(
        const sp<AMessage> &notify,
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers,
        bool isWidevine,
        bool uidValid,
        uid_t uid)
    : Source(notify),
@@ -48,38 +44,41 @@ NuPlayer::GenericSource::GenericSource(
      mFetchTimedTextDataGeneration(0),
      mDurationUs(0ll),
      mAudioIsVorbis(false),
      mIsWidevine(isWidevine),
      mIsWidevine(false),
      mUIDValid(uidValid),
      mUID(uid) {
    DataSource::RegisterDefaultSniffers();
}

status_t NuPlayer::GenericSource::init(
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers) {
    mIsWidevine = !strncasecmp(url, "widevine://", 11);

    AString sniffedMIME;

    sp<DataSource> dataSource =
        DataSource::CreateFromURI(httpService, url, headers);
    CHECK(dataSource != NULL);
        DataSource::CreateFromURI(httpService, url, headers, &sniffedMIME);

    initFromDataSource(dataSource);
    if (dataSource == NULL) {
        return UNKNOWN_ERROR;
    }

NuPlayer::GenericSource::GenericSource(
        const sp<AMessage> &notify,
        int fd, int64_t offset, int64_t length)
    : Source(notify),
      mFetchSubtitleDataGeneration(0),
      mFetchTimedTextDataGeneration(0),
      mDurationUs(0ll),
      mAudioIsVorbis(false),
      mIsWidevine(false),
      mUIDValid(false),
      mUID(0) {
    DataSource::RegisterDefaultSniffers();
    return initFromDataSource(
            dataSource, sniffedMIME.empty() ? NULL : sniffedMIME.c_str());
}

status_t NuPlayer::GenericSource::init(
        int fd, int64_t offset, int64_t length) {
    sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);

    initFromDataSource(dataSource);
    return initFromDataSource(dataSource, NULL);
}

void NuPlayer::GenericSource::initFromDataSource(
        const sp<DataSource> &dataSource) {
status_t NuPlayer::GenericSource::initFromDataSource(
        const sp<DataSource> &dataSource,
        const char* mime) {
    sp<MediaExtractor> extractor;

    if (mIsWidevine) {
@@ -93,7 +92,7 @@ void NuPlayer::GenericSource::initFromDataSource(
                || strcasecmp(
                    mimeType.string(), MEDIA_MIMETYPE_CONTAINER_WVM)) {
            ALOGE("unsupported widevine mime: %s", mimeType.string());
            return;
            return UNKNOWN_ERROR;
        }

        sp<WVMExtractor> wvmExtractor = new WVMExtractor(dataSource);
@@ -103,10 +102,12 @@ void NuPlayer::GenericSource::initFromDataSource(
        }
        extractor = wvmExtractor;
    } else {
        extractor = MediaExtractor::Create(dataSource);
        extractor = MediaExtractor::Create(dataSource, mime);
    }

    CHECK(extractor != NULL);
    if (extractor == NULL) {
        return UNKNOWN_ERROR;
    }

    sp<MetaData> fileMeta = extractor->getMetaData();
    if (fileMeta != NULL) {
@@ -144,6 +145,9 @@ void NuPlayer::GenericSource::initFromDataSource(
                int32_t secure;
                if (meta->findInt32(kKeyRequiresSecureBuffers, &secure) && secure) {
                    mIsWidevine = true;
                    if (mUIDValid) {
                        extractor->setUID(mUID);
                    }
                }
            }
        }
@@ -158,6 +162,8 @@ void NuPlayer::GenericSource::initFromDataSource(
            }
        }
    }

    return OK;
}

status_t NuPlayer::GenericSource::setBuffers(bool audio, Vector<MediaBuffer *> &buffers) {
+8 −10
Original line number Diff line number Diff line
@@ -34,18 +34,14 @@ struct MediaSource;
class MediaBuffer;

struct NuPlayer::GenericSource : public NuPlayer::Source {
    GenericSource(
            const sp<AMessage> &notify,
    GenericSource(const sp<AMessage> &notify, bool uidValid, uid_t uid);

    status_t init(
            const sp<IMediaHTTPService> &httpService,
            const char *url,
            const KeyedVector<String8, String8> *headers,
            bool isWidevine = false,
            bool uidValid = false,
            uid_t uid = 0);
            const KeyedVector<String8, String8> *headers);

    GenericSource(
            const sp<AMessage> &notify,
            int fd, int64_t offset, int64_t length);
    status_t init(int fd, int64_t offset, int64_t length);

    virtual void prepareAsync();

@@ -101,7 +97,9 @@ private:
    bool mUIDValid;
    uid_t mUID;

    void initFromDataSource(const sp<DataSource> &dataSource);
    status_t initFromDataSource(
            const sp<DataSource> &dataSource,
            const char *mime);

    void fetchTextData(
            uint32_t what, media_track_type type,
+32 −14
Original line number Diff line number Diff line
@@ -207,6 +207,7 @@ void NuPlayer::setDataSourceAsync(
        const sp<IMediaHTTPService> &httpService,
        const char *url,
        const KeyedVector<String8, String8> *headers) {

    sp<AMessage> msg = new AMessage(kWhatSetDataSource, id());
    size_t len = strlen(url);

@@ -224,16 +225,21 @@ void NuPlayer::setDataSourceAsync(
                    || strstr(url, ".sdp?"))) {
        source = new RTSPSource(
                notify, httpService, url, headers, mUIDValid, mUID, true);
    } else if ((!strncasecmp(url, "widevine://", 11))) {
        source = new GenericSource(notify, httpService, url, headers,
                true /* isWidevine */, mUIDValid, mUID);
        // Don't set FLAG_SECURE on mSourceFlags here, the correct flags
        // will be updated in Source::kWhatFlagsChanged handler when
        // GenericSource is prepared.
    } else {
        source = new GenericSource(notify, httpService, url, headers);
    }
        sp<GenericSource> genericSource =
                new GenericSource(notify, mUIDValid, mUID);
        // Don't set FLAG_SECURE on mSourceFlags here for widevine.
        // The correct flags will be updated in Source::kWhatFlagsChanged
        // handler when  GenericSource is prepared.

        status_t err = genericSource->init(httpService, url, headers);

        if (err == OK) {
            source = genericSource;
        } else {
            ALOGE("Failed to initialize generic source!");
        }
    }
    msg->setObject("source", source);
    msg->post();
}
@@ -243,7 +249,16 @@ void NuPlayer::setDataSourceAsync(int fd, int64_t offset, int64_t length) {

    sp<AMessage> notify = new AMessage(kWhatSourceNotify, id());

    sp<Source> source = new GenericSource(notify, fd, offset, length);
    sp<GenericSource> source =
            new GenericSource(notify, mUIDValid, mUID);

    status_t err = source->init(fd, offset, length);

    if (err != OK) {
        ALOGE("Failed to initialize generic source!");
        source = NULL;
    }

    msg->setObject("source", source);
    msg->post();
}
@@ -352,17 +367,20 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {

            CHECK(mSource == NULL);

            status_t err = OK;
            sp<RefBase> obj;
            CHECK(msg->findObject("source", &obj));

            if (obj != NULL) {
                mSource = static_cast<Source *>(obj.get());

                looper()->registerHandler(mSource);
            } else {
                err = UNKNOWN_ERROR;
            }

            CHECK(mDriver != NULL);
            sp<NuPlayerDriver> driver = mDriver.promote();
            if (driver != NULL) {
                driver->notifySetDataSourceCompleted(OK);
                driver->notifySetDataSourceCompleted(err);
            }
            break;
        }
Loading