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

Commit daeb5b33 authored by James Dong's avatar James Dong
Browse files

Remove streaming related logic from preview player.

Video editor engine only deals with local file playback/preview.

Change-Id: I8e3414abf8a109a77a1e34a959fb4a090612ae3d
related-to-bug: 5857057
parent 8dcbd11c
Loading
Loading
Loading
Loading
+6 −16
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@

#include <binder/IPCThreadState.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractor.h>
@@ -129,7 +128,7 @@ PreviewPlayer::~PreviewPlayer() {
    }
}

void PreviewPlayer::cancelPlayerEvents(bool keepBufferingGoing) {
void PreviewPlayer::cancelPlayerEvents() {
    mQueue.cancelEvent(mVideoEvent->eventID());
    mVideoEventPending = false;
    mQueue.cancelEvent(mStreamDoneEvent->eventID());
@@ -141,21 +140,15 @@ void PreviewPlayer::cancelPlayerEvents(bool keepBufferingGoing) {
    mProgressCbEventPending = false;
}

status_t PreviewPlayer::setDataSource(
        const char *uri, const KeyedVector<String8, String8> *headers) {
status_t PreviewPlayer::setDataSource(const char *path) {
    Mutex::Autolock autoLock(mLock);
    return setDataSource_l(uri, headers);
    return setDataSource_l(path);
}

status_t PreviewPlayer::setDataSource_l(
        const char *uri, const KeyedVector<String8, String8> *headers) {
status_t PreviewPlayer::setDataSource_l(const char *path) {
    reset_l();

    mUri = uri;

    if (headers) {
        mUriHeaders = *headers;
    }
    mUri = path;

    // The actual work will be done during preparation in the call to
    // ::finishSetDataSource_l to avoid blocking the calling thread in
@@ -324,9 +317,6 @@ void PreviewPlayer::reset_l() {
    mSeekTimeUs = 0;

    mUri.setTo("");
    mUriHeaders.clear();

    mFileSource.clear();

    mCurrentVideoEffect = VIDEO_EFFECT_NONE;
    mIsVideoSourceJpg = false;
@@ -1160,7 +1150,7 @@ status_t PreviewPlayer::finishSetDataSource_l() {
    sp<DataSource> dataSource;
    sp<MediaExtractor> extractor;

    dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
    dataSource = DataSource::CreateFromURI(mUri.string(), NULL);

    if (dataSource == NULL) {
        return UNKNOWN_ERROR;
+3 −9
Original line number Diff line number Diff line
@@ -22,7 +22,6 @@
#include "VideoEditorAudioPlayer.h"

#include <media/MediaPlayerInterface.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/TimeSource.h>
#include <utils/threads.h>
@@ -33,10 +32,7 @@
namespace android {

struct AudioPlayerBase;
struct DataSource;
struct MediaBuffer;
struct MediaExtractor;
struct MediaSource;

struct PreviewPlayer : public PreviewPlayerBase {
    PreviewPlayer(NativeWindowRenderer* renderer);
@@ -55,8 +51,7 @@ struct PreviewPlayer : public PreviewPlayerBase {
    void releaseLock();

    status_t prepare();
    status_t setDataSource(
        const char *uri, const KeyedVector<String8, String8> *headers);
    status_t setDataSource(const char *path);

    //Added methods
    status_t loadEffectsSettings(M4VSS3GPP_EffectSettings* pEffectSettings,
@@ -98,10 +93,9 @@ private:
        INFORMED_AV_EOS     = 2048,
    };

    void cancelPlayerEvents(bool keepBufferingGoing = false);
    void cancelPlayerEvents();
    status_t setDataSource_l(const sp<MediaExtractor> &extractor);
    status_t setDataSource_l(
        const char *uri, const KeyedVector<String8, String8> *headers);
    status_t setDataSource_l(const char *path);
    void reset_l();
    status_t play_l();
    status_t initRenderer_l();
+8 −244
Original line number Diff line number Diff line
@@ -23,9 +23,6 @@
#include "PreviewPlayerBase.h"
#include "AudioPlayerBase.h"
#include "include/SoftwareRenderer.h"
#include "include/NuCachedSource2.h"
#include "include/ThrottledSource.h"
#include "include/MPEG2TSExtractor.h"

#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -33,7 +30,6 @@
#include <media/stagefright/foundation/hexdump.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBuffer.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaExtractor.h>
@@ -52,11 +48,6 @@

namespace android {

static int64_t kLowWaterMarkUs = 2000000ll;  // 2secs
static int64_t kHighWaterMarkUs = 10000000ll;  // 10secs
static const size_t kLowWaterMarkBytes = 40000;
static const size_t kHighWaterMarkBytes = 200000;

struct AwesomeEvent : public TimedEventQueue::Event {
    AwesomeEvent(
            PreviewPlayerBase *player,
@@ -186,8 +177,6 @@ PreviewPlayerBase::PreviewPlayerBase()
    mVideoEventPending = false;
    mStreamDoneEvent = new AwesomeEvent(this, &PreviewPlayerBase::onStreamDone);
    mStreamDoneEventPending = false;
    mBufferingEvent = new AwesomeEvent(this, &PreviewPlayerBase::onBufferingUpdate);
    mBufferingEventPending = false;
    mVideoLagEvent = new AwesomeEvent(this, &PreviewPlayerBase::onVideoLagUpdate);
    mVideoEventPending = false;

@@ -209,7 +198,7 @@ PreviewPlayerBase::~PreviewPlayerBase() {
    mClient.disconnect();
}

void PreviewPlayerBase::cancelPlayerEvents(bool keepBufferingGoing) {
void PreviewPlayerBase::cancelPlayerEvents() {
    mQueue.cancelEvent(mVideoEvent->eventID());
    mVideoEventPending = false;
    mQueue.cancelEvent(mStreamDoneEvent->eventID());
@@ -218,11 +207,6 @@ void PreviewPlayerBase::cancelPlayerEvents(bool keepBufferingGoing) {
    mAudioStatusEventPending = false;
    mQueue.cancelEvent(mVideoLagEvent->eventID());
    mVideoLagEventPending = false;

    if (!keepBufferingGoing) {
        mQueue.cancelEvent(mBufferingEvent->eventID());
        mBufferingEventPending = false;
    }
}

void PreviewPlayerBase::setListener(const wp<MediaPlayerBase> &listener) {
@@ -230,31 +214,15 @@ void PreviewPlayerBase::setListener(const wp<MediaPlayerBase> &listener) {
    mListener = listener;
}

status_t PreviewPlayerBase::setDataSource(
        const char *uri, const KeyedVector<String8, String8> *headers) {
status_t PreviewPlayerBase::setDataSource(const char *path) {
    Mutex::Autolock autoLock(mLock);
    return setDataSource_l(uri, headers);
    return setDataSource_l(path);
}

status_t PreviewPlayerBase::setDataSource_l(
        const char *uri, const KeyedVector<String8, String8> *headers) {
status_t PreviewPlayerBase::setDataSource_l(const char *path) {
    reset_l();

    mUri = uri;

    if (headers) {
        mUriHeaders = *headers;

        ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
        if (index >= 0) {
            // Browser is in "incognito" mode, suppress logging URLs.

            // This isn't something that should be passed to the server.
            mUriHeaders.removeItemsAt(index);

            mFlags |= INCOGNITO;
        }
    }
    mUri = path;

    if (!(mFlags & INCOGNITO)) {
        ALOGI("setDataSource_l('%s')", mUri.string());
@@ -269,36 +237,10 @@ status_t PreviewPlayerBase::setDataSource_l(
    return OK;
}

status_t PreviewPlayerBase::setDataSource(
        int fd, int64_t offset, int64_t length) {
    Mutex::Autolock autoLock(mLock);

    reset_l();

    sp<DataSource> dataSource = new FileSource(fd, offset, length);

    status_t err = dataSource->initCheck();

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

    mFileSource = dataSource;

    return setDataSource_l(dataSource);
}

status_t PreviewPlayerBase::setDataSource(const sp<IStreamSource> &source) {
    return INVALID_OPERATION;
}

status_t PreviewPlayerBase::setDataSource_l(
        const sp<DataSource> &dataSource) {

    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
    return setDataSource_l(extractor);
}

status_t PreviewPlayerBase::setDataSource_l(const sp<MediaExtractor> &extractor) {
    if (extractor == NULL) {
        return UNKNOWN_ERROR;
@@ -408,10 +350,6 @@ void PreviewPlayerBase::reset_l() {

    if (mFlags & PREPARING) {
        mFlags |= PREPARE_CANCELLED;
        if (mConnectingDataSource != NULL) {
            ALOGI("interrupting the connection process");
            mConnectingDataSource->disconnect();
        }

        if (mFlags & PREPARING_CONNECTED) {
            // We are basically done preparing, we're just buffering
@@ -426,7 +364,6 @@ void PreviewPlayerBase::reset_l() {

    cancelPlayerEvents();

    mCachedSource.clear();
    mAudioTrack.clear();
    mVideoTrack.clear();

@@ -465,9 +402,6 @@ void PreviewPlayerBase::reset_l() {
    mSeekTimeUs = 0;

    mUri.setTo("");
    mUriHeaders.clear();

    mFileSource.clear();

    mBitrate = -1;
    mLastVideoTimeUs = -1;
@@ -483,45 +417,6 @@ void PreviewPlayerBase::notifyListener_l(int msg, int ext1, int ext2) {
    }
}

bool PreviewPlayerBase::getBitrate(int64_t *bitrate) {
    off64_t size;
    if (mDurationUs >= 0 && mCachedSource != NULL
            && mCachedSource->getSize(&size) == OK) {
        *bitrate = size * 8000000ll / mDurationUs;  // in bits/sec
        return true;
    }

    if (mBitrate >= 0) {
        *bitrate = mBitrate;
        return true;
    }

    *bitrate = 0;

    return false;
}

// Returns true iff cached duration is available/applicable.
bool PreviewPlayerBase::getCachedDuration_l(int64_t *durationUs, bool *eos) {
    int64_t bitrate;

    if (mCachedSource != NULL && getBitrate(&bitrate)) {
        status_t finalStatus;
        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
        *durationUs = cachedDataRemaining * 8000000ll / bitrate;
        *eos = (finalStatus != OK);
        return true;
    }

    return false;
}

void PreviewPlayerBase::ensureCacheIsFetching_l() {
    if (mCachedSource != NULL) {
        mCachedSource->resumeFetchingIfNecessary();
    }
}

void PreviewPlayerBase::onVideoLagUpdate() {
    Mutex::Autolock autoLock(mLock);
    if (!mVideoLagEventPending) {
@@ -544,99 +439,6 @@ void PreviewPlayerBase::onVideoLagUpdate() {
    postVideoLagEvent_l();
}

void PreviewPlayerBase::onBufferingUpdate() {
    Mutex::Autolock autoLock(mLock);
    if (!mBufferingEventPending) {
        return;
    }
    mBufferingEventPending = false;

    if (mCachedSource != NULL) {
        status_t finalStatus;
        size_t cachedDataRemaining = mCachedSource->approxDataRemaining(&finalStatus);
        bool eos = (finalStatus != OK);

        if (eos) {
            if (finalStatus == ERROR_END_OF_STREAM) {
                notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
            }
            if (mFlags & PREPARING) {
                ALOGV("cache has reached EOS, prepare is done.");
                finishAsyncPrepare_l();
            }
        } else {
            int64_t bitrate;
            if (getBitrate(&bitrate)) {
                size_t cachedSize = mCachedSource->cachedSize();
                int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;

                int percentage = 100.0 * (double)cachedDurationUs / mDurationUs;
                if (percentage > 100) {
                    percentage = 100;
                }

                notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
            } else {
                // We don't know the bitrate of the stream, use absolute size
                // limits to maintain the cache.

                if ((mFlags & PLAYING) && !eos
                        && (cachedDataRemaining < kLowWaterMarkBytes)) {
                    ALOGI("cache is running low (< %d) , pausing.",
                         kLowWaterMarkBytes);
                    mFlags |= CACHE_UNDERRUN;
                    pause_l();
                    ensureCacheIsFetching_l();
                    notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
                } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
                    if (mFlags & CACHE_UNDERRUN) {
                        ALOGI("cache has filled up (> %d), resuming.",
                             kHighWaterMarkBytes);
                        mFlags &= ~CACHE_UNDERRUN;
                        play_l();
                        notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
                    } else if (mFlags & PREPARING) {
                        ALOGV("cache has filled up (> %d), prepare is done",
                             kHighWaterMarkBytes);
                        finishAsyncPrepare_l();
                    }
                }
            }
        }
    }

    int64_t cachedDurationUs;
    bool eos;
    if (getCachedDuration_l(&cachedDurationUs, &eos)) {
        ALOGV("cachedDurationUs = %.2f secs, eos=%d",
             cachedDurationUs / 1E6, eos);

        if ((mFlags & PLAYING) && !eos
                && (cachedDurationUs < kLowWaterMarkUs)) {
            ALOGI("cache is running low (%.2f secs) , pausing.",
                 cachedDurationUs / 1E6);
            mFlags |= CACHE_UNDERRUN;
            pause_l();
            ensureCacheIsFetching_l();
            notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
        } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
            if (mFlags & CACHE_UNDERRUN) {
                ALOGI("cache has filled up (%.2f secs), resuming.",
                     cachedDurationUs / 1E6);
                mFlags &= ~CACHE_UNDERRUN;
                play_l();
                notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
            } else if (mFlags & PREPARING) {
                ALOGV("cache has filled up (%.2f secs), prepare is done",
                     cachedDurationUs / 1E6);
                finishAsyncPrepare_l();
            }
        }
    }

    postBufferingEvent_l();
}

void PreviewPlayerBase::onStreamDone() {
    // Posted whenever any stream finishes playing.

@@ -919,7 +721,7 @@ status_t PreviewPlayerBase::pause_l(bool at_eos) {
        return OK;
    }

    cancelPlayerEvents(true /* keepBufferingGoing */);
    cancelPlayerEvents();

    if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
        if (at_eos) {
@@ -1244,24 +1046,6 @@ void PreviewPlayerBase::onVideoEvent() {
            mVideoBuffer->release();
            mVideoBuffer = NULL;
        }

        if (mSeeking == SEEK && mCachedSource != NULL && mAudioSource != NULL
                && !(mFlags & SEEK_PREVIEW)) {
            // We're going to seek the video source first, followed by
            // the audio source.
            // In order to avoid jumps in the DataSource offset caused by
            // the audio codec prefetching data from the old locations
            // while the video codec is already reading data from the new
            // locations, we'll "pause" the audio source, causing it to
            // stop reading input data until a subsequent seek.

            if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
                mAudioPlayer->pause();

                mFlags &= ~AUDIO_RUNNING;
            }
            mAudioSource->pause();
        }
    }

    if (!mVideoBuffer) {
@@ -1459,14 +1243,6 @@ void PreviewPlayerBase::postStreamDoneEvent_l(status_t status) {
    mQueue.postEvent(mStreamDoneEvent);
}

void PreviewPlayerBase::postBufferingEvent_l() {
    if (mBufferingEventPending) {
        return;
    }
    mBufferingEventPending = true;
    mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
}

void PreviewPlayerBase::postVideoLagEvent_l() {
    if (mVideoLagEventPending) {
        return;
@@ -1573,7 +1349,7 @@ status_t PreviewPlayerBase::prepareAsync_l() {

status_t PreviewPlayerBase::finishSetDataSource_l() {
    sp<DataSource> dataSource =
            DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
            DataSource::CreateFromURI(mUri.string(), NULL);

    if (dataSource == NULL) {
        return UNKNOWN_ERROR;
@@ -1642,12 +1418,8 @@ void PreviewPlayerBase::onPrepareAsyncEvent() {

    mFlags |= PREPARING_CONNECTED;

    if (mCachedSource != NULL) {
        postBufferingEvent_l();
    } else {
    finishAsyncPrepare_l();
}
}

void PreviewPlayerBase::finishAsyncPrepare_l() {
    if (mIsAsyncPrepare) {
@@ -1681,12 +1453,4 @@ void PreviewPlayerBase::postAudioSeekComplete() {
    postCheckAudioStatusEvent_l(0 /* delayUs */);
}

status_t PreviewPlayerBase::setParameter(int key, const Parcel &request) {
    return OK;
}

status_t PreviewPlayerBase::getParameter(int key, Parcel *reply) {
    return OK;
}

}  // namespace android
+3 −31
Original line number Diff line number Diff line
@@ -18,11 +18,9 @@

#define PREVIEW_PLAYER_BASE_H_

#include "HTTPBase.h"
#include "TimedEventQueue.h"

#include <media/MediaPlayerInterface.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaSource.h>
#include <media/stagefright/OMXClient.h>
#include <media/stagefright/TimeSource.h>
@@ -31,11 +29,9 @@
namespace android {

struct AudioPlayerBase;
struct DataSource;
struct MediaBuffer;
struct MediaExtractor;
struct MediaSource;
struct NuCachedSource2;
struct ISurfaceTexture;

struct AwesomeRenderer : public RefBase {
@@ -54,12 +50,7 @@ struct PreviewPlayerBase {

    void setListener(const wp<MediaPlayerBase> &listener);

    status_t setDataSource(
            const char *uri,
            const KeyedVector<String8, String8> *headers = NULL);

    status_t setDataSource(int fd, int64_t offset, int64_t length);

    status_t setDataSource(const char *path);
    status_t setDataSource(const sp<IStreamSource> &source);

    void reset();
@@ -82,9 +73,6 @@ struct PreviewPlayerBase {
    status_t getDuration(int64_t *durationUs);
    status_t getPosition(int64_t *positionUs);

    status_t setParameter(int key, const Parcel &request);
    status_t getParameter(int key, Parcel *reply);

    status_t seekTo(int64_t timeUs);

    // This is a mask of MediaExtractor::Flags.
@@ -143,8 +131,6 @@ private:
    String8 mUri;
    KeyedVector<String8, String8> mUriHeaders;

    sp<DataSource> mFileSource;

    sp<MediaSource> mVideoTrack;
    sp<MediaSource> mVideoSource;
    sp<AwesomeRenderer> mVideoRenderer;
@@ -183,8 +169,6 @@ private:
    bool mVideoEventPending;
    sp<TimedEventQueue::Event> mStreamDoneEvent;
    bool mStreamDoneEventPending;
    sp<TimedEventQueue::Event> mBufferingEvent;
    bool mBufferingEventPending;
    sp<TimedEventQueue::Event> mCheckAudioStatusEvent;
    bool mAudioStatusEventPending;
    sp<TimedEventQueue::Event> mVideoLagEvent;
@@ -205,19 +189,12 @@ private:

    MediaBuffer *mVideoBuffer;

    sp<HTTPBase> mConnectingDataSource;
    sp<NuCachedSource2> mCachedSource;

    int64_t mLastVideoTimeUs;

    ARect mCropRect;
    int32_t mGivenWidth, mGivenHeight;

    status_t setDataSource_l(
            const char *uri,
            const KeyedVector<String8, String8> *headers = NULL);

    status_t setDataSource_l(const sp<DataSource> &dataSource);
    status_t setDataSource_l(const char *path);
    status_t setDataSource_l(const sp<MediaExtractor> &extractor);
    void reset_l();
    status_t seekTo_l(int64_t timeUs);
@@ -226,7 +203,7 @@ private:
    void notifyVideoSize_l();
    void seekAudioIfNecessary_l();

    void cancelPlayerEvents(bool keepBufferingGoing = false);
    void cancelPlayerEvents();

    void setAudioSource(sp<MediaSource> source);
    status_t initAudioDecoder();
@@ -246,16 +223,11 @@ private:
    void finishAsyncPrepare_l();
    void onVideoLagUpdate();

    bool getCachedDuration_l(int64_t *durationUs, bool *eos);

    status_t finishSetDataSource_l();

    static bool ContinuePreparation(void *cookie);

    bool getBitrate(int64_t *bitrate);

    void finishSeekIfNecessary(int64_t videoTimeUs);
    void ensureCacheIsFetching_l();

    status_t startAudioPlayer_l();

+9 −5
Original line number Diff line number Diff line
@@ -59,8 +59,12 @@ status_t VideoEditorPlayer::setAudioPlayer(VideoEditorAudioPlayer *audioPlayer)
status_t VideoEditorPlayer::setDataSource(
        const char *url, const KeyedVector<String8, String8> *headers) {
    ALOGI("setDataSource('%s')", url);
    if (headers != NULL) {
        ALOGE("Headers parameter is not supported");
        return INVALID_OPERATION;
    }

    return mPlayer->setDataSource(url, headers);
    return mPlayer->setDataSource(url);
}

//We donot use this in preview, dummy implimentation as this is pure virtual
@@ -159,13 +163,13 @@ status_t VideoEditorPlayer::setLooping(int loop) {
}

status_t VideoEditorPlayer::setParameter(int key, const Parcel &request) {
    ALOGV("setParameter");
    return mPlayer->setParameter(key, request);
    ALOGE("setParameter not implemented");
    return INVALID_OPERATION;
}

status_t VideoEditorPlayer::getParameter(int key, Parcel *reply) {
    ALOGV("getParameter");
    return mPlayer->getParameter(key, reply);
    ALOGE("getParameter not implemented");
    return INVALID_OPERATION;
}

player_type VideoEditorPlayer::playerType() {
Loading